215 lines
5.4 KiB
TypeScript
215 lines
5.4 KiB
TypeScript
/**
|
|
* Composant réutilisable pour les actions sur les chantiers
|
|
*/
|
|
|
|
import React, { useRef } from 'react';
|
|
import { Button } from 'primereact/button';
|
|
import { Menu } from 'primereact/menu';
|
|
import { MenuItem } from 'primereact/menuitem';
|
|
import { ACTION_BUTTONS, COMMON_CLASSES, ActionButtonType } from './ChantierStyles';
|
|
import { ChantierActif } from '../../hooks/useDashboard';
|
|
|
|
interface ChantierActionsProps {
|
|
chantier: ChantierActif;
|
|
onQuickView?: (chantier: ChantierActif) => void;
|
|
onManagePhases?: (chantier: ChantierActif) => void;
|
|
onViewPlanning?: (chantier: ChantierActif) => void;
|
|
onViewStats?: (chantier: ChantierActif) => void;
|
|
onMenuAction?: (action: string, chantier: ChantierActif) => void;
|
|
showLabels?: boolean;
|
|
size?: 'small' | 'normal' | 'large';
|
|
layout?: 'horizontal' | 'vertical';
|
|
buttons?: ActionButtonType[];
|
|
className?: string;
|
|
}
|
|
|
|
const ChantierActions: React.FC<ChantierActionsProps> = ({
|
|
chantier,
|
|
onQuickView,
|
|
onManagePhases,
|
|
onViewPlanning,
|
|
onViewStats,
|
|
onMenuAction,
|
|
showLabels = false,
|
|
size = 'normal',
|
|
layout = 'horizontal',
|
|
buttons = ['VIEW', 'PHASES', 'PLANNING', 'STATS', 'MENU'],
|
|
className = ''
|
|
}) => {
|
|
const menuRef = useRef<Menu>(null);
|
|
|
|
const sizeClasses = {
|
|
small: 'p-button-sm',
|
|
normal: '',
|
|
large: 'p-button-lg'
|
|
};
|
|
|
|
const layoutClasses = {
|
|
horizontal: COMMON_CLASSES.BUTTON_GROUP,
|
|
vertical: 'flex flex-column gap-2'
|
|
};
|
|
|
|
// Configuration du menu contextuel
|
|
const menuItems: MenuItem[] = [
|
|
{
|
|
label: 'Navigation',
|
|
items: [
|
|
{
|
|
label: 'Détails complets',
|
|
icon: 'pi pi-external-link',
|
|
command: () => onMenuAction?.('details', chantier)
|
|
},
|
|
{
|
|
label: 'Documents',
|
|
icon: 'pi pi-file',
|
|
command: () => onMenuAction?.('documents', chantier)
|
|
},
|
|
{
|
|
label: 'Photos',
|
|
icon: 'pi pi-images',
|
|
command: () => onMenuAction?.('photos', chantier)
|
|
}
|
|
]
|
|
},
|
|
{ separator: true },
|
|
{
|
|
label: 'Ressources',
|
|
items: [
|
|
{
|
|
label: 'Équipe assignée',
|
|
icon: 'pi pi-users',
|
|
command: () => onMenuAction?.('team', chantier)
|
|
},
|
|
{
|
|
label: 'Matériel utilisé',
|
|
icon: 'pi pi-cog',
|
|
command: () => onMenuAction?.('equipment', chantier)
|
|
}
|
|
]
|
|
},
|
|
{ separator: true },
|
|
{
|
|
label: 'Rapports',
|
|
items: [
|
|
{
|
|
label: 'Générer rapport',
|
|
icon: 'pi pi-chart-bar',
|
|
command: () => onMenuAction?.('report', chantier)
|
|
},
|
|
{
|
|
label: 'Export PDF',
|
|
icon: 'pi pi-file-pdf',
|
|
command: () => onMenuAction?.('export-pdf', chantier)
|
|
},
|
|
{
|
|
label: 'Export Excel',
|
|
icon: 'pi pi-file-excel',
|
|
command: () => onMenuAction?.('export-excel', chantier)
|
|
}
|
|
]
|
|
},
|
|
{ separator: true },
|
|
{
|
|
label: 'Actions',
|
|
items: [
|
|
{
|
|
label: chantier.statut === 'SUSPENDU' ? 'Reprendre' : 'Suspendre',
|
|
icon: chantier.statut === 'SUSPENDU' ? 'pi pi-play' : 'pi pi-pause',
|
|
command: () => onMenuAction?.('toggle-suspend', chantier),
|
|
className: 'text-orange-500'
|
|
},
|
|
{
|
|
label: 'Clôturer',
|
|
icon: 'pi pi-check-circle',
|
|
command: () => onMenuAction?.('close', chantier),
|
|
disabled: chantier.statut === 'TERMINE',
|
|
className: 'text-green-500'
|
|
},
|
|
{
|
|
label: 'Archiver',
|
|
icon: 'pi pi-inbox',
|
|
command: () => onMenuAction?.('archive', chantier),
|
|
className: 'text-gray-500'
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
const handleMenuClick = (e: React.MouseEvent) => {
|
|
menuRef.current?.toggle(e);
|
|
};
|
|
|
|
const renderButton = (buttonType: ActionButtonType) => {
|
|
const config = ACTION_BUTTONS[buttonType];
|
|
const baseClassName = `${config.className} ${sizeClasses[size]}`;
|
|
|
|
const buttonProps = {
|
|
icon: config.icon,
|
|
tooltip: config.tooltip,
|
|
tooltipOptions: { position: 'top' as const, showDelay: 500 },
|
|
className: baseClassName,
|
|
'aria-label': config.tooltip
|
|
};
|
|
|
|
switch (buttonType) {
|
|
case 'VIEW':
|
|
return (
|
|
<Button
|
|
key="view"
|
|
{...buttonProps}
|
|
onClick={() => onQuickView?.(chantier)}
|
|
/>
|
|
);
|
|
|
|
case 'PHASES':
|
|
return (
|
|
<Button
|
|
key="phases"
|
|
{...buttonProps}
|
|
onClick={() => onManagePhases?.(chantier)}
|
|
/>
|
|
);
|
|
|
|
case 'PLANNING':
|
|
return (
|
|
<Button
|
|
key="planning"
|
|
{...buttonProps}
|
|
onClick={() => onViewPlanning?.(chantier)}
|
|
/>
|
|
);
|
|
|
|
case 'STATS':
|
|
return (
|
|
<Button
|
|
key="stats"
|
|
{...buttonProps}
|
|
onClick={() => onViewStats?.(chantier)}
|
|
/>
|
|
);
|
|
|
|
case 'MENU':
|
|
return (
|
|
<Button
|
|
key="menu"
|
|
{...buttonProps}
|
|
onClick={handleMenuClick}
|
|
/>
|
|
);
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className={`${layoutClasses[layout]} ${className}`}>
|
|
{buttons.map(buttonType => renderButton(buttonType))}
|
|
</div>
|
|
<Menu ref={menuRef} model={menuItems} popup />
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default ChantierActions; |