88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useTransition } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
import { updateProfileAction } from "../actions";
|
|
|
|
type Props = {
|
|
initial: { firstName: string; lastName: string; phone: string | null };
|
|
};
|
|
|
|
export function ProfileForm({ initial }: Props) {
|
|
const router = useRouter();
|
|
const [pending, startTransition] = useTransition();
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [success, setSuccess] = useState<string | null>(null);
|
|
|
|
function onSubmit(fd: FormData) {
|
|
setError(null);
|
|
setSuccess(null);
|
|
startTransition(async () => {
|
|
const res = await updateProfileAction(fd);
|
|
if (res && res.ok === false) setError(res.error);
|
|
else {
|
|
setSuccess("Profil enregistré.");
|
|
router.refresh();
|
|
}
|
|
});
|
|
}
|
|
|
|
const inputCls =
|
|
"mt-0.5 w-full rounded-md border border-zinc-300 px-3 py-2 text-sm focus:border-zinc-900 focus:outline-none";
|
|
|
|
return (
|
|
<form action={onSubmit} className="space-y-3">
|
|
<fieldset disabled={pending} className="space-y-3">
|
|
<div className="grid grid-cols-2 gap-2">
|
|
<label className="block">
|
|
<span className="text-xs text-zinc-600">Prénom</span>
|
|
<input
|
|
name="firstName"
|
|
type="text"
|
|
required
|
|
maxLength={100}
|
|
defaultValue={initial.firstName}
|
|
className={inputCls}
|
|
/>
|
|
</label>
|
|
<label className="block">
|
|
<span className="text-xs text-zinc-600">Nom</span>
|
|
<input
|
|
name="lastName"
|
|
type="text"
|
|
required
|
|
maxLength={100}
|
|
defaultValue={initial.lastName}
|
|
className={inputCls}
|
|
/>
|
|
</label>
|
|
</div>
|
|
<label className="block">
|
|
<span className="text-xs text-zinc-600">Téléphone (optionnel)</span>
|
|
<input
|
|
name="phone"
|
|
type="tel"
|
|
maxLength={40}
|
|
defaultValue={initial.phone ?? ""}
|
|
className={inputCls}
|
|
/>
|
|
</label>
|
|
|
|
{error ? (
|
|
<div className="rounded border border-rose-200 bg-rose-50 px-3 py-2 text-sm text-rose-700">{error}</div>
|
|
) : null}
|
|
{success ? (
|
|
<div className="rounded border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm text-emerald-800">{success}</div>
|
|
) : null}
|
|
|
|
<button
|
|
type="submit"
|
|
className="rounded-md bg-zinc-900 px-4 py-2 text-sm font-semibold text-white hover:bg-zinc-800 disabled:opacity-50"
|
|
>
|
|
{pending ? "Enregistrement…" : "Enregistrer"}
|
|
</button>
|
|
</fieldset>
|
|
</form>
|
|
);
|
|
}
|