Files
btpxpress-frontend/components/chantiers/ChantierActions.tsx

215 lines
5.4 KiB
TypeScript
Executable File

/**
* 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;