website refactor
This commit is contained in:
134
apps/website/app/profile/ProfilePageClient.tsx
Normal file
134
apps/website/app/profile/ProfilePageClient.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import Button from '@/components/ui/Button';
|
||||
import Card from '@/components/ui/Card';
|
||||
import Container from '@/components/ui/Container';
|
||||
import Heading from '@/components/ui/Heading';
|
||||
import Input from '@/components/ui/Input';
|
||||
import TabNavigation from '@/components/ui/TabNavigation';
|
||||
import { routes } from '@/lib/routing/RouteConfig';
|
||||
import type { Result } from '@/lib/contracts/Result';
|
||||
import type { ProfileViewData } from '@/lib/view-data/ProfileViewData';
|
||||
|
||||
type ProfileTab = 'overview' | 'history' | 'stats';
|
||||
|
||||
type SaveError = string | null;
|
||||
|
||||
interface ProfilePageClientProps {
|
||||
viewData: ProfileViewData;
|
||||
mode: 'profile-exists' | 'needs-profile';
|
||||
onSaveSettings: (updates: { bio?: string; country?: string }) => Promise<Result<void, string>>;
|
||||
}
|
||||
|
||||
export function ProfilePageClient({ viewData, mode, onSaveSettings }: ProfilePageClientProps) {
|
||||
const [activeTab, setActiveTab] = useState<ProfileTab>('overview');
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
const [bio, setBio] = useState(viewData.driver.bio ?? '');
|
||||
const [countryCode, setCountryCode] = useState(viewData.driver.countryCode ?? '');
|
||||
const [saveError, setSaveError] = useState<SaveError>(null);
|
||||
|
||||
if (mode === 'needs-profile') {
|
||||
return (
|
||||
<Container size="md">
|
||||
<Heading level={1}>Create your driver profile</Heading>
|
||||
<Card>
|
||||
<p>Driver profile not found for this account.</p>
|
||||
<Link href={routes.protected.onboarding}>
|
||||
<Button variant="primary">Start onboarding</Button>
|
||||
</Link>
|
||||
</Card>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
if (editMode) {
|
||||
return (
|
||||
<Container size="md">
|
||||
<Heading level={1}>Edit profile</Heading>
|
||||
|
||||
<Card>
|
||||
<Heading level={3}>Profile</Heading>
|
||||
|
||||
<Input
|
||||
value={bio}
|
||||
onChange={(e) => setBio(e.target.value)}
|
||||
placeholder="Bio"
|
||||
/>
|
||||
|
||||
<Input
|
||||
value={countryCode}
|
||||
onChange={(e) => setCountryCode(e.target.value)}
|
||||
placeholder="Country code (e.g. DE)"
|
||||
/>
|
||||
|
||||
{saveError ? <p>{saveError}</p> : null}
|
||||
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={async () => {
|
||||
setSaveError(null);
|
||||
const result = await onSaveSettings({ bio, country: countryCode });
|
||||
if (result.isErr()) {
|
||||
setSaveError(result.getError());
|
||||
return;
|
||||
}
|
||||
setEditMode(false);
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
|
||||
<Button variant="secondary" onClick={() => setEditMode(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
</Card>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Container size="lg">
|
||||
<Heading level={1}>{viewData.driver.name || 'Profile'}</Heading>
|
||||
|
||||
<Button variant="primary" onClick={() => setEditMode(true)}>
|
||||
Edit profile
|
||||
</Button>
|
||||
|
||||
<TabNavigation
|
||||
tabs={[
|
||||
{ id: 'overview', label: 'Overview' },
|
||||
{ id: 'history', label: 'Race History' },
|
||||
{ id: 'stats', label: 'Detailed Stats' },
|
||||
]}
|
||||
activeTab={activeTab}
|
||||
onTabChange={(tabId) => setActiveTab(tabId as ProfileTab)}
|
||||
/>
|
||||
|
||||
{activeTab === 'overview' ? (
|
||||
<Card>
|
||||
<Heading level={3}>Driver</Heading>
|
||||
<p>{viewData.driver.countryCode}</p>
|
||||
<p>{viewData.driver.joinedAtLabel}</p>
|
||||
<p>{viewData.driver.bio ?? ''}</p>
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{activeTab === 'history' ? (
|
||||
<Card>
|
||||
<Heading level={3}>Race history</Heading>
|
||||
<p>Race history is currently unavailable in this view.</p>
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{activeTab === 'stats' ? (
|
||||
<Card>
|
||||
<Heading level={3}>Stats</Heading>
|
||||
<p>{viewData.stats?.ratingLabel ?? ''}</p>
|
||||
<p>{viewData.stats?.globalRankLabel ?? ''}</p>
|
||||
</Card>
|
||||
) : null}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user