212 lines
7.5 KiB
TypeScript
212 lines
7.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { X } from "lucide-react";
|
|
|
|
type Referrer = {
|
|
id: string;
|
|
code: string;
|
|
name: string;
|
|
contact_name?: string;
|
|
address?: string;
|
|
postal_code?: string;
|
|
city?: string;
|
|
email?: string;
|
|
};
|
|
|
|
type ReferrerModalProps = {
|
|
referrer?: Referrer | null;
|
|
onClose: () => void;
|
|
onSuccess: () => void;
|
|
};
|
|
|
|
export default function ReferrerModal({ referrer, onClose, onSuccess }: ReferrerModalProps) {
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const [formData, setFormData] = useState({
|
|
code: referrer?.code || "",
|
|
name: referrer?.name || "",
|
|
contact_name: referrer?.contact_name || "",
|
|
address: referrer?.address || "",
|
|
postal_code: referrer?.postal_code || "",
|
|
city: referrer?.city || "",
|
|
email: referrer?.email || ""
|
|
});
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const url = "/api/staff/referrers";
|
|
const method = referrer ? "PATCH" : "POST";
|
|
const body = referrer ? { id: referrer.id, ...formData } : formData;
|
|
|
|
const res = await fetch(url, {
|
|
method,
|
|
headers: { "Content-Type": "application/json" },
|
|
credentials: "include",
|
|
body: JSON.stringify(body)
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const data = await res.json();
|
|
throw new Error(data.error || "Erreur lors de l'enregistrement");
|
|
}
|
|
|
|
onSuccess();
|
|
onClose();
|
|
} catch (err: any) {
|
|
setError(err.message);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4">
|
|
<div className="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
|
|
<div className="sticky top-0 bg-white border-b border-slate-200 px-6 py-4 flex items-center justify-between">
|
|
<h2 className="text-xl font-bold text-slate-900">
|
|
{referrer ? "Modifier l'apporteur" : "Nouvel apporteur"}
|
|
</h2>
|
|
<button
|
|
onClick={onClose}
|
|
className="p-2 hover:bg-slate-100 rounded-lg transition"
|
|
>
|
|
<X className="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit} className="p-6 space-y-4">
|
|
{error && (
|
|
<div className="p-3 bg-red-50 border border-red-200 text-red-700 rounded-lg text-sm">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
Code <span className="text-red-500">*</span>
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
disabled={!!referrer}
|
|
value={formData.code}
|
|
onChange={(e) => setFormData({ ...formData, code: e.target.value.toUpperCase() })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent disabled:bg-slate-100 disabled:cursor-not-allowed"
|
|
placeholder="LDP"
|
|
/>
|
|
{referrer && (
|
|
<p className="text-xs text-slate-500 mt-1">Le code ne peut pas être modifié</p>
|
|
)}
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
Nom <span className="text-red-500">*</span>
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={formData.name}
|
|
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
|
placeholder="La Douce Prod"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
Nom du contact
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={formData.contact_name}
|
|
onChange={(e) => setFormData({ ...formData, contact_name: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
|
placeholder="Raphaël LEFEBVRE"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
Adresse
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={formData.address}
|
|
onChange={(e) => setFormData({ ...formData, address: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
|
placeholder="16 rue Nationale"
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-3 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
Code postal
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={formData.postal_code}
|
|
onChange={(e) => setFormData({ ...formData, postal_code: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
|
placeholder="59000"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-span-2">
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
Ville
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={formData.city}
|
|
onChange={(e) => setFormData({ ...formData, city: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
|
placeholder="LILLE"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">
|
|
Email
|
|
</label>
|
|
<input
|
|
type="email"
|
|
value={formData.email}
|
|
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
|
placeholder="contact@ladouceprod.fr"
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-end gap-3 pt-4 border-t border-slate-200">
|
|
<button
|
|
type="button"
|
|
onClick={onClose}
|
|
disabled={loading}
|
|
className="px-4 py-2 text-slate-700 bg-slate-100 hover:bg-slate-200 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
Annuler
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
disabled={loading}
|
|
className="px-4 py-2 text-white bg-indigo-600 hover:bg-indigo-700 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
{loading ? "Enregistrement..." : referrer ? "Modifier" : "Créer"}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|