Files
gridpilot.gg/apps/website/templates/ProfileTemplate.tsx
2026-01-19 18:01:30 +01:00

159 lines
5.6 KiB
TypeScript

'use client';
import { AchievementGrid } from '@/components/achievements/AchievementGrid';
import { CreateDriverForm } from '@/components/drivers/CreateDriverForm';
import { ProfileDetailsPanel } from '@/components/profile/ProfileDetailsPanel';
import { ProfileHeader } from '@/components/profile/ProfileHeader';
import { ProfileNavTabs, type ProfileTab } from '@/components/profile/ProfileNavTabs';
import { ProfileStatGrid } from '@/components/profile/ProfileStatGrid';
import { SessionHistoryTable } from '@/components/profile/SessionHistoryTable';
import { TeamMembershipGrid } from '@/components/teams/TeamMembershipGrid';
import type { ProfileViewData } from '@/lib/view-data/ProfileViewData';
import { Box } from '@/ui/Box';
import { Card } from '@/ui/Card';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { Stack } from '@/ui/Stack';
import { Surface } from '@/ui/Surface';
import { Text } from '@/ui/Text';
import { User } from 'lucide-react';
interface ProfileTemplateProps {
viewData: ProfileViewData;
mode: 'profile-exists' | 'needs-profile';
activeTab: ProfileTab;
onTabChange: (tab: ProfileTab) => void;
friendRequestSent: boolean;
onFriendRequestSend: () => void;
}
export function ProfileTemplate({
viewData,
mode,
activeTab,
onTabChange,
friendRequestSent,
onFriendRequestSend,
}: ProfileTemplateProps) {
if (mode === 'needs-profile') {
return (
<Stack align="center" gap={4} mb={8}>
<Surface variant="muted" rounded="xl" border padding={4}>
<Icon icon={User} size={8} color="var(--color-primary)" />
</Surface>
<Box>
<Heading level={1}>Create Your Driver Profile</Heading>
<Text color="text-gray-400">Join the GridPilot community and start your racing journey</Text>
</Box>
<Box maxWidth="42rem" mx="auto" width="100%">
<Card>
<Stack gap={6}>
<Box>
<Heading level={2}>Get Started</Heading>
<Text size="sm" color="text-gray-400">
Create your driver profile to join leagues, compete in races, and connect with other drivers.
</Text>
</Box>
<CreateDriverForm onSuccess={() => {}} isPending={false} />
</Stack>
</Card>
</Box>
</Stack>
);
}
return (
<Stack gap={8}>
<ProfileHeader
driver={{
...viewData.driver,
country: viewData.driver.countryCode,
iracingId: Number(viewData.driver.iracingId) || 0,
}}
stats={viewData.stats ? { ratingLabel: viewData.stats.ratingLabel } : null}
globalRankLabel={viewData.stats?.globalRankLabel || '—'}
onAddFriend={onFriendRequestSend}
friendRequestSent={friendRequestSent}
isOwnProfile={true}
/>
<ProfileNavTabs activeTab={activeTab} onTabChange={onTabChange} />
{activeTab === 'overview' && (
<Stack gap={8}>
<ProfileDetailsPanel
driver={{
name: viewData.driver.name,
country: viewData.driver.countryCode,
bio: viewData.driver.bio
}}
/>
{viewData.teamMemberships.length > 0 && (
<Box as="section" aria-labelledby="teams-heading">
<Stack gap={4}>
<Heading level={3} id="teams-heading">Teams</Heading>
<TeamMembershipGrid
memberships={viewData.teamMemberships.map(m => ({
team: { id: m.teamId, name: m.teamName },
role: m.roleLabel,
joinedAtLabel: m.joinedAtLabel
}))}
/>
</Stack>
</Box>
)}
{viewData.extendedProfile && (
<Box as="section" aria-labelledby="achievements-heading">
<Stack gap={4}>
<Stack direction="row" justify="between" align="center">
<Heading level={3} id="achievements-heading">Achievements</Heading>
<Text size="sm" color="text-gray-500">{viewData.extendedProfile.achievements.length} earned</Text>
</Stack>
<AchievementGrid
achievements={viewData.extendedProfile.achievements.map(a => ({
...a,
rarity: a.rarityLabel,
earnedAtLabel: a.earnedAtLabel
}))}
/>
</Stack>
</Box>
)}
</Stack>
)}
{activeTab === 'history' && (
<Box as="section" aria-labelledby="history-heading">
<Stack gap={4}>
<Heading level={3} id="history-heading">Race History</Heading>
<Card>
<SessionHistoryTable results={[]} />
</Card>
</Stack>
</Box>
)}
{activeTab === 'stats' && viewData.stats && (
<Box as="section" aria-labelledby="stats-heading">
<Stack gap={4}>
<Heading level={3} id="stats-heading">Performance Overview</Heading>
<Card>
<ProfileStatGrid
stats={[
{ label: 'Races', value: viewData.stats.totalRacesLabel },
{ label: 'Wins', value: viewData.stats.winsLabel, intent: 'success' },
{ label: 'Podiums', value: viewData.stats.podiumsLabel, intent: 'telemetry' },
{ label: 'Consistency', value: viewData.stats.consistencyLabel, intent: 'primary' },
]}
/>
</Card>
</Stack>
</Box>
)}
</Stack>
);
}