import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Button } from '@/components/ui/button'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { useToast } from '@/hooks/use-toast'; import { Camera, User, Package, Users, IdCard, Save, X, Trash2 } from 'lucide-react'; import { Sale, FormData, PhotoType } from '@/types/sale'; import { validateRequiredFields, validateEAN13, ARTICLE_CATEGORY_MAPPING, IDENTITY_TYPES } from '@/lib/validation'; import { useCamera } from '@/hooks/useCamera'; import CameraModal from './CameraModal'; interface NewSaleFormProps { onSaveSale: (sale: Omit) => Promise; } export default function NewSaleForm({ onSaveSale }: NewSaleFormProps) { const { toast } = useToast(); const [photos, setPhotos] = useState<{ recto?: string; verso?: string }>({}); const [isSubmitting, setIsSubmitting] = useState(false); const camera = useCamera(); const form = useForm({ defaultValues: { vendeur: '', dateVente: new Date().toISOString().split('T')[0], typeArticle: '', categorie: '', quantite: '', gencode: '', nom: '', prenom: '', dateNaissance: '', lieuNaissance: '', typeIdentite: '', autoriteDelivrance: '', dateDelivrance: '', } }); const typeArticle = form.watch('typeArticle'); const availableCategories = typeArticle ? ARTICLE_CATEGORY_MAPPING[typeArticle as keyof typeof ARTICLE_CATEGORY_MAPPING] || [] : []; const handlePhotoCapture = async (photoType: PhotoType) => { try { await camera.startCamera(photoType); toast({ title: "Caméra activée", description: "Positionnez la carte d'identité", }); } catch (error) { toast({ title: "Erreur caméra", description: error instanceof Error ? error.message : "Impossible d'accéder à la caméra", variant: "destructive", }); } }; const handlePhotoTaken = (photoType: PhotoType, photoData: string) => { setPhotos(prev => ({ ...prev, [photoType]: photoData })); toast({ title: "Photo capturée", description: `Photo ${photoType} sauvegardée avec succès`, }); }; const deletePhoto = (photoType: PhotoType) => { setPhotos(prev => { const newPhotos = { ...prev }; delete newPhotos[photoType]; return newPhotos; }); toast({ title: "Photo supprimée", description: `Photo ${photoType} supprimée`, }); }; const onSubmit = async (data: FormData) => { try { setIsSubmitting(true); // Validate required fields const missingFields = validateRequiredFields(data); if (missingFields.length > 0) { toast({ title: "Champs manquants", description: `Veuillez remplir: ${missingFields.join(', ')}`, variant: "destructive", }); return; } // Validate EAN13 if provided if (data.gencode && !validateEAN13(data.gencode)) { toast({ title: "Code EAN13 invalide", description: "Le code produit doit être un code EAN13 valide à 13 chiffres", variant: "destructive", }); return; } const saleData: Omit = { vendeur: data.vendeur, dateVente: data.dateVente, typeArticle: data.typeArticle, categorie: data.categorie as 'F2' | 'F3', quantite: parseInt(data.quantite), gencode: data.gencode || undefined, nom: data.nom, prenom: data.prenom, dateNaissance: data.dateNaissance || undefined, lieuNaissance: data.lieuNaissance || undefined, typeIdentite: data.typeIdentite || undefined, autoriteDelivrance: data.autoriteDelivrance || undefined, dateDelivrance: data.dateDelivrance || undefined, photoRecto: photos.recto, photoVerso: photos.verso, }; await onSaveSale(saleData); // Reset form form.reset({ vendeur: '', dateVente: new Date().toISOString().split('T')[0], typeArticle: '', categorie: '', quantite: '', gencode: '', nom: '', prenom: '', dateNaissance: '', lieuNaissance: '', typeIdentite: '', autoriteDelivrance: '', dateDelivrance: '', }); setPhotos({}); toast({ title: "Vente enregistrée", description: "La vente a été enregistrée avec succès", }); } catch (error) { toast({ title: "Erreur", description: "Erreur lors de l'enregistrement de la vente", variant: "destructive", }); } finally { setIsSubmitting(false); } }; return ( <> Nouvelle Vente

Enregistrement d'une vente de feux d'artifice

{/* Seller Information */}

Informations Vendeur

( Nom du vendeur * )} /> ( Date de vente )} />
{/* Product Information */}

Informations Produit

( Type d'article * )} /> ( Catégorie réglementaire * )} /> ( Quantité * )} /> ( Code produit (EAN13) )} />
Information réglementaire :
  • • F2 : Feux d'artifice de catégorie F2 - Vente libre aux majeurs
  • • F3 : Feux d'artifice de catégorie F3 - Vente soumise à autorisation préfectorale
{/* Customer Information */}

Informations Client

( Nom de famille * )} /> ( Prénom * )} /> ( Date de naissance )} /> ( Lieu de naissance )} />
{/* Identity Document */}

Pièce d'Identité

( Type de pièce d'identité )} /> ( Autorité de délivrance )} /> ( Date de délivrance )} />
{/* Identity Photos */}

Photos de la Pièce d'Identité

{/* Photo Recto */}
{photos.recto ? (
Photo recto
) : (

Aucune photo

)}
{/* Photo Verso */}
{photos.verso ? (
Photo verso
) : (

Aucune photo

)}
{/* Form Actions */}
{ try { const photoData = await camera.capturePhoto(); if (camera.currentPhotoType) { handlePhotoTaken(camera.currentPhotoType, photoData); } camera.stopCamera(); } catch (error) { toast({ title: "Erreur", description: "Erreur lors de la capture de la photo", variant: "destructive", }); } }} /> ); }