added dashboard

This commit is contained in:
2025-11-24 21:44:55 +01:00
parent 234e30c25c
commit dda9e0e4d7
11 changed files with 396 additions and 8 deletions

View File

@@ -0,0 +1,114 @@
/* Conteneur principal centré */
.livraisons-container {
max-width: 650px;
margin: 40px 0 0 80px;
padding: 25px;
background: #f9fafb;
border-radius: 16px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
flex-direction: column;
align-items: flex-start;
/* Box shadow pour effet superposition */
box-shadow:
0 4px 8px rgba(0, 0, 0, 0.06),
0 8px 20px rgba(0, 0, 0, 0.08),
0 16px 40px rgba(0, 0, 0, 0.06);
}
/* Barre de recherche */
.search-input {
width: 100%;
padding: 14px 18px;
border-radius: 12px;
border: 1px solid #ddd;
margin-bottom: 20px;
font-size: 16px;
transition: all 0.3s ease;
}
.search-input:focus {
border-color: #3b82f6;
box-shadow: 0 0 8px rgba(59,130,246,0.2);
outline: none;
}
/* Liste scrollable */
.livraisons-list {
width: 100%;
max-height: 350px; /* hauteur max de la liste */
overflow-y: auto; /* scroll vertical activé */
padding-right: 10px; /* pour le scrollbar */
}
/* Scrollbar personnalisée (optionnel) */
.livraisons-list::-webkit-scrollbar {
width: 8px;
}
.livraisons-list::-webkit-scrollbar-thumb {
background: #9ca3af;
border-radius: 4px;
}
.livraisons-list::-webkit-scrollbar-track {
background: #f3f4f6;
}
/* Carte de livraison */
.livraison-card {
background: #ffffff;
padding: 20px 22px;
border-radius: 14px;
box-shadow: 0 6px 16px rgba(0,0,0,0.05);
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
margin-bottom: 18px;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.livraison-card:hover {
transform: translateY(-3px);
box-shadow: 0 10px 22px rgba(0,0,0,0.08);
}
/* Infos livraison */
.livraison-info h3 {
font-size: 17px;
margin: 0 0 4px;
color: #111827;
}
.livraison-info p {
margin: 0;
font-size: 14px;
color: #6b7280;
}
/* Bouton valider */
.validate-btn {
padding: 10px 20px;
border-radius: 12px;
border: none;
cursor: pointer;
font-weight: 600;
background: #3b82f6;
color: white;
transition: all 0.3s ease;
}
.validate-btn:hover {
background: #2563eb;
}
.validate-btn.validated {
background: #9ca3af;
cursor: default;
color: #ffffff;
opacity: 0.9;
}

View File

@@ -0,0 +1,20 @@
<div class="livraisons-container">
<input type="text" placeholder="Rechercher une livraison" class="search-input" (input)="search.set($any($event.target).value)"/>
<div class="livraisons-list">
@for (deliveryItem of filteredLivraisons(); track deliveryItem.id) {
<div class="livraison-card">
<div class="livraison-info">
<h3>{{ deliveryItem.client }}</h3>
<p class="mr-5">Date d'expédition: {{ deliveryItem.date }}</p>
<p>Produits : {{ deliveryItem.produits }}</p>
</div>
<button nz-button nzType="primary" [nzSize]="size" nzShape="round" (click)="validate(deliveryItem.id)">
<nz-icon nzType="check" />
Valider
</button>
</div>
}
</div>
</div>

View File

@@ -0,0 +1,44 @@
import {Component, computed, signal} from '@angular/core';
import {NzButtonComponent, NzButtonSize} from "ng-zorro-antd/button";
import {NzIconDirective} from "ng-zorro-antd/icon";
@Component({
selector: 'app-delivery-validator',
imports: [
NzButtonComponent,
NzIconDirective
],
templateUrl: './delivery-validator.html',
styleUrl: './delivery-validator.css',
})
export class DeliveryValidator {
size: NzButtonSize = 'large';
search = signal('');
livraisons = signal([
{ id: 1, client: 'Carrefour', date: '2025-02-03', produits: 12 },
{ id: 2, client: 'Intermarché', date: '2025-02-04', produits: 8 },
{ id: 3, client: 'Auchan', date: '2025-02-05', produits: 23 },
{ id: 1, client: 'Carrefour', date: '2025-02-03', produits: 12 },
{ id: 2, client: 'Intermarché', date: '2025-02-04', produits: 8 },
{ id: 3, client: 'Auchan', date: '2025-02-05', produits: 23 },
{ id: 1, client: 'Carrefour', date: '2025-02-03', produits: 12 },
{ id: 2, client: 'Intermarché', date: '2025-02-04', produits: 8 },
{ id: 3, client: 'Auchan', date: '2025-02-05', produits: 23 },
{ id: 1, client: 'Carrefour', date: '2025-02-03', produits: 12 },
{ id: 2, client: 'Intermarché', date: '2025-02-04', produits: 8 },
{ id: 3, client: 'Auchan', date: '2025-02-05', produits: 23 }
]);
filteredLivraisons = computed(() => {
const query = this.search().toLowerCase();
return this.livraisons().filter(l =>
l.client.toLowerCase().includes(query) ||
l.date.includes(query)
);
});
validate(id: number) {
return
}
}

View File

@@ -0,0 +1,42 @@
.card-content {
background: #ffffff;
padding: 32px 36px;
border-radius: 20px;
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.12);
width: 350px;
min-height: 180px;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card-content:hover {
transform: translateY(-6px);
box-shadow: 0 14px 26px rgba(0, 0, 0, 0.16);
}
/* Ligne du haut : icône ET nombre */
.card-top {
display: flex;
align-items: center;
gap: 20px;
}
/* Icône à gauche (plus grande) */
.card-top nz-icon {
font-size: 50px;
}
/* Nombre à droite de l'icône (plus grand) */
.card-number {
font-size: 48px;
font-weight: 700;
margin: 0;
color: #111827;
}
/* Texte en dessous (plus lisible) */
.card-text {
margin-top: 18px;
font-size: 18px;
line-height: 1.4;
color: #4b5563;
}

View File

@@ -0,0 +1,7 @@
<div class="card-content">
<div class="card-top">
<nz-icon [ngStyle]="{ 'color': color() }" [nzType]="icon()" nzTheme="outline"></nz-icon>
<p class="card-number">{{value()}}</p>
</div>
<p class="card-text">{{description()}}</p>
</div>

View File

@@ -0,0 +1,19 @@
import {Component, input} from '@angular/core';
import {NzIconDirective} from "ng-zorro-antd/icon";
import {NgStyle} from "@angular/common";
@Component({
selector: 'app-info-card',
imports: [
NzIconDirective,
NgStyle
],
templateUrl: './info-card.html',
styleUrl: './info-card.css',
})
export class InfoCard {
icon = input.required<string>()
value = input.required<string>()
description = input.required<string>()
color = input.required<string>()
}

View File

@@ -0,0 +1,72 @@
.documents-section {
display: flex;
flex-direction: column;
align-items: flex-start; /* contenu aligné à gauche */
gap: 16px; /* espace entre le titre et la liste */
margin: 40px 6%;
}
/* Titre */
.documents-section h1 {
font-size: 24px;
font-weight: 700;
color: #111827;
margin: 0; /* on gère lespace avec le gap */
letter-spacing: 0.5px;
text-transform: capitalize;
border-left: 4px solid #3b82f6;
padding-left: 12px;
}
/* Liste de documents scrollable */
.content {
width: 1000px;
display: flex;
flex-wrap: wrap;
gap: 16px;
padding: 30px 15px;
border-radius: 20px;
box-shadow:
0 4px 8px rgba(0, 0, 0, 0.06),
0 8px 20px rgba(0, 0, 0, 0.08),
0 16px 40px rgba(0, 0, 0, 0.06);
max-height: 390px;
overflow-y: auto;
}
/* Chaque carte */
.content > div {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 120px;
height: 140px;
padding: 12px;
background: #ffffff;
border-radius: 14px;
cursor: pointer;
box-shadow: 0 6px 16px rgba(0,0,0,0.08);
transition: all 0.2s ease;
text-align: center;
}
.content > div:hover {
transform: translateY(-3px);
box-shadow: 0 10px 22px rgba(0,0,0,0.12);
}
.content img {
width: 48px;
height: 48px;
margin-bottom: 10px;
object-fit: contain;
}
.content p {
margin: 0;
font-size: 16px;
font-weight: 600;
color: #111827;
word-break: break-word;
}

View File

@@ -0,0 +1,11 @@
<div class="documents-section">
<h1>Documents récents</h1>
<div class="content">
@for (doc of purchaseOrder(); track doc.id) {
<div>
<img src="https://cdn-icons-png.flaticon.com/512/337/337946.png" alt="pdf">
<p>{{ doc.name }}</p>
</div>
}
</div>
</div>

View File

@@ -0,0 +1,44 @@
import { Component } from '@angular/core';
interface PurchaseOrder {
id: number;
name: string;
}
@Component({
selector: 'app-info-table',
templateUrl: './info-table.html',
styleUrls: ['./info-table.css'],
})
export class InfoTable {
docs: PurchaseOrder[] = [
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
{ id: 1, name: 'Bon de commande'},
{ id: 2, name: 'Bon de commande'},
{ id: 3, name: 'Bon de commande'},
];
purchaseOrder(): PurchaseOrder[] {
return this.docs;
}
}

View File

@@ -1,4 +1,11 @@
<p>
faire dashboard ici
et faire la verif des livraisons ici aussi
</p>
<div class="flex gap-17 ml-20">
<app-info-card color="#f59e0b" icon="inbox" value="15" description="Produits sous le seuil minimal."></app-info-card>
<app-info-card color="#3b82f6" icon="team" value="56" description="Partenaires actifs."></app-info-card>
<app-info-card color="#10b981" icon="truck" value="8" description="Livreurs partenaires."></app-info-card>
<app-info-card color="#ef4444" icon="shop" value="48" description="Fournisseurs travaillant avec nous."></app-info-card>
</div>
<div class="mt-10 flex gap-30">
<app-delivery-validator></app-delivery-validator>
<app-info-table></app-info-table>
</div>

View File

@@ -1,11 +1,19 @@
import { Component } from '@angular/core';
import {ModalNav} from "../../components/modal-nav/modal-nav";
import {NzIconDirective} from "ng-zorro-antd/icon";
import {InfoCard} from "../../components/info-card/info-card";
import {DeliveryValidator} from "../../components/delivery-validator/delivery-validator";
import {InfoTable} from "../../components/info-table/info-table";
@Component({
selector: 'app-welcome',
imports: [],
imports: [
InfoCard,
DeliveryValidator,
InfoTable,
],
templateUrl: './welcome.html',
styleUrl: './welcome.css'
})
export class Welcome {}
export class Welcome {
}