di usage in website

This commit is contained in:
2026-01-06 19:36:03 +01:00
parent 589b55a87e
commit e589c30bf8
191 changed files with 6367 additions and 4253 deletions

View File

@@ -1,12 +1,17 @@
'use client';
import Card from '@/components/ui/Card';
import type { LeagueAdminRosterJoinRequestViewModel } from '@/lib/view-models/LeagueAdminRosterJoinRequestViewModel';
import type { LeagueAdminRosterMemberViewModel } from '@/lib/view-models/LeagueAdminRosterMemberViewModel';
import type { MembershipRole } from '@/lib/types/MembershipRole';
import { useServices } from '@/lib/services/ServiceProvider';
import { useParams } from 'next/navigation';
import { useEffect, useMemo, useState } from 'react';
import { useMemo } from 'react';
import {
useLeagueRosterJoinRequests,
useLeagueRosterMembers,
useApproveJoinRequest,
useRejectJoinRequest,
useUpdateMemberRole,
useRemoveMember,
} from '@/hooks/league/useLeagueRosterAdmin';
const ROLE_OPTIONS: MembershipRole[] = ['owner', 'admin', 'steward', 'member'];
@@ -14,56 +19,56 @@ export function RosterAdminPage() {
const params = useParams();
const leagueId = params.id as string;
const { leagueService } = useServices();
// Fetch data using React-Query + DI
const {
data: joinRequests = [],
isLoading: loadingJoinRequests,
refetch: refetchJoinRequests,
} = useLeagueRosterJoinRequests(leagueId);
const [loading, setLoading] = useState(true);
const [joinRequests, setJoinRequests] = useState<LeagueAdminRosterJoinRequestViewModel[]>([]);
const [members, setMembers] = useState<LeagueAdminRosterMemberViewModel[]>([]);
const {
data: members = [],
isLoading: loadingMembers,
refetch: refetchMembers,
} = useLeagueRosterMembers(leagueId);
const loadRoster = async () => {
setLoading(true);
try {
const [requestsVm, membersVm] = await Promise.all([
leagueService.getAdminRosterJoinRequests(leagueId),
leagueService.getAdminRosterMembers(leagueId),
]);
setJoinRequests(requestsVm);
setMembers(membersVm);
} finally {
setLoading(false);
}
};
const loading = loadingJoinRequests || loadingMembers;
useEffect(() => {
void loadRoster();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [leagueId]);
// Mutations
const approveMutation = useApproveJoinRequest({
onSuccess: () => refetchJoinRequests(),
});
const rejectMutation = useRejectJoinRequest({
onSuccess: () => refetchJoinRequests(),
});
const updateRoleMutation = useUpdateMemberRole({
onError: () => refetchMembers(), // Refetch on error to restore state
});
const removeMemberMutation = useRemoveMember({
onSuccess: () => refetchMembers(),
});
const pendingCountLabel = useMemo(() => {
return joinRequests.length === 1 ? '1 request' : `${joinRequests.length} requests`;
}, [joinRequests.length]);
const handleApprove = async (joinRequestId: string) => {
await leagueService.approveJoinRequest(leagueId, joinRequestId);
setJoinRequests((prev) => prev.filter((r) => r.id !== joinRequestId));
await approveMutation.mutateAsync({ leagueId, joinRequestId });
};
const handleReject = async (joinRequestId: string) => {
await leagueService.rejectJoinRequest(leagueId, joinRequestId);
setJoinRequests((prev) => prev.filter((r) => r.id !== joinRequestId));
await rejectMutation.mutateAsync({ leagueId, joinRequestId });
};
const handleRoleChange = async (driverId: string, newRole: MembershipRole) => {
setMembers((prev) => prev.map((m) => (m.driverId === driverId ? { ...m, role: newRole } : m)));
const result = await leagueService.updateMemberRole(leagueId, driverId, newRole);
if (!result.success) {
await loadRoster();
}
await updateRoleMutation.mutateAsync({ leagueId, driverId, role: newRole });
};
const handleRemove = async (driverId: string) => {
await leagueService.removeMember(leagueId, driverId);
setMembers((prev) => prev.filter((m) => m.driverId !== driverId));
await removeMemberMutation.mutateAsync({ leagueId, driverId });
};
return (