From 209ac114b0f0807edc83944a71e17660818afdb2 Mon Sep 17 00:00:00 2001 From: belviskhoremk Date: Sun, 24 May 2026 18:50:28 +0000 Subject: [PATCH] Update May 24 by Elvis --- app/admin/commandes/page.tsx | 2 +- app/connexion/page.tsx | 104 +++++++++++++++++++++++++---------- app/mon-compte/page.tsx | 1 + app/reservation/page.tsx | 8 ++- components/Header.tsx | 6 +- contexts/AdminContext.tsx | 3 + contexts/LanguageContext.tsx | 6 ++ 7 files changed, 94 insertions(+), 36 deletions(-) diff --git a/app/admin/commandes/page.tsx b/app/admin/commandes/page.tsx index 1a79da9..e5ea648 100644 --- a/app/admin/commandes/page.tsx +++ b/app/admin/commandes/page.tsx @@ -131,7 +131,7 @@ export default function AdminCommandes() { #{o.id.slice(0, 8).toUpperCase()} -
{o.client_name ?? "—"}
+
{o.client_name || "—"}
{o.client_email ?? ""}
diff --git a/app/connexion/page.tsx b/app/connexion/page.tsx index 80d9814..7fd4d1c 100644 --- a/app/connexion/page.tsx +++ b/app/connexion/page.tsx @@ -7,14 +7,17 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { useLanguage } from "@/contexts/LanguageContext"; import { useAuth } from "@/contexts/AuthContext"; +import { forgotPassword } from "@/lib/api/auth"; import { ApiError } from "@/lib/api"; import { toast } from "sonner"; +type Mode = "login" | "register" | "forgot"; + export default function Auth() { const { t } = useLanguage(); const { login, register, user } = useAuth(); const router = useRouter(); - const [isLogin, setIsLogin] = useState(true); + const [mode, setMode] = useState("login"); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [name, setName] = useState(""); @@ -30,11 +33,11 @@ export default function Auth() { e.preventDefault(); setLoading(true); try { - if (isLogin) { + if (mode === "login") { const profile = await login(email, password); toast.success(t("auth.login_success")); router.push(profile.role === "admin" ? "/admin" : "/"); - } else { + } else if (mode === "register") { const profile = await register(email, password, name); if (profile) { toast.success(t("auth.register_success")); @@ -43,6 +46,11 @@ export default function Auth() { toast.success(t("auth.confirm_email")); router.push("/connexion"); } + } else { + await forgotPassword(email); + toast.success(t("auth.forgot_sent")); + setMode("login"); + setEmail(""); } } catch (err) { const msg = err instanceof ApiError ? err.message : t("auth.error"); @@ -56,14 +64,18 @@ export default function Auth() {

- {isLogin ? t("auth.login") : t("auth.register")} + {mode === "login" ? t("auth.login") : mode === "register" ? t("auth.register") : t("auth.forgot_title")}

- {isLogin ? t("auth.login_subtitle") : t("auth.register_subtitle")} + {mode === "login" + ? t("auth.login_subtitle") + : mode === "register" + ? t("auth.register_subtitle") + : t("auth.forgot_subtitle")}

- {!isLogin && ( + {mode === "register" && (
-
- - setPassword(e.target.value)} - className="mt-1" - required - minLength={8} - /> -
+ {mode !== "forgot" && ( +
+
+ + {mode === "login" && ( + + )} +
+ setPassword(e.target.value)} + required + minLength={8} + /> +
+ )}
-

- {isLogin ? t("auth.no_account") : t("auth.has_account")}{" "} - -

+ {mode === "forgot" ? ( +

+ +

+ ) : ( +

+ {mode === "login" ? t("auth.no_account") : t("auth.has_account")}{" "} + +

+ )}
); diff --git a/app/mon-compte/page.tsx b/app/mon-compte/page.tsx index 855f44d..2f1eb65 100644 --- a/app/mon-compte/page.tsx +++ b/app/mon-compte/page.tsx @@ -36,6 +36,7 @@ export default function MonCompte() { useEffect(() => { if (!isLoading && !user) router.replace("/connexion"); + if (!isLoading && user?.role === "admin") router.replace("/admin"); }, [user, isLoading, router]); useEffect(() => { diff --git a/app/reservation/page.tsx b/app/reservation/page.tsx index 78f3fcb..ed1cf28 100644 --- a/app/reservation/page.tsx +++ b/app/reservation/page.tsx @@ -236,7 +236,9 @@ export default function Booking() { {!user && ( <>
- +
- + - {user.full_name ?? user.email} + {user.full_name || user.email} diff --git a/contexts/AdminContext.tsx b/contexts/AdminContext.tsx index 52c4c53..a30f828 100644 --- a/contexts/AdminContext.tsx +++ b/contexts/AdminContext.tsx @@ -108,9 +108,12 @@ export const AdminProvider = ({ children }: { children: ReactNode }) => { const updateReservationStatus = async (id: string, status: "confirmed" | "cancelled") => { await bookingsApi.adminUpdateBookingStatus(id, status); + // Optimistic update for immediate feedback setReservations((prev) => prev.map((r) => (r.id === id ? { ...r, status } : r)) ); + // Refresh from server to ensure consistency + refreshReservations(); }; const deleteReservation = async (id: string) => { diff --git a/contexts/LanguageContext.tsx b/contexts/LanguageContext.tsx index 827d0a0..1fbbfaf 100644 --- a/contexts/LanguageContext.tsx +++ b/contexts/LanguageContext.tsx @@ -83,6 +83,12 @@ const translations: Record> = { "auth.no_account": { fr: "Pas encore de compte ?", de: "Noch kein Konto?", en: "No account yet?" }, "auth.has_account": { fr: "Déjà un compte ?", de: "Bereits ein Konto?", en: "Already have an account?" }, "auth.logout": { fr: "Se déconnecter", de: "Abmelden", en: "Log out" }, + "auth.forgot_link": { fr: "Mot de passe oublié ?", de: "Passwort vergessen?", en: "Forgot password?" }, + "auth.forgot_title": { fr: "Réinitialiser le mot de passe", de: "Passwort zurücksetzen", en: "Reset password" }, + "auth.forgot_subtitle": { fr: "Entrez votre email pour recevoir un lien de réinitialisation", de: "E-Mail eingeben, um einen Reset-Link zu erhalten", en: "Enter your email to receive a reset link" }, + "auth.forgot_send": { fr: "Envoyer le lien", de: "Link senden", en: "Send link" }, + "auth.forgot_sent": { fr: "Email envoyé ! Vérifiez votre boîte mail.", de: "E-Mail gesendet! Prüfen Sie Ihren Posteingang.", en: "Email sent! Check your inbox." }, + "auth.back_to_login": { fr: "Retour à la connexion", de: "Zurück zur Anmeldung", en: "Back to login" }, // ── Booking (public page) ──────────────────────────────────────────────────── "booking.select_service": { fr: "Choisir un service", de: "Service wählen", en: "Select service" },