This commit is contained in:
2026-01-15 01:26:30 +01:00
parent 4a2d7d15a5
commit c3b308e960
102 changed files with 2532 additions and 4744 deletions

View File

@@ -1,7 +1,13 @@
import { User, Clock, ChevronRight } from 'lucide-react';
import Input from '@/ui/Input';
import Heading from '@/ui/Heading';
import CountrySelect from '@/ui/CountrySelect';
import { Input } from '@/ui/Input';
import { Heading } from '@/ui/Heading';
import { CountrySelect } from '@/ui/CountrySelect';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Icon } from '@/ui/Icon';
import { Grid } from '@/ui/Grid';
import { Select } from '@/ui/Select';
export interface PersonalInfo {
firstName: string;
@@ -37,115 +43,115 @@ const TIMEZONES = [
export function PersonalInfoStep({ personalInfo, setPersonalInfo, errors, loading }: PersonalInfoStepProps) {
return (
<div className="space-y-6">
<div>
<Heading level={2} className="text-xl mb-1 flex items-center gap-2">
<User className="w-5 h-5 text-primary-blue" />
<Stack gap={6}>
<Box>
<Heading level={2} icon={<Icon icon={User} size={5} color="text-primary-blue" />}>
Personal Information
</Heading>
<p className="text-sm text-gray-400">
<Text size="sm" color="text-gray-400" block mt={1}>
Tell us a bit about yourself
</p>
</div>
</Text>
</Box>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label htmlFor="firstName" className="block text-sm font-medium text-gray-300 mb-2">
<Grid cols={2} gap={4}>
<Box>
<Text as="label" htmlFor="firstName" size="sm" weight="medium" color="text-gray-300" block mb={2}>
First Name *
</label>
</Text>
<Input
id="firstName"
type="text"
value={personalInfo.firstName}
onChange={(e) =>
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPersonalInfo({ ...personalInfo, firstName: e.target.value })
}
error={!!errors.firstName}
variant={errors.firstName ? 'error' : 'default'}
errorMessage={errors.firstName}
placeholder="John"
disabled={loading}
/>
</div>
</Box>
<div>
<label htmlFor="lastName" className="block text-sm font-medium text-gray-300 mb-2">
<Box>
<Text as="label" htmlFor="lastName" size="sm" weight="medium" color="text-gray-300" block mb={2}>
Last Name *
</label>
</Text>
<Input
id="lastName"
type="text"
value={personalInfo.lastName}
onChange={(e) =>
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPersonalInfo({ ...personalInfo, lastName: e.target.value })
}
error={!!errors.lastName}
variant={errors.lastName ? 'error' : 'default'}
errorMessage={errors.lastName}
placeholder="Racer"
disabled={loading}
/>
</div>
</div>
</Box>
</Grid>
<div>
<label htmlFor="displayName" className="block text-sm font-medium text-gray-300 mb-2">
Display Name * <span className="text-gray-500 font-normal">(shown publicly)</span>
</label>
<Box>
<Text as="label" htmlFor="displayName" size="sm" weight="medium" color="text-gray-300" block mb={2}>
Display Name * <Text color="text-gray-500" weight="normal">(shown publicly)</Text>
</Text>
<Input
id="displayName"
type="text"
value={personalInfo.displayName}
onChange={(e) =>
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPersonalInfo({ ...personalInfo, displayName: e.target.value })
}
error={!!errors.displayName}
variant={errors.displayName ? 'error' : 'default'}
errorMessage={errors.displayName}
placeholder="SpeedyRacer42"
disabled={loading}
/>
</div>
</Box>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label htmlFor="country" className="block text-sm font-medium text-gray-300 mb-2">
<Grid cols={2} gap={4}>
<Box>
<Text as="label" htmlFor="country" size="sm" weight="medium" color="text-gray-300" block mb={2}>
Country *
</label>
</Text>
<CountrySelect
value={personalInfo.country}
onChange={(value) =>
onChange={(value: string) =>
setPersonalInfo({ ...personalInfo, country: value })
}
error={!!errors.country}
errorMessage={errors.country ?? ''}
disabled={loading}
/>
</div>
</Box>
<div>
<label htmlFor="timezone" className="block text-sm font-medium text-gray-300 mb-2">
<Box>
<Text as="label" htmlFor="timezone" size="sm" weight="medium" color="text-gray-300" block mb={2}>
Timezone
</label>
<div className="relative">
<Clock className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500 z-10" />
<select
</Text>
<Box position="relative">
<Box position="absolute" left={3} top="50%" style={{ transform: 'translateY(-50%)' }} zIndex={10}>
<Icon icon={Clock} size={4} color="text-gray-500" />
</Box>
<Select
id="timezone"
value={personalInfo.timezone}
onChange={(e) =>
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
setPersonalInfo({ ...personalInfo, timezone: e.target.value })
}
className="block w-full rounded-md border-0 px-4 py-3 pl-10 bg-iron-gray text-white shadow-sm ring-1 ring-inset ring-charcoal-outline placeholder:text-gray-500 focus:ring-2 focus:ring-inset focus:ring-primary-blue transition-all duration-150 sm:text-sm appearance-none cursor-pointer"
options={[
{ value: '', label: 'Select timezone' },
...TIMEZONES
]}
className="pl-10"
disabled={loading}
>
<option value="">Select timezone</option>
{TIMEZONES.map((tz) => (
<option key={tz.value} value={tz.value}>
{tz.label}
</option>
))}
</select>
<ChevronRight className="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500 rotate-90" />
</div>
</div>
</div>
</div>
/>
<Box position="absolute" right={3} top="50%" style={{ transform: 'translateY(-50%)' }} pointerEvents="none">
<Icon icon={ChevronRight} size={4} color="text-gray-500" className="rotate-90" />
</Box>
</Box>
</Box>
</Grid>
</Stack>
);
}
}