From d4b10e06799ee537e74fda52102c17f95e6b6cf1 Mon Sep 17 00:00:00 2001 From: roble Date: Tue, 14 Jul 2026 12:35:34 +0100 Subject: [PATCH] feat: add terms acceptance checkbox and validation --- resources/js/react/pages/Login.tsx | 4 +- resources/js/react/pages/Register.tsx | 57 ++++++++++++++++- resources/js/vue/pages/Login.vue | 4 +- resources/js/vue/pages/Register.vue | 63 ++++++++++++++++++- src/Http/Requests/RegisterRequest.php | 13 ++++ tests/Feature/RegisterTest.php | 15 +++++ tests/e2e/pages/RegisterPage.ts | 4 ++ .../e2e/tests/register/register.basic.spec.ts | 15 +++++ 8 files changed, 166 insertions(+), 9 deletions(-) diff --git a/resources/js/react/pages/Login.tsx b/resources/js/react/pages/Login.tsx index 6e84633..fc63613 100644 --- a/resources/js/react/pages/Login.tsx +++ b/resources/js/react/pages/Login.tsx @@ -124,7 +124,7 @@ export default function Login() { {route().has('password.request') && ( {t('Forgot your password?')} @@ -145,7 +145,7 @@ export default function Login() { {(page.props.auth as any)?.magic_link_enabled && ( {t('Login with magic link')} diff --git a/resources/js/react/pages/Register.tsx b/resources/js/react/pages/Register.tsx index 6579862..6612f6b 100644 --- a/resources/js/react/pages/Register.tsx +++ b/resources/js/react/pages/Register.tsx @@ -1,5 +1,6 @@ import { Button } from '@/components/ui/button'; -import { Field, FieldError } from '@/components/ui/field'; +import { Checkbox } from '@/components/ui/checkbox'; +import { Field, FieldError, FieldLabel } from '@/components/ui/field'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { useT } from '@/i18n'; @@ -17,6 +18,7 @@ export default function Register() { email: '', password: '', password_confirmation: '', + terms: false, }); const handleSubmit = (e: React.FormEvent) => { @@ -24,6 +26,12 @@ export default function Register() { post(route('register'), { preserveScroll: true }); }; + const canSubmit = + data.name.trim() !== '' && + data.email.trim() !== '' && + data.password !== '' && + data.terms; + return ( + + + setData('terms', !!checked) + } + aria-invalid={!!errors.terms} + /> + + {t('I agree to the')}{' '} + + {t('Terms of Service')} + {' '} + {t('and the')}{' '} + + {t('Privacy Policy')} + + + + {errors.terms && ( + + {errors.terms} + + )} +