Files
fotospiel-app/resources/js/admin/mobile/components/LegalConsentSheet.tsx
Codex Agent b1f9f7cee0
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Fix TypeScript typecheck errors
2026-01-30 15:56:06 +01:00

164 lines
4.9 KiB
TypeScript

import React from 'react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Checkbox } from '@tamagui/checkbox';
import { Check } from 'lucide-react';
import { MobileSheet } from './Sheet';
import { CTAButton } from './Primitives';
import { useAdminTheme } from '../theme';
type Translator = any;
type LegalConsentSheetProps = {
open: boolean;
onClose: () => void;
onConfirm: (consents: { acceptedTerms: boolean; acceptedWaiver: boolean }) => Promise<void> | void;
busy?: boolean;
requireTerms?: boolean;
requireWaiver?: boolean;
copy?: {
title?: string;
description?: string;
checkboxTerms?: string;
checkboxWaiver?: string;
errorTerms?: string;
errorWaiver?: string;
confirm?: string;
cancel?: string;
};
t: Translator;
};
export function LegalConsentSheet({
open,
onClose,
onConfirm,
busy = false,
requireTerms = true,
requireWaiver = true,
copy,
t,
}: LegalConsentSheetProps) {
const { primary, border, surface, danger, text } = useAdminTheme();
const [acceptedTerms, setAcceptedTerms] = React.useState(false);
const [acceptedWaiver, setAcceptedWaiver] = React.useState(false);
const [error, setError] = React.useState<string | null>(null);
React.useEffect(() => {
if (open) {
setAcceptedTerms(false);
setAcceptedWaiver(false);
setError(null);
}
}, [open]);
async function handleConfirm() {
if (requireTerms && !acceptedTerms) {
setError(copy?.errorTerms ?? t('events.legalConsent.errorTerms', 'Please confirm the terms.'));
return;
}
if (requireWaiver && !acceptedWaiver) {
setError(copy?.errorWaiver ?? t('events.legalConsent.errorWaiver', 'Please confirm the waiver.'));
return;
}
setError(null);
await onConfirm({
acceptedTerms: requireTerms ? acceptedTerms : true,
acceptedWaiver: requireWaiver ? acceptedWaiver : true,
});
}
return (
<MobileSheet
open={open}
onClose={onClose}
title={copy?.title ?? t('events.legalConsent.title', 'Before purchase')}
footer={
<YStack space="$2">
{error ? (
<Text fontSize="$sm" color={danger}>
{error}
</Text>
) : null}
<CTAButton
label={copy?.confirm ?? t('events.legalConsent.confirm', 'Continue to checkout')}
onPress={handleConfirm}
loading={busy}
disabled={busy}
/>
<CTAButton
label={copy?.cancel ?? t('events.legalConsent.cancel', 'Cancel')}
tone="ghost"
onPress={onClose}
disabled={busy}
/>
</YStack>
}
>
<YStack space="$2">
<Text fontSize="$sm" color={text}>
{copy?.description ?? t('events.legalConsent.description', 'Please confirm the legal notes before buying an add-on.')}
</Text>
{requireTerms ? (
<XStack space="$3" alignItems="flex-start">
<Checkbox
id="legal-terms"
size="$4"
checked={acceptedTerms}
onCheckedChange={(checked: boolean) => setAcceptedTerms(Boolean(checked))}
borderWidth={1}
borderColor={border}
backgroundColor={surface}
>
<Checkbox.Indicator>
<Check size={14} color={primary} />
</Checkbox.Indicator>
</Checkbox>
<Text
fontSize="$sm"
color={text}
onPress={() => setAcceptedTerms((prev) => !prev)}
flex={1}
>
{copy?.checkboxTerms ?? t(
'events.legalConsent.checkboxTerms',
'I have read and accept the Terms & Conditions, Privacy Policy, and Right of Withdrawal.',
)}
</Text>
</XStack>
) : null}
{requireWaiver ? (
<XStack space="$3" alignItems="flex-start">
<Checkbox
id="legal-waiver"
size="$4"
checked={acceptedWaiver}
onCheckedChange={(checked: boolean) => setAcceptedWaiver(Boolean(checked))}
borderWidth={1}
borderColor={border}
backgroundColor={surface}
>
<Checkbox.Indicator>
<Check size={14} color={primary} />
</Checkbox.Indicator>
</Checkbox>
<Text
fontSize="$sm"
color={text}
onPress={() => setAcceptedWaiver((prev) => !prev)}
flex={1}
>
{copy?.checkboxWaiver ?? t(
'events.legalConsent.checkboxWaiver',
'I expressly request immediate provision of the digital service and understand my right of withdrawal expires once fulfilled.',
)}
</Text>
</XStack>
) : null}
</YStack>
</MobileSheet>
);
}