164 lines
4.9 KiB
TypeScript
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>
|
|
);
|
|
}
|