Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 19x 19x 1x 1x 18x 18x 12x 12x | /**
* SignupForm - Presentational component for signup
* Renders the signup form UI based on props, no hooks or side effects
*/
import { IconAlertTriangle, IconCheck } from '@tabler/icons-react';
import { Alert, Button, Card, Code, Group, Stack, Text, TextInput, Title } from '@mantine/core';
export interface SignupFormProps {
// Form state
username: string;
onUsernameChange: (value: string) => void;
onSubmit: (e: React.FormEvent) => void;
// Loading states
isLoading: boolean;
loadingText?: string;
// Error state
error?: string | null;
// Success state
successData?: {
account_id: string;
root_kid: string;
} | null;
}
export function SignupForm({
username,
onUsernameChange,
onSubmit,
isLoading,
loadingText,
error,
successData,
}: SignupFormProps) {
if (successData) {
return (
<Stack gap="md" maw={500} mx="auto" mt="xl">
<Alert icon={<IconCheck size={16} />} title="Account Created" color="green">
Your account has been created successfully.
</Alert>
<Card shadow="sm" padding="lg" radius="md" withBorder>
<Stack gap="sm">
<Text fw={500}>Account Details</Text>
<Text size="sm">
<strong>Account ID:</strong> <Code>{successData.account_id}</Code>
</Text>
<Text size="sm">
<strong>Root Key ID:</strong> <Code>{successData.root_kid}</Code>
</Text>
</Stack>
</Card>
<Text size="xs" c="dimmed" ta="center">
Your keys were generated locally.
<br />
(Key persistence will be added in a future update)
</Text>
</Stack>
);
}
return (
<Stack gap="md" maw={500} mx="auto" mt="xl">
<div>
<Title order={2}>Create Account</Title>
<Text c="dimmed" size="sm" mt="xs">
Sign up for TinyCongress with cryptographic identity
</Text>
</div>
<Card shadow="sm" padding="lg" radius="md" withBorder>
<form onSubmit={onSubmit}>
<Stack gap="md">
<TextInput
label="Username"
placeholder="alice"
required
value={username}
onChange={(e) => {
onUsernameChange(e.currentTarget.value);
}}
disabled={isLoading}
/>
{error ? (
<Alert icon={<IconAlertTriangle size={16} />} title="Signup failed" color="red">
{error}
</Alert>
) : null}
<Group justify="flex-end">
<Button type="submit" loading={isLoading}>
{loadingText ?? 'Sign Up'}
</Button>
</Group>
</Stack>
</form>
</Card>
<Text size="xs" c="dimmed" ta="center">
Your keys are generated locally and never leave your device.
</Text>
</Stack>
);
}
|