page wrapper

This commit is contained in:
2026-01-07 12:40:52 +01:00
parent e589c30bf8
commit 0db80fa98d
128 changed files with 7386 additions and 8096 deletions

View File

@@ -1,169 +0,0 @@
'use client';
import { useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { useQuery } from '@tanstack/react-query';
import { DriverProfileTemplate } from '@/templates/DriverProfileTemplate';
import { useInject } from '@/lib/di/hooks/useInject';
import { DRIVER_SERVICE_TOKEN, TEAM_SERVICE_TOKEN } from '@/lib/di/tokens';
import SponsorInsightsCard, { useSponsorMode, MetricBuilders, SlotTemplates } from '@/components/sponsors/SponsorInsightsCard';
import { Car } from 'lucide-react';
interface Team {
id: string;
name: string;
}
interface TeamMembershipInfo {
team: Team;
role: string;
joinedAt: Date;
}
export function DriverProfileInteractive() {
const router = useRouter();
const params = useParams();
const driverId = params.id as string;
const driverService = useInject(DRIVER_SERVICE_TOKEN);
const teamService = useInject(TEAM_SERVICE_TOKEN);
const [activeTab, setActiveTab] = useState<'overview' | 'stats'>('overview');
const [friendRequestSent, setFriendRequestSent] = useState(false);
const isSponsorMode = useSponsorMode();
// Fetch driver profile using React-Query
const { data: driverProfile, isLoading, error, refetch } = useQuery({
queryKey: ['driverProfile', driverId],
queryFn: () => driverService.getDriverProfile(driverId),
});
// Fetch team memberships using React-Query
const { data: allTeamMemberships } = useQuery({
queryKey: ['driverTeamMemberships', driverId],
queryFn: async () => {
if (!driverProfile?.currentDriver) return [];
const allTeams = await teamService.getAllTeams();
const memberships: TeamMembershipInfo[] = [];
for (const team of allTeams) {
const teamMembers = await teamService.getTeamMembers(team.id, driverId, '');
const membership = teamMembers.find(member => member.driverId === driverId);
if (membership) {
memberships.push({
team: {
id: team.id,
name: team.name,
} as Team,
role: membership.role,
joinedAt: new Date(membership.joinedAt),
});
}
}
return memberships;
},
enabled: !!driverProfile?.currentDriver,
});
const handleAddFriend = () => {
setFriendRequestSent(true);
};
const handleBackClick = () => {
router.push('/drivers');
};
// Build sponsor insights for driver
const friendsCount = driverProfile?.socialSummary?.friends?.length ?? 0;
const stats = driverProfile?.stats || null;
const driver = driverProfile?.currentDriver;
const driverMetrics = [
MetricBuilders.rating(stats?.rating ?? 0, 'Driver Rating'),
MetricBuilders.views((friendsCount * 8) + 50),
MetricBuilders.engagement(stats?.consistency ?? 75),
MetricBuilders.reach((friendsCount * 12) + 100),
];
const sponsorInsights = isSponsorMode && driver ? (
<SponsorInsightsCard
entityType="driver"
entityId={driver.id}
entityName={driver.name}
tier="standard"
metrics={driverMetrics}
slots={SlotTemplates.driver(true, 200)}
trustScore={88}
monthlyActivity={stats?.consistency ?? 75}
/>
) : null;
// Loading state
if (isLoading) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
<p className="text-gray-600">Loading driver profile...</p>
</div>
</div>
);
}
// Error state
if (error) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="text-center max-w-md">
<div className="text-red-600 text-4xl mb-4"></div>
<h2 className="text-xl font-semibold text-gray-900 mb-2">Error loading driver profile</h2>
<p className="text-gray-600 mb-4">{error.message}</p>
<button
onClick={() => refetch()}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
>
Retry
</button>
</div>
</div>
);
}
// Empty state
if (!driverProfile) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="text-center max-w-md">
<div className="text-gray-400 text-4xl mb-4">
<Car size={48} />
</div>
<h2 className="text-xl font-semibold text-gray-900 mb-2">Driver not found</h2>
<p className="text-gray-600 mb-4">The driver profile may not exist or you may not have access</p>
<button
onClick={handleBackClick}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
>
Back to Drivers
</button>
</div>
</div>
);
}
return (
<DriverProfileTemplate
driverProfile={driverProfile}
allTeamMemberships={allTeamMemberships || []}
isLoading={false}
error={null}
onBackClick={handleBackClick}
onAddFriend={handleAddFriend}
friendRequestSent={friendRequestSent}
activeTab={activeTab}
setActiveTab={setActiveTab}
isSponsorMode={isSponsorMode}
sponsorInsights={sponsorInsights}
/>
);
}

View File

@@ -1,37 +0,0 @@
import { DriverProfileTemplate } from '@/templates/DriverProfileTemplate';
import { DriverProfileViewModel } from '@/lib/view-models/DriverProfileViewModel';
interface DriverProfileStaticProps {
profileData: DriverProfileViewModel;
teamMemberships: Array<{
team: { id: string; name: string };
role: string;
joinedAt: Date;
}>;
}
export async function DriverProfileStatic({ profileData, teamMemberships }: DriverProfileStaticProps) {
return (
<DriverProfileTemplate
driverProfile={profileData}
allTeamMemberships={teamMemberships}
isLoading={false}
error={null}
onBackClick={() => {
// This will be handled by the parent page component
window.history.back();
}}
onAddFriend={() => {
// Server component - no-op for static version
console.log('Add friend - static mode');
}}
friendRequestSent={false}
activeTab="overview"
setActiveTab={() => {
// Server component - no-op for static version
console.log('Set tab - static mode');
}}
isSponsorMode={false}
/>
);
}

View File

@@ -1,3 +1,81 @@
import { DriverProfileInteractive } from './DriverProfileInteractive';
'use client';
export default DriverProfileInteractive;
import { StatefulPageWrapper } from '@/components/shared/state/StatefulPageWrapper';
import { DriverProfileTemplate } from '@/templates/DriverProfileTemplate';
import { useDriverProfilePageData } from '@/hooks/driver/useDriverProfilePageData';
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react';
interface DriverProfileData {
driverProfile: any;
teamMemberships: Array<{
team: { id: string; name: string };
role: string;
joinedAt: Date;
}>;
}
export default function DriverProfilePage() {
const router = useRouter();
const params = useParams();
const driverId = params.id as string;
const currentDriverId = useEffectiveDriverId() || '';
// UI State
const [activeTab, setActiveTab] = useState<'overview' | 'stats'>('overview');
const [friendRequestSent, setFriendRequestSent] = useState(false);
// Fetch data using domain hook
const { data: queries, isLoading, error, refetch } = useDriverProfilePageData(driverId);
// Transform data for template
const data: DriverProfileData | undefined = queries?.driverProfile && queries?.teamMemberships
? {
driverProfile: queries.driverProfile,
teamMemberships: queries.teamMemberships,
}
: undefined;
// Actions
const handleAddFriend = () => {
setFriendRequestSent(true);
};
const handleBackClick = () => {
router.push('/drivers');
};
return (
<StatefulPageWrapper
data={data}
isLoading={isLoading}
error={error as Error | null}
retry={refetch}
Template={({ data }) => {
if (!data) return null;
return (
<DriverProfileTemplate
driverProfile={data.driverProfile}
allTeamMemberships={data.teamMemberships}
isLoading={false}
error={null}
onBackClick={handleBackClick}
onAddFriend={handleAddFriend}
friendRequestSent={friendRequestSent}
activeTab={activeTab}
setActiveTab={setActiveTab}
/>
);
}}
loading={{ variant: 'skeleton', message: 'Loading driver profile...' }}
errorConfig={{ variant: 'full-screen' }}
empty={{
icon: require('lucide-react').Car,
title: 'Driver not found',
description: 'The driver profile may not exist or you may not have access',
action: { label: 'Back to Drivers', onClick: handleBackClick }
}}
/>
);
}