'use client' import { useState, useEffect } from 'react' import { Plus, Edit2, Trash2, X, FileText } from 'lucide-react' import { formatCurrency } from '@/lib/utils' import { format } from 'date-fns' import { fr } from 'date-fns/locale' interface Contract { id: string name: string client: { id: string; name: string } startDate: string endDate: string | null setupPrice: number setupCost: number monthlyPrice: number monthlyCost: number status: string billingDay: number notes: string | null _count?: { invoices: number } } export function ContractsContent() { const [contracts, setContracts] = useState([]) const [loading, setLoading] = useState(true) const [showForm, setShowForm] = useState(false) const [editing, setEditing] = useState(null) const [clients, setClients] = useState<{ id: string; name: string }[]>([]) const [form, setForm] = useState({ clientId: '', name: '', startDate: format(new Date(), 'yyyy-MM-dd'), endDate: '', setupPrice: '', setupCost: '', monthlyPrice: '', monthlyCost: '', billingDay: '1', status: 'ACTIVE', notes: '', }) const [saving, setSaving] = useState(false) useEffect(() => { fetchContracts(); fetchClients() }, []) const fetchContracts = async () => { setLoading(true) try { const res = await fetch('/api/contracts') if (res.ok) { const data = await res.json() setContracts(data.contracts) } } finally { setLoading(false) } } const fetchClients = async () => { try { const res = await fetch('/api/clients') if (res.ok) { const data = await res.json() const sorted = (data.clients || []).sort((a: { name: string }, b: { name: string }) => a.name.localeCompare(b.name)) setClients(sorted) } } catch {} } const openNew = () => { setEditing(null) setForm({ clientId: '', name: '', startDate: format(new Date(), 'yyyy-MM-dd'), endDate: '', setupPrice: '', setupCost: '', monthlyPrice: '', monthlyCost: '', billingDay: '1', status: 'ACTIVE', notes: '', }) setShowForm(true) } const openEdit = (contract: Contract) => { setEditing(contract) setForm({ clientId: contract.client.id, name: contract.name, startDate: format(new Date(contract.startDate), 'yyyy-MM-dd'), endDate: contract.endDate ? format(new Date(contract.endDate), 'yyyy-MM-dd') : '', setupPrice: contract.setupPrice.toString(), setupCost: contract.setupCost.toString(), monthlyPrice: contract.monthlyPrice.toString(), monthlyCost: contract.monthlyCost.toString(), billingDay: contract.billingDay.toString(), status: contract.status, notes: contract.notes || '', }) setShowForm(true) } const handleSave = async () => { if (!form.clientId || !form.name.trim()) return setSaving(true) try { const body = { clientId: form.clientId, name: form.name, startDate: form.startDate, endDate: form.endDate || null, setupPrice: parseFloat(form.setupPrice) || 0, setupCost: parseFloat(form.setupCost) || 0, monthlyPrice: parseFloat(form.monthlyPrice) || 0, monthlyCost: parseFloat(form.monthlyCost) || 0, billingDay: parseInt(form.billingDay) || 1, status: form.status, notes: form.notes || null, } if (editing) { await fetch(`/api/contracts/${editing.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }) } else { await fetch('/api/contracts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }) } setShowForm(false) setEditing(null) fetchContracts() } finally { setSaving(false) } } const handleDelete = async (id: string) => { if (!confirm('Supprimer ce contrat ?')) return try { await fetch(`/api/contracts/${id}`, { method: 'DELETE' }) fetchContracts() } catch {} } const statusColors: Record = { PROPOSAL: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400', ACTIVE: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400', PAUSED: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400', CANCELLED: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400', EXPIRED: 'bg-slate-100 text-slate-700 dark:bg-slate-700 dark:text-slate-300', } const statusLabels: Record = { PROPOSAL: 'Proposition en cours', ACTIVE: 'Actif', PAUSED: 'En pause', CANCELLED: 'Annulé', EXPIRED: 'Expiré', } return (

Contrats

{showForm && (

{editing ? 'Modifier' : 'Nouveau'} contrat

setForm({ ...form, name: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />
setForm({ ...form, startDate: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />
setForm({ ...form, endDate: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />
setForm({ ...form, setupPrice: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />
setForm({ ...form, setupCost: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />
setForm({ ...form, monthlyPrice: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />
setForm({ ...form, monthlyCost: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />
setForm({ ...form, billingDay: e.target.value })} className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white text-sm" />