error and load state
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import TeamDetailTemplate from '@/templates/TeamDetailTemplate';
|
||||
import { useServices } from '@/lib/services/ServiceProvider';
|
||||
import { TeamDetailsViewModel } from '@/lib/view-models/TeamDetailsViewModel';
|
||||
import { TeamMemberViewModel } from '@/lib/view-models/TeamMemberViewModel';
|
||||
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
|
||||
|
||||
// Shared state components
|
||||
import { useDataFetching } from '@/components/shared/hooks/useDataFetching';
|
||||
import { StateContainer } from '@/components/shared/state/StateContainer';
|
||||
import { Users } from 'lucide-react';
|
||||
|
||||
type Tab = 'overview' | 'roster' | 'standings' | 'admin';
|
||||
|
||||
export default function TeamDetailInteractive() {
|
||||
@@ -17,43 +20,37 @@ export default function TeamDetailInteractive() {
|
||||
const router = useRouter();
|
||||
const currentDriverId = useEffectiveDriverId();
|
||||
|
||||
const [team, setTeam] = useState<TeamDetailsViewModel | null>(null);
|
||||
const [memberships, setMemberships] = useState<TeamMemberViewModel[]>([]);
|
||||
const [activeTab, setActiveTab] = useState<Tab>('overview');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
|
||||
const loadTeamData = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const teamDetails = await teamService.getTeamDetails(teamId, currentDriverId);
|
||||
// Fetch team details
|
||||
const { data: teamDetails, isLoading: teamLoading, error: teamError, retry: teamRetry } = useDataFetching({
|
||||
queryKey: ['teamDetails', teamId, currentDriverId],
|
||||
queryFn: () => teamService.getTeamDetails(teamId, currentDriverId),
|
||||
});
|
||||
|
||||
if (!teamDetails) {
|
||||
setTeam(null);
|
||||
setMemberships([]);
|
||||
setIsAdmin(false);
|
||||
return;
|
||||
}
|
||||
// Fetch team members
|
||||
const { data: memberships, isLoading: membersLoading, error: membersError, retry: membersRetry } = useDataFetching({
|
||||
queryKey: ['teamMembers', teamId, currentDriverId],
|
||||
queryFn: async () => {
|
||||
if (!teamDetails?.ownerId) return [];
|
||||
return teamService.getTeamMembers(teamId, currentDriverId, teamDetails.ownerId);
|
||||
},
|
||||
enabled: !!teamDetails?.ownerId,
|
||||
});
|
||||
|
||||
const teamMembers = await teamService.getTeamMembers(teamId, currentDriverId, teamDetails.ownerId);
|
||||
const isLoading = teamLoading || membersLoading;
|
||||
const error = teamError || membersError;
|
||||
const retry = async () => {
|
||||
await teamRetry();
|
||||
await membersRetry();
|
||||
};
|
||||
|
||||
const adminStatus = teamDetails.isOwner ||
|
||||
teamMembers.some((m) => m.driverId === currentDriverId && (m.role === 'manager' || m.role === 'owner'));
|
||||
|
||||
setTeam(teamDetails);
|
||||
setMemberships(teamMembers);
|
||||
setIsAdmin(adminStatus);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [teamId, currentDriverId, teamService]);
|
||||
|
||||
useEffect(() => {
|
||||
void loadTeamData();
|
||||
}, [loadTeamData]);
|
||||
// Determine admin status
|
||||
const isAdmin = teamDetails?.isOwner ||
|
||||
(memberships || []).some((m: any) => m.driverId === currentDriverId && (m.role === 'manager' || m.role === 'owner'));
|
||||
|
||||
const handleUpdate = () => {
|
||||
loadTeamData();
|
||||
retry();
|
||||
};
|
||||
|
||||
const handleRemoveMember = async (driverId: string) => {
|
||||
@@ -111,17 +108,36 @@ export default function TeamDetailInteractive() {
|
||||
};
|
||||
|
||||
return (
|
||||
<TeamDetailTemplate
|
||||
team={team}
|
||||
memberships={memberships}
|
||||
activeTab={activeTab}
|
||||
loading={loading}
|
||||
isAdmin={isAdmin}
|
||||
onTabChange={setActiveTab}
|
||||
onUpdate={handleUpdate}
|
||||
onRemoveMember={handleRemoveMember}
|
||||
onChangeRole={handleChangeRole}
|
||||
onGoBack={handleGoBack}
|
||||
/>
|
||||
<StateContainer
|
||||
data={teamDetails}
|
||||
isLoading={isLoading}
|
||||
error={error}
|
||||
retry={retry}
|
||||
config={{
|
||||
loading: { variant: 'skeleton', message: 'Loading team details...' },
|
||||
error: { variant: 'full-screen' },
|
||||
empty: {
|
||||
icon: Users,
|
||||
title: 'Team not found',
|
||||
description: 'The team may have been deleted or you may not have access',
|
||||
action: { label: 'Back to Teams', onClick: () => router.push('/teams') }
|
||||
}
|
||||
}}
|
||||
>
|
||||
{(teamData) => (
|
||||
<TeamDetailTemplate
|
||||
team={teamData}
|
||||
memberships={memberships || []}
|
||||
activeTab={activeTab}
|
||||
loading={isLoading}
|
||||
isAdmin={isAdmin}
|
||||
onTabChange={setActiveTab}
|
||||
onUpdate={handleUpdate}
|
||||
onRemoveMember={handleRemoveMember}
|
||||
onChangeRole={handleChangeRole}
|
||||
onGoBack={handleGoBack}
|
||||
/>
|
||||
)}
|
||||
</StateContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user