169 lines
5.2 KiB
TypeScript
169 lines
5.2 KiB
TypeScript
'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}
|
||
/>
|
||
);
|
||
} |