feat: Permettre modification des dates de travail pour techniciens en mode détails par date
This commit is contained in:
parent
e32d7a1aa9
commit
a24b8dfb09
2 changed files with 93 additions and 3 deletions
|
|
@ -2585,6 +2585,7 @@ export default function ContractEditor({
|
|||
<SalaireParDateEditor
|
||||
salairesParDate={contract.salaires_par_date}
|
||||
contractId={contract.id}
|
||||
categoriePro={categoriePro}
|
||||
onUpdate={(newSalaires) => {
|
||||
contract.salaires_par_date = newSalaires;
|
||||
setMontant(String(newSalaires.total_calcule));
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Edit2, Save, X } from "lucide-react";
|
||||
import { Edit2, Save, X, CalendarPlus, Trash2 } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import DatesQuantityModal from "@/components/DatesQuantityModal";
|
||||
|
||||
interface SalaireItem {
|
||||
numero: number;
|
||||
|
|
@ -29,12 +30,15 @@ interface SalaireParDateEditorProps {
|
|||
salairesParDate: SalairesParDate;
|
||||
contractId: string;
|
||||
onUpdate?: (newSalaires: SalairesParDate) => void;
|
||||
categoriePro?: "Artiste" | "Technicien";
|
||||
}
|
||||
|
||||
export function SalaireParDateEditor({ salairesParDate, contractId, onUpdate }: SalaireParDateEditorProps) {
|
||||
export function SalaireParDateEditor({ salairesParDate, contractId, onUpdate, categoriePro }: SalaireParDateEditorProps) {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [editedData, setEditedData] = useState<SalairesParDate>(salairesParDate);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [isDatesModalOpen, setIsDatesModalOpen] = useState(false);
|
||||
const [pendingDates, setPendingDates] = useState<string[]>([]);
|
||||
|
||||
// Calculer le total
|
||||
const calculateTotal = (data: SalairesParDate): number => {
|
||||
|
|
@ -94,6 +98,49 @@ export function SalaireParDateEditor({ salairesParDate, contractId, onUpdate }:
|
|||
}
|
||||
};
|
||||
|
||||
// Supprimer un jour travaillé
|
||||
const deleteJourTravail = (jourIdx: number) => {
|
||||
const newData = { ...editedData };
|
||||
if (newData.jours_travail) {
|
||||
newData.jours_travail = newData.jours_travail.filter((_, idx) => idx !== jourIdx);
|
||||
newData.total_calcule = calculateTotal(newData);
|
||||
setEditedData(newData);
|
||||
}
|
||||
};
|
||||
|
||||
// Ouvrir le modal de sélection de dates
|
||||
const handleOpenDatesModal = () => {
|
||||
const existingDates = editedData.jours_travail?.map(jour => jour.date) || [];
|
||||
setPendingDates(existingDates);
|
||||
setIsDatesModalOpen(true);
|
||||
};
|
||||
|
||||
// Appliquer les nouvelles dates sélectionnées
|
||||
const handleApplyDates = (result: {
|
||||
selectedDates: string[];
|
||||
hasMultiMonth: boolean;
|
||||
pdfFormatted: string;
|
||||
globalQuantity?: number;
|
||||
globalDuration?: "3" | "4";
|
||||
totalHours?: number;
|
||||
totalQuantities?: number;
|
||||
}) => {
|
||||
const newData = { ...editedData };
|
||||
|
||||
// Créer les nouveaux jours de travail avec les montants existants ou 0
|
||||
newData.jours_travail = result.selectedDates.map((date) => {
|
||||
const existing = editedData.jours_travail?.find(j => j.date === date);
|
||||
return {
|
||||
date: date,
|
||||
montant: existing?.montant || 0,
|
||||
};
|
||||
});
|
||||
|
||||
newData.total_calcule = calculateTotal(newData);
|
||||
setEditedData(newData);
|
||||
setIsDatesModalOpen(false);
|
||||
};
|
||||
|
||||
// Sauvegarder les modifications
|
||||
const handleSave = async () => {
|
||||
setIsSaving(true);
|
||||
|
|
@ -287,7 +334,21 @@ export function SalaireParDateEditor({ salairesParDate, contractId, onUpdate }:
|
|||
{/* Jours travaillés */}
|
||||
{currentData.jours_travail && currentData.jours_travail.length > 0 && (
|
||||
<div>
|
||||
<div className="text-xs font-semibold text-green-700 uppercase tracking-wide mb-2">Jours travaillés</div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="text-xs font-semibold text-green-700 uppercase tracking-wide">Jours travaillés</div>
|
||||
{isEditing && categoriePro === "Technicien" && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleOpenDatesModal}
|
||||
className="h-6 px-2 text-xs"
|
||||
>
|
||||
<CalendarPlus className="h-3 w-3 mr-1" />
|
||||
Modifier les dates
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="overflow-hidden rounded-md border border-slate-200">
|
||||
<table className="w-full text-xs">
|
||||
<thead className="bg-slate-100">
|
||||
|
|
@ -295,6 +356,9 @@ export function SalaireParDateEditor({ salairesParDate, contractId, onUpdate }:
|
|||
<th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Date</th>
|
||||
<th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Type</th>
|
||||
<th className="text-right px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Montant</th>
|
||||
{isEditing && categoriePro === "Technicien" && (
|
||||
<th className="text-center px-3 py-2 font-semibold text-slate-700 border-b border-slate-200 w-16">Actions</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white divide-y divide-slate-100">
|
||||
|
|
@ -315,6 +379,19 @@ export function SalaireParDateEditor({ salairesParDate, contractId, onUpdate }:
|
|||
<span className="font-semibold text-slate-900">{(jour.montant || 0).toFixed(2)} €</span>
|
||||
)}
|
||||
</td>
|
||||
{isEditing && categoriePro === "Technicien" && (
|
||||
<td className="px-3 py-2 text-center">
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => deleteJourTravail(jourIdx)}
|
||||
className="h-6 w-6 p-0 text-red-600 hover:text-red-700 hover:bg-red-50"
|
||||
>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
</Button>
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
|
@ -331,6 +408,18 @@ export function SalaireParDateEditor({ salairesParDate, contractId, onUpdate }:
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Modal de sélection de dates pour les techniciens */}
|
||||
{categoriePro === "Technicien" && (
|
||||
<DatesQuantityModal
|
||||
isOpen={isDatesModalOpen}
|
||||
onClose={() => setIsDatesModalOpen(false)}
|
||||
selectedDates={pendingDates}
|
||||
dateType="jours_travail"
|
||||
onApply={handleApplyDates}
|
||||
allowSkipHoursByDay={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue