fix: Update PrimeReact and fix all compilation errors
This commit is contained in:
760
app/(main)/admin/attributions/page.tsx
Normal file → Executable file
760
app/(main)/admin/attributions/page.tsx
Normal file → Executable file
@@ -1,381 +1,381 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { DataTable } from 'primereact/datatable';
|
||||
import { Column } from 'primereact/column';
|
||||
import { Button } from 'primereact/button';
|
||||
import { Card } from 'primereact/card';
|
||||
import { Toast } from 'primereact/toast';
|
||||
import { Toolbar } from 'primereact/toolbar';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import { Dropdown } from 'primereact/dropdown';
|
||||
import { MultiSelect } from 'primereact/multiselect';
|
||||
import { Tag } from 'primereact/tag';
|
||||
import { Divider } from 'primereact/divider';
|
||||
import clientService from '../../../../services/clientService';
|
||||
import userService from '../../../../services/userService';
|
||||
import type { Client } from '../../../../types/btp';
|
||||
import type { User } from '../../../../types/auth';
|
||||
|
||||
interface ClientGestionnaire {
|
||||
client: Client;
|
||||
gestionnairePrincipal?: User;
|
||||
gestionnairesSecondaires: User[];
|
||||
}
|
||||
|
||||
const AttributionsPage = () => {
|
||||
const [clients, setClients] = useState<Client[]>([]);
|
||||
const [gestionnaires, setGestionnaires] = useState<User[]>([]);
|
||||
const [attributions, setAttributions] = useState<ClientGestionnaire[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [attributionDialog, setAttributionDialog] = useState(false);
|
||||
const [selectedClient, setSelectedClient] = useState<Client | null>(null);
|
||||
const [selectedGestionnairePrincipal, setSelectedGestionnairePrincipal] = useState<User | null>(null);
|
||||
const [selectedGestionnairesSecondaires, setSelectedGestionnairesSecondaires] = useState<User[]>([]);
|
||||
const toast = useRef<Toast>(null);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Charger les clients
|
||||
const clientsData = await clientService.getAll();
|
||||
setClients(clientsData);
|
||||
|
||||
// Charger les gestionnaires depuis le service
|
||||
const gestionnairesData = await userService.getGestionnaires();
|
||||
setGestionnaires(gestionnairesData);
|
||||
|
||||
// Construire les attributions
|
||||
const attributionsData = clientsData.map(client => ({
|
||||
client,
|
||||
gestionnairePrincipal: gestionnairesData.find(g => g.id === client.gestionnairePrincipalId),
|
||||
gestionnairesSecondaires: gestionnairesData.filter(g =>
|
||||
client.gestionnairesSecondaires?.includes(g.id)
|
||||
)
|
||||
}));
|
||||
setAttributions(attributionsData);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du chargement des données:', error);
|
||||
toast.current?.show({
|
||||
severity: 'error',
|
||||
summary: 'Erreur',
|
||||
detail: 'Impossible de charger les données',
|
||||
life: 3000
|
||||
});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const openAttributionDialog = (client: Client) => {
|
||||
setSelectedClient(client);
|
||||
|
||||
// Pré-remplir les sélections actuelles
|
||||
const gestionnairePrincipal = gestionnaires.find(g => g.id === client.gestionnairePrincipalId);
|
||||
setSelectedGestionnairePrincipal(gestionnairePrincipal || null);
|
||||
|
||||
const gestionnairesSecondaires = gestionnaires.filter(g =>
|
||||
client.gestionnairesSecondaires?.includes(g.id)
|
||||
);
|
||||
setSelectedGestionnairesSecondaires(gestionnairesSecondaires);
|
||||
|
||||
setAttributionDialog(true);
|
||||
};
|
||||
|
||||
const saveAttribution = async () => {
|
||||
if (!selectedClient) return;
|
||||
|
||||
try {
|
||||
const updatedClient = {
|
||||
...selectedClient,
|
||||
gestionnairePrincipalId: selectedGestionnairePrincipal?.id,
|
||||
gestionnairesSecondaires: selectedGestionnairesSecondaires.map(g => g.id)
|
||||
};
|
||||
|
||||
// Mise à jour côté serveur
|
||||
await clientService.update(selectedClient.id, updatedClient);
|
||||
|
||||
// Mettre à jour localement
|
||||
const updatedClients = clients.map(c =>
|
||||
c.id === selectedClient.id ? updatedClient : c
|
||||
);
|
||||
setClients(updatedClients);
|
||||
|
||||
// Mettre à jour les attributions
|
||||
const updatedAttributions = attributions.map(a =>
|
||||
a.client.id === selectedClient.id
|
||||
? {
|
||||
...a,
|
||||
client: updatedClient,
|
||||
gestionnairePrincipal: selectedGestionnairePrincipal || undefined,
|
||||
gestionnairesSecondaires: selectedGestionnairesSecondaires
|
||||
}
|
||||
: a
|
||||
);
|
||||
setAttributions(updatedAttributions);
|
||||
|
||||
setAttributionDialog(false);
|
||||
toast.current?.show({
|
||||
severity: 'success',
|
||||
summary: 'Succès',
|
||||
detail: 'Attribution mise à jour',
|
||||
life: 3000
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la sauvegarde:', error);
|
||||
toast.current?.show({
|
||||
severity: 'error',
|
||||
summary: 'Erreur',
|
||||
detail: 'Impossible de sauvegarder l\'attribution',
|
||||
life: 3000
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const hideDialog = () => {
|
||||
setAttributionDialog(false);
|
||||
setSelectedClient(null);
|
||||
setSelectedGestionnairePrincipal(null);
|
||||
setSelectedGestionnairesSecondaires([]);
|
||||
};
|
||||
|
||||
const leftToolbarTemplate = () => {
|
||||
return (
|
||||
<div className="my-2">
|
||||
<Button
|
||||
label="Actualiser"
|
||||
icon="pi pi-refresh"
|
||||
className="mr-2"
|
||||
onClick={loadData}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const rightToolbarTemplate = () => {
|
||||
return (
|
||||
<div className="flex align-items-center">
|
||||
<span className="text-color-secondary mr-2">
|
||||
{attributions.filter(a => a.gestionnairePrincipal).length} / {attributions.length} clients attribués
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const actionBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
return (
|
||||
<Button
|
||||
icon="pi pi-pencil"
|
||||
className="p-button-rounded p-button-text p-button-info"
|
||||
tooltip="Attribuer"
|
||||
onClick={() => openAttributionDialog(rowData.client)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const clientBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
return (
|
||||
<div className="flex flex-column">
|
||||
<span className="font-medium">{`${rowData.client.prenom} ${rowData.client.nom}`}</span>
|
||||
{rowData.client.entreprise && (
|
||||
<span className="text-sm text-color-secondary">{rowData.client.entreprise}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const gestionnairePrincipalBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
if (!rowData.gestionnairePrincipal) {
|
||||
return (
|
||||
<Tag
|
||||
value="Non attribué"
|
||||
severity="danger"
|
||||
className="text-sm"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-column">
|
||||
<span className="font-medium">
|
||||
{`${rowData.gestionnairePrincipal.prenom} ${rowData.gestionnairePrincipal.nom}`}
|
||||
</span>
|
||||
<span className="text-sm text-color-secondary">
|
||||
{rowData.gestionnairePrincipal.email}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const gestionnairesSecondairesBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
if (rowData.gestionnairesSecondaires.length === 0) {
|
||||
return <span className="text-color-secondary">Aucun</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-column gap-1">
|
||||
{rowData.gestionnairesSecondaires.map(gestionnaire => (
|
||||
<Tag
|
||||
key={gestionnaire.id}
|
||||
value={`${gestionnaire.prenom} ${gestionnaire.nom}`}
|
||||
severity="info"
|
||||
className="text-sm"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const header = (
|
||||
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
|
||||
<h5 className="m-0">Attribution des Clients aux Gestionnaires</h5>
|
||||
</div>
|
||||
);
|
||||
|
||||
const attributionDialogFooter = (
|
||||
<>
|
||||
<Button
|
||||
label="Annuler"
|
||||
icon="pi pi-times"
|
||||
text
|
||||
onClick={hideDialog}
|
||||
/>
|
||||
<Button
|
||||
label="Sauvegarder"
|
||||
icon="pi pi-check"
|
||||
text
|
||||
onClick={saveAttribution}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="grid">
|
||||
<div className="col-12">
|
||||
<Card>
|
||||
<Toast ref={toast} />
|
||||
<Toolbar
|
||||
className="mb-4"
|
||||
left={leftToolbarTemplate}
|
||||
right={rightToolbarTemplate}
|
||||
/>
|
||||
|
||||
<DataTable
|
||||
value={attributions}
|
||||
dataKey="client.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} attributions"
|
||||
emptyMessage="Aucune attribution trouvée."
|
||||
header={header}
|
||||
responsiveLayout="scroll"
|
||||
loading={loading}
|
||||
>
|
||||
<Column
|
||||
header="Client"
|
||||
body={clientBodyTemplate}
|
||||
sortable
|
||||
headerStyle={{ minWidth: '15rem' }}
|
||||
/>
|
||||
<Column
|
||||
header="Gestionnaire Principal"
|
||||
body={gestionnairePrincipalBodyTemplate}
|
||||
headerStyle={{ minWidth: '15rem' }}
|
||||
/>
|
||||
<Column
|
||||
header="Gestionnaires Secondaires"
|
||||
body={gestionnairesSecondairesBodyTemplate}
|
||||
headerStyle={{ minWidth: '12rem' }}
|
||||
/>
|
||||
<Column
|
||||
body={actionBodyTemplate}
|
||||
headerStyle={{ minWidth: '8rem' }}
|
||||
/>
|
||||
</DataTable>
|
||||
|
||||
<Dialog
|
||||
visible={attributionDialog}
|
||||
style={{ width: '600px' }}
|
||||
header="Attribution des Gestionnaires"
|
||||
modal
|
||||
className="p-fluid"
|
||||
footer={attributionDialogFooter}
|
||||
onHide={hideDialog}
|
||||
>
|
||||
{selectedClient && (
|
||||
<div>
|
||||
<div className="field mb-4">
|
||||
<h6 className="text-primary">Client</h6>
|
||||
<div className="p-3 surface-100 border-round">
|
||||
<div className="font-medium text-lg">
|
||||
{`${selectedClient.prenom} ${selectedClient.nom}`}
|
||||
</div>
|
||||
{selectedClient.entreprise && (
|
||||
<div className="text-color-secondary">
|
||||
{selectedClient.entreprise}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<div className="field">
|
||||
<label htmlFor="gestionnairePrincipal">
|
||||
<strong>Gestionnaire Principal</strong>
|
||||
</label>
|
||||
<Dropdown
|
||||
id="gestionnairePrincipal"
|
||||
value={selectedGestionnairePrincipal}
|
||||
options={gestionnaires}
|
||||
onChange={(e) => setSelectedGestionnairePrincipal(e.value)}
|
||||
'use client';
|
||||
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { DataTable } from 'primereact/datatable';
|
||||
import { Column } from 'primereact/column';
|
||||
import { Button } from 'primereact/button';
|
||||
import { Card } from 'primereact/card';
|
||||
import { Toast } from 'primereact/toast';
|
||||
import { Toolbar } from 'primereact/toolbar';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import { Dropdown } from 'primereact/dropdown';
|
||||
import { MultiSelect } from 'primereact/multiselect';
|
||||
import { Tag } from 'primereact/tag';
|
||||
import { Divider } from 'primereact/divider';
|
||||
import clientService from '../../../../services/clientService';
|
||||
import userService from '../../../../services/userService';
|
||||
import type { Client } from '../../../../types/btp';
|
||||
import type { User } from '../../../../types/auth';
|
||||
|
||||
interface ClientGestionnaire {
|
||||
client: Client;
|
||||
gestionnairePrincipal?: User;
|
||||
gestionnairesSecondaires: User[];
|
||||
}
|
||||
|
||||
const AttributionsPage = () => {
|
||||
const [clients, setClients] = useState<Client[]>([]);
|
||||
const [gestionnaires, setGestionnaires] = useState<User[]>([]);
|
||||
const [attributions, setAttributions] = useState<ClientGestionnaire[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [attributionDialog, setAttributionDialog] = useState(false);
|
||||
const [selectedClient, setSelectedClient] = useState<Client | null>(null);
|
||||
const [selectedGestionnairePrincipal, setSelectedGestionnairePrincipal] = useState<User | null>(null);
|
||||
const [selectedGestionnairesSecondaires, setSelectedGestionnairesSecondaires] = useState<User[]>([]);
|
||||
const toast = useRef<Toast>(null);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Charger les clients
|
||||
const clientsData = await clientService.getAll();
|
||||
setClients(clientsData);
|
||||
|
||||
// Charger les gestionnaires depuis le service
|
||||
const gestionnairesData = await userService.getGestionnaires();
|
||||
setGestionnaires(gestionnairesData);
|
||||
|
||||
// Construire les attributions
|
||||
const attributionsData = clientsData.map(client => ({
|
||||
client,
|
||||
gestionnairePrincipal: gestionnairesData.find(g => g.id === client.gestionnairePrincipalId),
|
||||
gestionnairesSecondaires: gestionnairesData.filter(g =>
|
||||
client.gestionnairesSecondaires?.includes(g.id)
|
||||
)
|
||||
}));
|
||||
setAttributions(attributionsData);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du chargement des données:', error);
|
||||
toast.current?.show({
|
||||
severity: 'error',
|
||||
summary: 'Erreur',
|
||||
detail: 'Impossible de charger les données',
|
||||
life: 3000
|
||||
});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const openAttributionDialog = (client: Client) => {
|
||||
setSelectedClient(client);
|
||||
|
||||
// Pré-remplir les sélections actuelles
|
||||
const gestionnairePrincipal = gestionnaires.find(g => g.id === client.gestionnairePrincipalId);
|
||||
setSelectedGestionnairePrincipal(gestionnairePrincipal || null);
|
||||
|
||||
const gestionnairesSecondaires = gestionnaires.filter(g =>
|
||||
client.gestionnairesSecondaires?.includes(g.id)
|
||||
);
|
||||
setSelectedGestionnairesSecondaires(gestionnairesSecondaires);
|
||||
|
||||
setAttributionDialog(true);
|
||||
};
|
||||
|
||||
const saveAttribution = async () => {
|
||||
if (!selectedClient) return;
|
||||
|
||||
try {
|
||||
const updatedClient = {
|
||||
...selectedClient,
|
||||
gestionnairePrincipalId: selectedGestionnairePrincipal?.id,
|
||||
gestionnairesSecondaires: selectedGestionnairesSecondaires.map(g => g.id)
|
||||
};
|
||||
|
||||
// Mise à jour côté serveur
|
||||
await clientService.update(selectedClient.id, updatedClient);
|
||||
|
||||
// Mettre à jour localement
|
||||
const updatedClients = clients.map(c =>
|
||||
c.id === selectedClient.id ? updatedClient : c
|
||||
);
|
||||
setClients(updatedClients);
|
||||
|
||||
// Mettre à jour les attributions
|
||||
const updatedAttributions = attributions.map(a =>
|
||||
a.client.id === selectedClient.id
|
||||
? {
|
||||
...a,
|
||||
client: updatedClient,
|
||||
gestionnairePrincipal: selectedGestionnairePrincipal || undefined,
|
||||
gestionnairesSecondaires: selectedGestionnairesSecondaires
|
||||
}
|
||||
: a
|
||||
);
|
||||
setAttributions(updatedAttributions);
|
||||
|
||||
setAttributionDialog(false);
|
||||
toast.current?.show({
|
||||
severity: 'success',
|
||||
summary: 'Succès',
|
||||
detail: 'Attribution mise à jour',
|
||||
life: 3000
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la sauvegarde:', error);
|
||||
toast.current?.show({
|
||||
severity: 'error',
|
||||
summary: 'Erreur',
|
||||
detail: 'Impossible de sauvegarder l\'attribution',
|
||||
life: 3000
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const hideDialog = () => {
|
||||
setAttributionDialog(false);
|
||||
setSelectedClient(null);
|
||||
setSelectedGestionnairePrincipal(null);
|
||||
setSelectedGestionnairesSecondaires([]);
|
||||
};
|
||||
|
||||
const leftToolbarTemplate = () => {
|
||||
return (
|
||||
<div className="my-2">
|
||||
<Button
|
||||
label="Actualiser"
|
||||
icon="pi pi-refresh"
|
||||
className="mr-2"
|
||||
onClick={loadData}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const rightToolbarTemplate = () => {
|
||||
return (
|
||||
<div className="flex align-items-center">
|
||||
<span className="text-color-secondary mr-2">
|
||||
{attributions.filter(a => a.gestionnairePrincipal).length} / {attributions.length} clients attribués
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const actionBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
return (
|
||||
<Button
|
||||
icon="pi pi-pencil"
|
||||
className="p-button-rounded p-button-text p-button-info"
|
||||
tooltip="Attribuer"
|
||||
onClick={() => openAttributionDialog(rowData.client)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const clientBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
return (
|
||||
<div className="flex flex-column">
|
||||
<span className="font-medium">{`${rowData.client.prenom} ${rowData.client.nom}`}</span>
|
||||
{rowData.client.entreprise && (
|
||||
<span className="text-sm text-color-secondary">{rowData.client.entreprise}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const gestionnairePrincipalBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
if (!rowData.gestionnairePrincipal) {
|
||||
return (
|
||||
<Tag
|
||||
value="Non attribué"
|
||||
severity="danger"
|
||||
className="text-sm"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-column">
|
||||
<span className="font-medium">
|
||||
{`${rowData.gestionnairePrincipal.prenom} ${rowData.gestionnairePrincipal.nom}`}
|
||||
</span>
|
||||
<span className="text-sm text-color-secondary">
|
||||
{rowData.gestionnairePrincipal.email}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const gestionnairesSecondairesBodyTemplate = (rowData: ClientGestionnaire) => {
|
||||
if (rowData.gestionnairesSecondaires.length === 0) {
|
||||
return <span className="text-color-secondary">Aucun</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-column gap-1">
|
||||
{rowData.gestionnairesSecondaires.map(gestionnaire => (
|
||||
<Tag
|
||||
key={gestionnaire.id}
|
||||
value={`${gestionnaire.prenom} ${gestionnaire.nom}`}
|
||||
severity="info"
|
||||
className="text-sm"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const header = (
|
||||
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
|
||||
<h5 className="m-0">Attribution des Clients aux Gestionnaires</h5>
|
||||
</div>
|
||||
);
|
||||
|
||||
const attributionDialogFooter = (
|
||||
<>
|
||||
<Button
|
||||
label="Annuler"
|
||||
icon="pi pi-times"
|
||||
text
|
||||
onClick={hideDialog}
|
||||
/>
|
||||
<Button
|
||||
label="Sauvegarder"
|
||||
icon="pi pi-check"
|
||||
text
|
||||
onClick={saveAttribution}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="grid">
|
||||
<div className="col-12">
|
||||
<Card>
|
||||
<Toast ref={toast} />
|
||||
<Toolbar
|
||||
className="mb-4"
|
||||
left={leftToolbarTemplate}
|
||||
right={rightToolbarTemplate}
|
||||
/>
|
||||
|
||||
<DataTable
|
||||
value={attributions}
|
||||
dataKey="client.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} attributions"
|
||||
emptyMessage="Aucune attribution trouvée."
|
||||
header={header}
|
||||
responsiveLayout="scroll"
|
||||
loading={loading}
|
||||
>
|
||||
<Column
|
||||
header="Client"
|
||||
body={clientBodyTemplate}
|
||||
sortable
|
||||
headerStyle={{ minWidth: '15rem' }}
|
||||
/>
|
||||
<Column
|
||||
header="Gestionnaire Principal"
|
||||
body={gestionnairePrincipalBodyTemplate}
|
||||
headerStyle={{ minWidth: '15rem' }}
|
||||
/>
|
||||
<Column
|
||||
header="Gestionnaires Secondaires"
|
||||
body={gestionnairesSecondairesBodyTemplate}
|
||||
headerStyle={{ minWidth: '12rem' }}
|
||||
/>
|
||||
<Column
|
||||
body={actionBodyTemplate}
|
||||
headerStyle={{ minWidth: '8rem' }}
|
||||
/>
|
||||
</DataTable>
|
||||
|
||||
<Dialog
|
||||
visible={attributionDialog}
|
||||
style={{ width: '600px' }}
|
||||
header="Attribution des Gestionnaires"
|
||||
modal
|
||||
className="p-fluid"
|
||||
footer={attributionDialogFooter}
|
||||
onHide={hideDialog}
|
||||
>
|
||||
{selectedClient && (
|
||||
<div>
|
||||
<div className="field mb-4">
|
||||
<h6 className="text-primary">Client</h6>
|
||||
<div className="p-3 surface-100 border-round">
|
||||
<div className="font-medium text-lg">
|
||||
{`${selectedClient.prenom} ${selectedClient.nom}`}
|
||||
</div>
|
||||
{selectedClient.entreprise && (
|
||||
<div className="text-color-secondary">
|
||||
{selectedClient.entreprise}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<div className="field">
|
||||
<label htmlFor="gestionnairePrincipal">
|
||||
<strong>Gestionnaire Principal</strong>
|
||||
</label>
|
||||
<Dropdown
|
||||
id="gestionnairePrincipal"
|
||||
value={selectedGestionnairePrincipal}
|
||||
options={gestionnaires}
|
||||
onChange={(e) => setSelectedGestionnairePrincipal(e.value)}
|
||||
optionLabel="nom"
|
||||
itemTemplate={(option) => option ? `${option.prenom} ${option.nom}` : ''}
|
||||
placeholder="Sélectionnez un gestionnaire principal"
|
||||
showClear
|
||||
className="w-full"
|
||||
/>
|
||||
<small className="text-color-secondary">
|
||||
Le gestionnaire principal est responsable de la relation client
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<label htmlFor="gestionnairesSecondaires">
|
||||
<strong>Gestionnaires Secondaires</strong>
|
||||
</label>
|
||||
<MultiSelect
|
||||
id="gestionnairesSecondaires"
|
||||
value={selectedGestionnairesSecondaires}
|
||||
options={gestionnaires.filter(g => g.id !== selectedGestionnairePrincipal?.id)}
|
||||
onChange={(e) => setSelectedGestionnairesSecondaires(e.value)}
|
||||
optionLabel="nom"
|
||||
itemTemplate={(option) => option ? `${option.prenom} ${option.nom}` : ''}
|
||||
placeholder="Sélectionnez un gestionnaire principal"
|
||||
showClear
|
||||
className="w-full"
|
||||
/>
|
||||
<small className="text-color-secondary">
|
||||
Le gestionnaire principal est responsable de la relation client
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<label htmlFor="gestionnairesSecondaires">
|
||||
<strong>Gestionnaires Secondaires</strong>
|
||||
</label>
|
||||
<MultiSelect
|
||||
id="gestionnairesSecondaires"
|
||||
value={selectedGestionnairesSecondaires}
|
||||
options={gestionnaires.filter(g => g.id !== selectedGestionnairePrincipal?.id)}
|
||||
onChange={(e) => setSelectedGestionnairesSecondaires(e.value)}
|
||||
optionLabel="nom"
|
||||
itemTemplate={(option) => option ? `${option.prenom} ${option.nom}` : ''}
|
||||
placeholder="Sélectionnez des gestionnaires secondaires"
|
||||
className="w-full"
|
||||
maxSelectedLabels={3}
|
||||
/>
|
||||
<small className="text-color-secondary">
|
||||
Les gestionnaires secondaires peuvent consulter et collaborer sur les projets
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttributionsPage;
|
||||
itemTemplate={(option) => option ? `${option.prenom} ${option.nom}` : ''}
|
||||
placeholder="Sélectionnez des gestionnaires secondaires"
|
||||
className="w-full"
|
||||
maxSelectedLabels={3}
|
||||
/>
|
||||
<small className="text-color-secondary">
|
||||
Les gestionnaires secondaires peuvent consulter et collaborer sur les projets
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttributionsPage;
|
||||
|
||||
3595
app/(main)/admin/demandes-acces/page.tsx
Normal file → Executable file
3595
app/(main)/admin/demandes-acces/page.tsx
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
0
app/(main)/admin/page.tsx
Normal file → Executable file
0
app/(main)/admin/page.tsx
Normal file → Executable file
3399
app/(main)/admin/parametres/page.tsx
Normal file → Executable file
3399
app/(main)/admin/parametres/page.tsx
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
1423
app/(main)/admin/roles/page.tsx
Normal file → Executable file
1423
app/(main)/admin/roles/page.tsx
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
2562
app/(main)/admin/sauvegarde/page.tsx
Normal file → Executable file
2562
app/(main)/admin/sauvegarde/page.tsx
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
1981
app/(main)/admin/utilisateurs/page.tsx
Normal file → Executable file
1981
app/(main)/admin/utilisateurs/page.tsx
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user