added dashboard
This commit is contained in:
114
src/app/components/delivery-validator/delivery-validator.css
Normal file
114
src/app/components/delivery-validator/delivery-validator.css
Normal 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;
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
44
src/app/components/delivery-validator/delivery-validator.ts
Normal file
44
src/app/components/delivery-validator/delivery-validator.ts
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/app/components/info-card/info-card.css
Normal file
42
src/app/components/info-card/info-card.css
Normal 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;
|
||||||
|
}
|
||||||
7
src/app/components/info-card/info-card.html
Normal file
7
src/app/components/info-card/info-card.html
Normal 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>
|
||||||
19
src/app/components/info-card/info-card.ts
Normal file
19
src/app/components/info-card/info-card.ts
Normal 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>()
|
||||||
|
}
|
||||||
72
src/app/components/info-table/info-table.css
Normal file
72
src/app/components/info-table/info-table.css
Normal 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 l’espace 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;
|
||||||
|
}
|
||||||
11
src/app/components/info-table/info-table.html
Normal file
11
src/app/components/info-table/info-table.html
Normal 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>
|
||||||
44
src/app/components/info-table/info-table.ts
Normal file
44
src/app/components/info-table/info-table.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
<p>
|
<div class="flex gap-17 ml-20">
|
||||||
faire dashboard ici
|
<app-info-card color="#f59e0b" icon="inbox" value="15" description="Produits sous le seuil minimal."></app-info-card>
|
||||||
et faire la verif des livraisons ici aussi
|
<app-info-card color="#3b82f6" icon="team" value="56" description="Partenaires actifs."></app-info-card>
|
||||||
</p>
|
<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>
|
||||||
@@ -1,11 +1,19 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {ModalNav} from "../../components/modal-nav/modal-nav";
|
import {InfoCard} from "../../components/info-card/info-card";
|
||||||
import {NzIconDirective} from "ng-zorro-antd/icon";
|
import {DeliveryValidator} from "../../components/delivery-validator/delivery-validator";
|
||||||
|
import {InfoTable} from "../../components/info-table/info-table";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-welcome',
|
selector: 'app-welcome',
|
||||||
imports: [],
|
imports: [
|
||||||
|
InfoCard,
|
||||||
|
DeliveryValidator,
|
||||||
|
InfoTable,
|
||||||
|
],
|
||||||
templateUrl: './welcome.html',
|
templateUrl: './welcome.html',
|
||||||
styleUrl: './welcome.css'
|
styleUrl: './welcome.css'
|
||||||
})
|
})
|
||||||
export class Welcome {}
|
|
||||||
|
export class Welcome {
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user