import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { useAuthUnified } from "@/hooks/useAuthUnified"; import { useStore } from "@/contexts/StoreContext"; import { useToast } from "@/hooks/use-toast"; import { apiRequest } from "@/lib/queryClient"; import { Plus, Search, Building, Phone, Mail, User, Edit, Trash2, BookUser, StickyNote, } from "lucide-react"; import type { Supplier, Contact, Group } from "@shared/schema"; const CAN_EDIT_ROLES = ["admin", "directeur", "manager"]; const CAN_EDIT_SUPPLIER = ["admin", "directeur"]; export default function Contacts() { const { user } = useAuthUnified(); const { toast } = useToast(); const queryClient = useQueryClient(); const { stores, selectedStoreId } = useStore(); const canEdit = user?.role && CAN_EDIT_ROLES.includes(user.role); const canEditSupplier = user?.role && CAN_EDIT_SUPPLIER.includes(user.role); const isAdmin = user?.role === "admin"; // Pour les admins, permettre de choisir un magasin const [adminGroupId, setAdminGroupId] = useState(null); const effectiveGroupId = isAdmin ? adminGroupId : selectedStoreId; const [supplierSearch, setSupplierSearch] = useState(""); const [contactSearch, setContactSearch] = useState(""); // Modal contacts libres const [showModal, setShowModal] = useState(false); const [selectedContact, setSelectedContact] = useState(null); const [formData, setFormData] = useState({ groupId: effectiveGroupId ?? 0, name: "", company: "", role: "", phone: "", email: "", notes: "", }); // Modal coordonnées fournisseur const [showSupplierModal, setShowSupplierModal] = useState(false); const [selectedSupplier, setSelectedSupplier] = useState(null); const [supplierFormData, setSupplierFormData] = useState({ contact: "", phone: "", email: "", }); const { data: suppliers = [] } = useQuery({ queryKey: ["/api/suppliers"], }); const contactsQueryKey = effectiveGroupId ? [`/api/contacts?groupId=${effectiveGroupId}`] : ["/api/contacts"]; const { data: contacts = [] } = useQuery({ queryKey: contactsQueryKey, queryFn: async () => { const url = effectiveGroupId ? `/api/contacts?groupId=${effectiveGroupId}` : "/api/contacts"; return await apiRequest(url, "GET"); }, }); const createMutation = useMutation({ mutationFn: (data: any) => apiRequest("/api/contacts", "POST", data), onSuccess: () => { toast({ title: "Succès", description: "Contact créé avec succès" }); queryClient.invalidateQueries({ queryKey: ["/api/contacts"] }); closeModal(); }, onError: () => { toast({ title: "Erreur", description: "Impossible de créer le contact", variant: "destructive" }); }, }); const updateMutation = useMutation({ mutationFn: (data: any) => apiRequest(`/api/contacts/${selectedContact?.id}`, "PUT", data), onSuccess: () => { toast({ title: "Succès", description: "Contact modifié avec succès" }); queryClient.invalidateQueries({ queryKey: ["/api/contacts"] }); closeModal(); }, onError: () => { toast({ title: "Erreur", description: "Impossible de modifier le contact", variant: "destructive" }); }, }); const deleteMutation = useMutation({ mutationFn: (id: number) => apiRequest(`/api/contacts/${id}`, "DELETE"), onSuccess: () => { toast({ title: "Succès", description: "Contact supprimé" }); queryClient.invalidateQueries({ queryKey: ["/api/contacts"] }); }, onError: () => { toast({ title: "Erreur", description: "Impossible de supprimer le contact", variant: "destructive" }); }, }); const updateSupplierMutation = useMutation({ mutationFn: (data: any) => apiRequest(`/api/suppliers/${selectedSupplier?.id}`, "PUT", data), onSuccess: () => { toast({ title: "Succès", description: "Coordonnées fournisseur mises à jour" }); queryClient.invalidateQueries({ queryKey: ["/api/suppliers"] }); setShowSupplierModal(false); setSelectedSupplier(null); }, onError: () => { toast({ title: "Erreur", description: "Impossible de modifier le fournisseur", variant: "destructive" }); }, }); const openCreate = () => { setSelectedContact(null); setFormData({ groupId: effectiveGroupId ?? 0, name: "", company: "", role: "", phone: "", email: "", notes: "", }); setShowModal(true); }; const openEdit = (contact: Contact) => { setSelectedContact(contact); setFormData({ groupId: contact.groupId, name: contact.name, company: (contact as any).company || "", role: contact.role || "", phone: contact.phone || "", email: contact.email || "", notes: contact.notes || "", }); setShowModal(true); }; const closeModal = () => { setShowModal(false); setSelectedContact(null); }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const payload = { ...formData, groupId: effectiveGroupId ?? formData.groupId }; if (selectedContact) { updateMutation.mutate(payload); } else { createMutation.mutate(payload); } }; const handleDelete = (contact: Contact) => { if (confirm(`Supprimer le contact "${contact.name}" ?`)) { deleteMutation.mutate(contact.id); } }; const openEditSupplier = (supplier: Supplier) => { setSelectedSupplier(supplier); setSupplierFormData({ contact: supplier.contact || "", phone: supplier.phone || "", email: (supplier as any).email || "", }); setShowSupplierModal(true); }; const filteredSuppliers = suppliers.filter((s) => s.name.toLowerCase().includes(supplierSearch.toLowerCase()) || (s.contact || "").toLowerCase().includes(supplierSearch.toLowerCase()) ); const filteredContacts = contacts.filter((c) => c.name.toLowerCase().includes(contactSearch.toLowerCase()) || (c.role || "").toLowerCase().includes(contactSearch.toLowerCase()) ); const groupName = (groupId: number) => stores.find((s) => s.id === groupId)?.name ?? `Magasin #${groupId}`; return (
{/* Header */}

Contacts

Fournisseurs et contacts par magasin

{canEdit && effectiveGroupId && ( )}
{/* Sélecteur de magasin (admin uniquement) */} {isAdmin && (
)} {/* Deux colonnes */}
{/* Colonne Fournisseurs */}

Fournisseurs ({filteredSuppliers.length})

setSupplierSearch(e.target.value)} className="pl-10" />
{filteredSuppliers.length === 0 ? (
Aucun fournisseur trouvé
) : ( filteredSuppliers.map((supplier) => (

{supplier.name}

{supplier.contact && (

{supplier.contact}

)}
{canEditSupplier && ( )}
{supplier.phone && ( {supplier.phone} )} {(supplier as any).email && ( {(supplier as any).email} )} {!supplier.phone && !(supplier as any).email && (

Aucune coordonnée renseignée

)}
)) )}
{/* Colonne Autres contacts */}

Autres contacts ({filteredContacts.length})

setContactSearch(e.target.value)} className="pl-10" />
{!effectiveGroupId && !isAdmin && (
Sélectionnez un magasin pour voir les contacts
)} {(effectiveGroupId || isAdmin) && (
{filteredContacts.length === 0 ? (
Aucun contact {canEdit && effectiveGroupId && (
)}
) : ( filteredContacts.map((contact) => (

{contact.name}

{(contact as any).company && (

{(contact as any).company}

)} {contact.role && (

{contact.role}

)} {isAdmin && (

{groupName(contact.groupId)}

)}
{canEdit && (
)}
{contact.phone && ( {contact.phone} )} {contact.email && ( {contact.email} )} {contact.notes && (

{contact.notes}

)}
)) )}
)}
{/* Modal créer / modifier contact */} {selectedContact ? "Modifier le contact" : "Nouveau contact"}
{isAdmin && !selectedContact && (
)}
setFormData((p) => ({ ...p, name: e.target.value }))} placeholder="Nom du contact" required />
setFormData((p) => ({ ...p, company: e.target.value }))} placeholder="Nom de l'entreprise" />
setFormData((p) => ({ ...p, role: e.target.value }))} placeholder="Ex: Directeur régional, Commercial..." />
setFormData((p) => ({ ...p, phone: e.target.value }))} placeholder="Numéro de téléphone" />
setFormData((p) => ({ ...p, email: e.target.value }))} placeholder="Adresse email" />
setFormData((p) => ({ ...p, notes: e.target.value }))} placeholder="Notes libres..." />
{/* Modal coordonnées fournisseur */} { setShowSupplierModal(false); setSelectedSupplier(null); }}> Coordonnées — {selectedSupplier?.name}
{ e.preventDefault(); updateSupplierMutation.mutate(supplierFormData); }} className="space-y-4" >
setSupplierFormData((p) => ({ ...p, contact: e.target.value }))} placeholder="Nom du contact chez le fournisseur" />
setSupplierFormData((p) => ({ ...p, phone: e.target.value }))} placeholder="Numéro de téléphone" />
setSupplierFormData((p) => ({ ...p, email: e.target.value }))} placeholder="Adresse email" />
); }