mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
Every word the landing, the header menus, the phone sheet, the footer,
the help corner and the way in (sign-in, sign-up, the reset, the
invitation, the callback, onboarding, the 404) write goes through
@hanzo/i18n's t(): one sentence is one message, its figures, names and
links arguments; copy written as data is phrase('…') where written and
t(label) where drawn. Plans, the chart, the API states and the lines
lib/kai and lib/enso build for the landing do the same.
Right to left: <html lang dir> is set before the first paint (the
package's bootScript first in the head); a figure, clock, range or
price outside a sentence is isolated; sides are logical gui props, the
layout's [data-join] corners logical, a bar grows from the start;
arrows along the line mirror (Onward for "words ->" links). The repo
dates read in the reader's language.
Gates select by slot, never by an English label (rtl, help). New gate
translated.spec.ts: in Arabic the landing at 1440 and 390, every menu
open, the phone sheet, sign-in, sign-up and the app signed in hold no
authored English, nothing scrolls sideways, every range is isolated;
French the same for English's commonest words. What another package
draws with no words prop is listed by name (@hanzo/ui's Footer label,
@hanzo/build's composer row and suggestions).
@hanzo/i18n 0.5.3 (the catalogs: 1,443 keys, every offered locale
complete), @hanzo/app 0.2.1 (the app's words). The link gate imports
the terms versions from @hanzo/app, the one SDK main now resolves.
68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* The terms, agreed once, by an account that has accepted none on record: the
|
|
* one a provider made a moment ago (/onboarding), or an address a code proved
|
|
* that holds no account yet (the sign-in panel's last step). IAM records the
|
|
* acceptance; this page asks for it and says nothing else. It is the focused
|
|
* page (components/shell/focus) like every page of the way in.
|
|
*/
|
|
|
|
import { useId, useState } from 'react'
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
import { Checkbox, Text, XStack, YStack } from '@hanzo/ui'
|
|
import { TextLink } from '@hanzo/ui/marketing'
|
|
import { Wrong } from '@/components/auth/steps'
|
|
import { Focus } from '@/components/shell/focus'
|
|
import { Pill, TILE } from './look'
|
|
|
|
export function Terms({
|
|
email,
|
|
busy,
|
|
wrong,
|
|
onCreate,
|
|
onOther,
|
|
title,
|
|
say,
|
|
}: {
|
|
/** The verified address the account is for. */
|
|
email: string
|
|
busy: boolean
|
|
wrong: string | null
|
|
onCreate: () => void
|
|
/** Another address: the page this one was reached from decides what that means. */
|
|
onOther: () => void
|
|
/** The page's heading, in the reader's language: /login names a new address's lack of an account here. */
|
|
title?: string
|
|
/** A line under it, in place of the address alone. */
|
|
say?: string
|
|
}) {
|
|
const { t } = useI18n()
|
|
const [agree, setAgree] = useState(false)
|
|
const id = useId()
|
|
return (
|
|
<Focus label={t('Terms')} title={title ?? t('Create your account')} line={say ?? (email || undefined)}>
|
|
<YStack gap="$4">
|
|
<XStack gap="$3" items="flex-start" p="$5" {...TILE} rounded={12}>
|
|
<Checkbox id={id} checked={agree} onCheckedChange={(v) => setAgree(v === true)} mt="$1" />
|
|
<Text render="label" htmlFor={id} flex={1} fontSize="$4" lineHeight="1.375rem" color="var(--foreground)">
|
|
{t("I agree to Hanzo's {terms} and {use} and confirm that I am at least 18 years of age.", {
|
|
terms: <TextLink href="/terms">{t('Terms of Service')}</TextLink>,
|
|
use: <TextLink href="/aup">{t('Acceptable Use Policy')}</TextLink>,
|
|
})}
|
|
</Text>
|
|
</XStack>
|
|
<Wrong text={wrong} />
|
|
<Pill fill disabled={!agree || busy} onPress={onCreate}>
|
|
{busy ? t('One moment…') : t('Create account')}
|
|
</Pill>
|
|
<XStack justify="center">
|
|
<TextLink onPress={onOther} disabled={busy} display="inline-flex" items="center" minH={44}>
|
|
{t('Use a different email')}
|
|
</TextLink>
|
|
</XStack>
|
|
</YStack>
|
|
</Focus>
|
|
)
|
|
}
|