Initial commit

This commit is contained in:
dahoud
2025-10-01 01:39:07 +00:00
commit b430bf3b96
826 changed files with 255287 additions and 0 deletions

View File

@@ -0,0 +1,336 @@
'use client';
import React, { useState, useRef } from 'react';
import { Card } from 'primereact/card';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { InputSwitch } from 'primereact/inputswitch';
import { Button } from 'primereact/button';
import { Toast } from 'primereact/toast';
import { Tag } from 'primereact/tag';
import { Divider } from 'primereact/divider';
import { Message } from 'primereact/message';
interface NotificationRule {
id: string;
nom: string;
description: string;
type: 'info' | 'warning' | 'success' | 'error';
evenement: string;
actif: boolean;
categorie: string;
}
const NotificationsAutomatiquesPage = () => {
const toast = useRef<Toast>(null);
const [rules, setRules] = useState<NotificationRule[]>([
{
id: '1',
nom: 'Nouveau chantier créé',
description: 'Notification envoyée lors de la création d\'un nouveau chantier',
type: 'success',
evenement: 'chantier.created',
actif: true,
categorie: 'Chantiers'
},
{
id: '2',
nom: 'Chantier terminé',
description: 'Notification envoyée lorsqu\'un chantier est marqué comme terminé',
type: 'success',
evenement: 'chantier.completed',
actif: true,
categorie: 'Chantiers'
},
{
id: '3',
nom: 'Dépassement de budget',
description: 'Alerte envoyée lorsque le budget d\'un chantier est dépassé',
type: 'warning',
evenement: 'budget.exceeded',
actif: true,
categorie: 'Budget'
},
{
id: '4',
nom: 'Retard de chantier',
description: 'Notification envoyée lorsqu\'un chantier est en retard',
type: 'warning',
evenement: 'chantier.delayed',
actif: true,
categorie: 'Chantiers'
},
{
id: '5',
nom: 'Phase terminée',
description: 'Notification envoyée lorsqu\'une phase de chantier est terminée',
type: 'success',
evenement: 'phase.completed',
actif: false,
categorie: 'Phases'
},
{
id: '6',
nom: 'Nouveau client',
description: 'Notification envoyée lors de l\'ajout d\'un nouveau client',
type: 'info',
evenement: 'client.created',
actif: true,
categorie: 'Clients'
},
{
id: '7',
nom: 'Stock faible',
description: 'Alerte envoyée lorsque le stock d\'un matériel est faible',
type: 'warning',
evenement: 'stock.low',
actif: true,
categorie: 'Stock'
},
{
id: '8',
nom: 'Erreur système',
description: 'Notification envoyée en cas d\'erreur système critique',
type: 'error',
evenement: 'system.error',
actif: true,
categorie: 'Système'
},
{
id: '9',
nom: 'Facture créée',
description: 'Notification envoyée lors de la création d\'une facture',
type: 'info',
evenement: 'facture.created',
actif: false,
categorie: 'Facturation'
},
{
id: '10',
nom: 'Paiement reçu',
description: 'Notification envoyée lors de la réception d\'un paiement',
type: 'success',
evenement: 'paiement.received',
actif: true,
categorie: 'Facturation'
}
]);
const toggleRule = (ruleId: string) => {
setRules(rules.map(rule => {
if (rule.id === ruleId) {
const newActif = !rule.actif;
toast.current?.show({
severity: newActif ? 'success' : 'info',
summary: newActif ? 'Activée' : 'Désactivée',
detail: `La règle "${rule.nom}" a été ${newActif ? 'activée' : 'désactivée'}`,
life: 3000
});
return { ...rule, actif: newActif };
}
return rule;
}));
};
const activerTout = () => {
setRules(rules.map(rule => ({ ...rule, actif: true })));
toast.current?.show({
severity: 'success',
summary: 'Succès',
detail: 'Toutes les notifications automatiques ont été activées',
life: 3000
});
};
const desactiverTout = () => {
setRules(rules.map(rule => ({ ...rule, actif: false })));
toast.current?.show({
severity: 'info',
summary: 'Désactivé',
detail: 'Toutes les notifications automatiques ont été désactivées',
life: 3000
});
};
const typeBodyTemplate = (rowData: NotificationRule) => {
const getSeverity = (type: string) => {
switch (type) {
case 'info': return 'info';
case 'warning': return 'warning';
case 'success': return 'success';
case 'error': return 'danger';
default: return 'info';
}
};
const getIcon = (type: string) => {
switch (type) {
case 'info': return 'pi-info-circle';
case 'warning': return 'pi-exclamation-triangle';
case 'success': return 'pi-check-circle';
case 'error': return 'pi-times-circle';
default: return 'pi-info-circle';
}
};
return (
<Tag
value={rowData.type.toUpperCase()}
severity={getSeverity(rowData.type)}
icon={`pi ${getIcon(rowData.type)}`}
/>
);
};
const statusBodyTemplate = (rowData: NotificationRule) => {
return (
<Tag
value={rowData.actif ? 'Activée' : 'Désactivée'}
severity={rowData.actif ? 'success' : 'secondary'}
/>
);
};
const actionBodyTemplate = (rowData: NotificationRule) => {
return (
<InputSwitch
checked={rowData.actif}
onChange={() => toggleRule(rowData.id)}
tooltip={rowData.actif ? 'Désactiver' : 'Activer'}
/>
);
};
const categorieBodyTemplate = (rowData: NotificationRule) => {
const getCategorieColor = (categorie: string) => {
switch (categorie) {
case 'Chantiers': return 'info';
case 'Budget': return 'warning';
case 'Phases': return 'success';
case 'Clients': return 'info';
case 'Stock': return 'warning';
case 'Système': return 'danger';
case 'Facturation': return 'success';
default: return 'info';
}
};
return (
<Tag value={rowData.categorie} severity={getCategorieColor(rowData.categorie)} />
);
};
const header = (
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
<h5 className="m-0">Règles de notifications automatiques</h5>
<div className="flex gap-2 mt-2 md:mt-0">
<Button
label="Tout activer"
icon="pi pi-check-square"
className="p-button-text p-button-success"
onClick={activerTout}
/>
<Button
label="Tout désactiver"
icon="pi pi-times"
className="p-button-text p-button-secondary"
onClick={desactiverTout}
/>
</div>
</div>
);
const activeCount = rules.filter(r => r.actif).length;
const totalCount = rules.length;
return (
<div className="grid">
<div className="col-12">
<h2>Notifications Automatiques</h2>
<p className="text-color-secondary">
Configurez les notifications automatiques envoyées lors d'événements spécifiques
</p>
</div>
<div className="col-12">
<Toast ref={toast} />
<Card>
<Message
severity="info"
content={
<div>
<div className="font-bold mb-2">Configuration des notifications automatiques</div>
<div className="text-sm">
{activeCount} règle{activeCount > 1 ? 's' : ''} activée{activeCount > 1 ? 's' : ''} sur {totalCount}
</div>
</div>
}
className="mb-4"
/>
<DataTable
value={rules}
dataKey="id"
paginator
rows={10}
rowsPerPageOptions={[5, 10, 25]}
className="datatable-responsive"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
currentPageReportTemplate="Affichage de {first} à {last} sur {totalRecords} règles"
emptyMessage="Aucune règle configurée."
header={header}
responsiveLayout="scroll"
>
<Column field="nom" header="Nom" sortable style={{ minWidth: '15rem' }} />
<Column field="description" header="Description" style={{ minWidth: '20rem' }} />
<Column field="categorie" header="Catégorie" body={categorieBodyTemplate} sortable style={{ minWidth: '10rem' }} />
<Column field="type" header="Type" body={typeBodyTemplate} sortable style={{ minWidth: '8rem' }} />
<Column field="actif" header="Statut" body={statusBodyTemplate} sortable style={{ minWidth: '8rem' }} />
<Column header="Activer/Désactiver" body={actionBodyTemplate} style={{ minWidth: '10rem' }} />
</DataTable>
<Divider />
<div className="text-sm text-color-secondary">
<h5 className="mt-0 mb-3">Informations sur les notifications automatiques</h5>
<div className="grid">
<div className="col-12 md:col-6">
<h6 className="text-color">Événements de chantiers</h6>
<ul className="pl-3 mt-2">
<li>Création de nouveau chantier</li>
<li>Chantier terminé</li>
<li>Retard détecté</li>
</ul>
</div>
<div className="col-12 md:col-6">
<h6 className="text-color">Événements de budget</h6>
<ul className="pl-3 mt-2">
<li>Dépassement de budget</li>
<li>Seuil d'alerte atteint</li>
</ul>
</div>
<div className="col-12 md:col-6">
<h6 className="text-color">Événements de stock</h6>
<ul className="pl-3 mt-2">
<li>Stock faible</li>
<li>Rupture de stock</li>
</ul>
</div>
<div className="col-12 md:col-6">
<h6 className="text-color">Événements système</h6>
<ul className="pl-3 mt-2">
<li>Erreurs critiques</li>
<li>Mises à jour importantes</li>
</ul>
</div>
</div>
</div>
</Card>
</div>
</div>
);
};
export default NotificationsAutomatiquesPage;