- Ajout de la création d'utilisateurs staff (STAFF et SUPER_STAFF) - Email de notification avec lien d'activation (paie.odentas.fr) - API de révocation/restauration des utilisateurs staff - Sécurité: SUPER_STAFF ne peut pas être révoqué - Sécurité: Seul SUPER_STAFF peut créer d'autres SUPER_STAFF - Tableau des utilisateurs clients avec filtres (organisation, niveau, statut) - Tri dynamique sur toutes les colonnes (prénom, email, organisation, niveau, date) - Utilisation du client admin pour contourner les RLS - Interface avec recherche et filtres avancés
145 lines
5 KiB
TypeScript
145 lines
5 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
interface CreateStaffFormProps {
|
|
isSuperStaff: boolean;
|
|
}
|
|
|
|
export default function CreateStaffForm({ isSuperStaff }: CreateStaffFormProps) {
|
|
const router = useRouter();
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [success, setSuccess] = useState(false);
|
|
|
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
setError(null);
|
|
setSuccess(false);
|
|
|
|
const formData = new FormData(e.currentTarget);
|
|
const email = formData.get("email") as string;
|
|
const firstName = formData.get("firstName") as string;
|
|
const isSuperStaff = formData.get("isSuperStaff") === "on";
|
|
|
|
try {
|
|
const res = await fetch("/api/staff/users/create-staff", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ email, firstName, isSuperStaff }),
|
|
});
|
|
|
|
const data = await res.json();
|
|
|
|
if (!res.ok) {
|
|
throw new Error(data.error || data.message || "Erreur lors de la création");
|
|
}
|
|
|
|
setSuccess(true);
|
|
setTimeout(() => {
|
|
router.push("/staff/utilisateurs");
|
|
router.refresh();
|
|
}, 2000);
|
|
} catch (err: any) {
|
|
setError(err.message || "Erreur lors de la création de l'utilisateur staff");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="rounded-2xl border bg-white p-6">
|
|
<h2 className="text-lg font-semibold mb-4">Créer un utilisateur staff</h2>
|
|
|
|
{error && (
|
|
<div className="mb-4 p-3 rounded-lg bg-red-50 border border-red-200 text-red-800 text-sm">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
{success && (
|
|
<div className="mb-4 p-3 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm">
|
|
Utilisateur staff créé avec succès ! Un email d'activation a été envoyé. Redirection...
|
|
</div>
|
|
)}
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<div>
|
|
<label htmlFor="email" className="block text-sm font-medium text-slate-700 mb-1">
|
|
Email *
|
|
</label>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
required
|
|
disabled={loading || success}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 disabled:bg-slate-100"
|
|
placeholder="utilisateur@odentas.fr"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label htmlFor="firstName" className="block text-sm font-medium text-slate-700 mb-1">
|
|
Prénom
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="firstName"
|
|
name="firstName"
|
|
disabled={loading || success}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 disabled:bg-slate-100"
|
|
placeholder="Jean"
|
|
/>
|
|
</div>
|
|
|
|
{isSuperStaff && (
|
|
<div className="flex items-center gap-2">
|
|
<input
|
|
type="checkbox"
|
|
id="isSuperStaff"
|
|
name="isSuperStaff"
|
|
disabled={loading || success}
|
|
className="w-4 h-4 text-purple-600 border-slate-300 rounded focus:ring-purple-500"
|
|
/>
|
|
<label htmlFor="isSuperStaff" className="text-sm font-medium text-slate-700">
|
|
Super Staff (accès étendu)
|
|
</label>
|
|
</div>
|
|
)}
|
|
|
|
<div className="bg-slate-50 p-4 rounded-lg text-sm text-slate-600">
|
|
<p className="font-medium mb-2">Informations importantes :</p>
|
|
<ul className="list-disc list-inside space-y-1">
|
|
<li>L'utilisateur recevra un email avec un lien d'activation</li>
|
|
<li>Le lien est valable pendant 7 jours</li>
|
|
<li>L'utilisateur aura un accès complet en tant que staff</li>
|
|
<li>Il pourra gérer tous les clients et toutes les données</li>
|
|
{isSuperStaff && <li>Le statut Super Staff donne des privilèges étendus (création d'autres Super Staff, non-révocable)</li>}
|
|
</ul>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3">
|
|
<button
|
|
type="submit"
|
|
disabled={loading || success}
|
|
className="px-4 py-2 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
{loading ? "Création en cours..." : "Créer l'utilisateur staff"}
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
onClick={() => router.back()}
|
|
disabled={loading}
|
|
className="px-4 py-2 rounded-lg border border-slate-300 text-slate-700 text-sm font-medium hover:bg-slate-50 disabled:opacity-50"
|
|
>
|
|
Annuler
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|