feat: add Terms & Conditions checkbox to signup (refs #4)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 4m38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 4m38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add terms_agreements table for legal audit trail - Create terms-agreement feature capsule with repository - Modify signup to create terms agreement atomically - Add checkbox with PDF link to SignupForm - Capture IP, User-Agent, terms version, content hash - Update CLAUDE.md documentation index 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,9 @@ const signupSchema = z
|
||||
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
|
||||
.regex(/[0-9]/, 'Password must contain at least one number'),
|
||||
confirmPassword: z.string(),
|
||||
termsAccepted: z.literal(true, {
|
||||
errorMap: () => ({ message: 'You must agree to the Terms & Conditions to create an account' }),
|
||||
}),
|
||||
})
|
||||
.refine((data) => data.password === data.confirmPassword, {
|
||||
message: 'Passwords do not match',
|
||||
@@ -42,8 +45,8 @@ export const SignupForm: React.FC<SignupFormProps> = ({ onSubmit, loading }) =>
|
||||
});
|
||||
|
||||
const handleFormSubmit = (data: SignupRequest & { confirmPassword: string }) => {
|
||||
const { email, password } = data;
|
||||
onSubmit({ email, password });
|
||||
const { email, password, termsAccepted } = data;
|
||||
onSubmit({ email, password, termsAccepted });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -138,6 +141,31 @@ export const SignupForm: React.FC<SignupFormProps> = ({ onSubmit, loading }) =>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-start min-h-[44px]">
|
||||
<label className="flex items-start cursor-pointer">
|
||||
<input
|
||||
{...register('termsAccepted')}
|
||||
type="checkbox"
|
||||
className="w-5 h-5 mt-0.5 rounded border-silverstone text-primary-600 focus:ring-abudhabi dark:border-silverstone dark:focus:ring-abudhabi"
|
||||
aria-label="I agree to the Terms and Conditions"
|
||||
/>
|
||||
<span className="ml-2 text-sm text-avus">
|
||||
I agree to the{' '}
|
||||
<a
|
||||
href="/docs/v2026-01-03.pdf"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-abudhabi hover:underline"
|
||||
>
|
||||
Terms & Conditions
|
||||
</a>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
{errors.termsAccepted && (
|
||||
<p className="text-sm text-red-400">{errors.termsAccepted.message}</p>
|
||||
)}
|
||||
|
||||
<div className="pt-4">
|
||||
<Button type="submit" loading={loading} className="w-full min-h-[44px]">
|
||||
Create Account
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
export interface SignupRequest {
|
||||
email: string;
|
||||
password: string;
|
||||
termsAccepted: boolean;
|
||||
}
|
||||
|
||||
export interface SignupResponse {
|
||||
|
||||
Reference in New Issue
Block a user