Replace checkbox with React state-driven toggle for reliable terms acceptance
This commit is contained in:
1 parent
3becaf5f4f
commit
8818d5364e
1 file changed
+23
-11
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useActionState } from "react";
|
import { useActionState, useState } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { register } from "@/actions/register";
|
import { register } from "@/actions/register";
|
||||||
@@ -19,6 +19,7 @@ export function RegisterForm({
|
|||||||
const t = useTranslations("pages.register");
|
const t = useTranslations("pages.register");
|
||||||
const showCaptcha = captcha.provider !== "none" && !!captcha.siteKey;
|
const showCaptcha = captcha.provider !== "none" && !!captcha.siteKey;
|
||||||
const [serverError, formAction, isPending] = useActionState(register, null);
|
const [serverError, formAction, isPending] = useActionState(register, null);
|
||||||
|
const [termsAccepted, setTermsAccepted] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto w-full max-w-[800px]">
|
<div className="mx-auto w-full max-w-[800px]">
|
||||||
@@ -154,18 +155,29 @@ export function RegisterForm({
|
|||||||
<div className="rounded-md p-3 flex flex-col gap-3" style={{
|
<div className="rounded-md p-3 flex flex-col gap-3" style={{
|
||||||
backgroundColor: "color-mix(in srgb, var(--color-background) 50%, var(--color-surface))",
|
backgroundColor: "color-mix(in srgb, var(--color-background) 50%, var(--color-surface))",
|
||||||
}}>
|
}}>
|
||||||
<label className="flex flex-wrap items-center w-full gap-3 text-sm cursor-pointer">
|
<div className="flex items-center gap-3 text-sm">
|
||||||
<input
|
<button
|
||||||
name="terms"
|
type="button"
|
||||||
type="checkbox"
|
role="checkbox"
|
||||||
className="w-4 h-4 border-gray-300 rounded focus:ring-0 shrink-0"
|
aria-checked={termsAccepted}
|
||||||
style={{ borderColor: "color-mix(in srgb, var(--color-text-muted) 30%, transparent)" }}
|
onClick={() => setTermsAccepted(!termsAccepted)}
|
||||||
required
|
className="w-5 h-5 rounded border-2 flex items-center justify-center shrink-0 transition-colors"
|
||||||
/>
|
style={{
|
||||||
<span className="font-semibold" style={{ color: "var(--color-text)" }}>
|
borderColor: termsAccepted ? "#27a44d" : "color-mix(in srgb, var(--color-text-muted) 30%, transparent)",
|
||||||
|
backgroundColor: termsAccepted ? "#27a44d" : "transparent",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{termsAccepted && (
|
||||||
|
<svg className="w-3 h-3 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
<input type="hidden" name="terms" value={termsAccepted ? "1" : ""} />
|
||||||
|
<span className="font-semibold cursor-pointer" style={{ color: "var(--color-text)" }} onClick={() => setTermsAccepted(!termsAccepted)}>
|
||||||
{t("termsAccept", { hotel: hotelName })}
|
{t("termsAccept", { hotel: hotelName })}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Captcha */}
|
{/* Captcha */}
|
||||||
|
|||||||
Reference in new issue
Block a user