import { useState, useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { z } from "zod"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Checkbox } from "@/components/ui/checkbox"; import { Label } from "@/components/ui/label"; import { Calendar } from "@/components/ui/calendar"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { CalendarIcon } from "lucide-react"; import { format } from "date-fns"; import { fr } from "date-fns/locale"; import { safeDate } from "@/lib/dateUtils"; import { cn } from "@/lib/utils"; import { useToast } from "@/hooks/use-toast"; import type { PublicityWithRelations, Group } from "@shared/schema"; const publicityFormSchema = z.object({ pubNumber: z.string().min(1, "Le numéro PUB est requis"), designation: z.string().min(1, "La désignation est requise"), startDate: z.date({ required_error: "La date de début est requise" }), endDate: z.date({ required_error: "La date de fin est requise" }), year: z.number().min(2020).max(2030), participatingGroups: z.array(z.number()), // Suppression de .min(1) pour permettre 0 magasin }).refine((data) => data.endDate >= data.startDate, { message: "La date de fin doit être postérieure à la date de début", path: ["endDate"] }); type PublicityFormData = z.infer; interface PublicityFormProps { publicity?: PublicityWithRelations | null; groups: Group[]; onSuccess: () => void; selectedYear?: number; // Année sélectionnée depuis le filtre principal } export default function PublicityForm({ publicity, groups, onSuccess, selectedYear }: PublicityFormProps) { const [startCalendarOpen, setStartCalendarOpen] = useState(false); const [endCalendarOpen, setEndCalendarOpen] = useState(false); const { toast } = useToast(); const queryClient = useQueryClient(); const form = useForm({ resolver: zodResolver(publicityFormSchema), defaultValues: { pubNumber: publicity?.pubNumber || "", designation: publicity?.designation || "", startDate: publicity?.startDate ? safeDate(publicity.startDate) : undefined, endDate: publicity?.endDate ? safeDate(publicity.endDate) : undefined, year: publicity?.year || selectedYear || 2025, // Utilise l'année sélectionnée ou 2025 par défaut participatingGroups: publicity?.participations?.map(p => p.groupId) || [], }, }); // L'année est définie manuellement par l'utilisateur, pas automatiquement par la date const createMutation = useMutation({ mutationFn: async (data: PublicityFormData) => { const response = await fetch('/api/publicities', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pubNumber: data.pubNumber, designation: data.designation, startDate: format(data.startDate, 'yyyy-MM-dd'), endDate: format(data.endDate, 'yyyy-MM-dd'), year: data.year, participatingGroups: data.participatingGroups, }), }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'Erreur lors de la création'); } return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['/api/publicities'] }); toast({ description: "Publicité créée avec succès" }); onSuccess(); }, onError: (error: Error) => { toast({ variant: "destructive", description: error.message || "Erreur lors de la création" }); } }); const updateMutation = useMutation({ mutationFn: async (data: PublicityFormData) => { const response = await fetch(`/api/publicities/${publicity!.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pubNumber: data.pubNumber, designation: data.designation, startDate: format(data.startDate, 'yyyy-MM-dd'), endDate: format(data.endDate, 'yyyy-MM-dd'), year: data.year, participatingGroups: data.participatingGroups, }), }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'Erreur lors de la modification'); } return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['/api/publicities'] }); toast({ description: "Publicité modifiée avec succès" }); onSuccess(); }, onError: (error: Error) => { toast({ variant: "destructive", description: error.message || "Erreur lors de la modification" }); } }); const onSubmit = (data: PublicityFormData) => { if (publicity) { updateMutation.mutate(data); } else { createMutation.mutate(data); } }; const isLoading = createMutation.isPending || updateMutation.isPending; return (
{form.formState.errors.pubNumber && (

{form.formState.errors.pubNumber.message}

)}
{form.formState.errors.year && (

{form.formState.errors.year.message}

)}