Initial commit
This commit is contained in:
215
components/chantiers/ChantierActions.tsx
Normal file
215
components/chantiers/ChantierActions.tsx
Normal file
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* 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;
|
||||
Reference in New Issue
Block a user