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,14 +1,12 @@
'use client';
import { useState, useEffect } from 'react';
import { useState } from 'react';
import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button';
import Input from '@/components/ui/Input';
import { useServices } from '@/lib/services/ServiceProvider';
import type { DriverViewModel } from '@/lib/view-models/DriverViewModel';
import { useTeamJoinRequests, useUpdateTeam, useApproveJoinRequest, useRejectJoinRequest } from '@/hooks/team';
import type { TeamJoinRequestViewModel } from '@/lib/view-models/TeamJoinRequestViewModel';
import type { TeamDetailsViewModel } from '@/lib/view-models/TeamDetailsViewModel';
import type { UpdateTeamViewModel } from '@/lib/view-models/UpdateTeamViewModel';
interface TeamAdminProps {
team: Pick<TeamDetailsViewModel, 'id' | 'name' | 'tag' | 'description' | 'ownerId'>;
@@ -16,10 +14,6 @@ interface TeamAdminProps {
}
export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
const { teamJoinService, teamService } = useServices();
const [joinRequests, setJoinRequests] = useState<TeamJoinRequestViewModel[]>([]);
const [requestDrivers, setRequestDrivers] = useState<Record<string, DriverViewModel>>({});
const [loading, setLoading] = useState(true);
const [editMode, setEditMode] = useState(false);
const [editedTeam, setEditedTeam] = useState({
name: team.name,
@@ -27,60 +21,63 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
description: team.description,
});
useEffect(() => {
const load = async () => {
setLoading(true);
try {
// Current build only supports read-only join requests. Driver hydration is
// not provided by the API response, so we only display driverId.
const currentUserId = team.ownerId;
const isOwner = true;
const requests = await teamJoinService.getJoinRequests(team.id, currentUserId, isOwner);
setJoinRequests(requests);
setRequestDrivers({});
} finally {
setLoading(false);
}
};
// Use hooks for data fetching
const { data: joinRequests = [], isLoading: loading } = useTeamJoinRequests(
team.id,
team.ownerId,
true
);
void load();
}, [team.id, team.name, team.tag, team.description, team.ownerId]);
// Use hooks for mutations
const updateTeamMutation = useUpdateTeam({
onSuccess: () => {
setEditMode(false);
onUpdate();
},
onError: (error) => {
alert(error instanceof Error ? error.message : 'Failed to update team');
},
});
const handleApprove = async (requestId: string) => {
try {
void requestId;
await teamJoinService.approveJoinRequest();
} catch (error) {
const approveJoinRequestMutation = useApproveJoinRequest({
onSuccess: () => {
onUpdate();
},
onError: (error) => {
alert(error instanceof Error ? error.message : 'Failed to approve request');
}
};
},
});
const handleReject = async (requestId: string) => {
try {
void requestId;
await teamJoinService.rejectJoinRequest();
} catch (error) {
const rejectJoinRequestMutation = useRejectJoinRequest({
onSuccess: () => {
onUpdate();
},
onError: (error) => {
alert(error instanceof Error ? error.message : 'Failed to reject request');
}
},
});
const handleApprove = (requestId: string) => {
// Note: The current API doesn't support approving specific requests
// This would need the requestId to be passed to the service
approveJoinRequestMutation.mutate();
};
const handleSaveChanges = async () => {
try {
const result: UpdateTeamViewModel = await teamService.updateTeam(team.id, {
const handleReject = (requestId: string) => {
// Note: The current API doesn't support rejecting specific requests
// This would need the requestId to be passed to the service
rejectJoinRequestMutation.mutate();
};
const handleSaveChanges = () => {
updateTeamMutation.mutate({
teamId: team.id,
input: {
name: editedTeam.name,
tag: editedTeam.tag,
description: editedTeam.description,
});
if (!result.success) {
throw new Error(result.successMessage);
}
setEditMode(false);
onUpdate();
} catch (error) {
alert(error instanceof Error ? error.message : 'Failed to update team');
}
},
});
};
return (
@@ -134,8 +131,8 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
</div>
<div className="flex gap-2">
<Button variant="primary" onClick={handleSaveChanges}>
Save Changes
<Button variant="primary" onClick={handleSaveChanges} disabled={updateTeamMutation.isPending}>
{updateTeamMutation.isPending ? 'Saving...' : 'Save Changes'}
</Button>
<Button
variant="secondary"
@@ -177,9 +174,9 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
<div className="text-center py-8 text-gray-400">Loading requests...</div>
) : joinRequests.length > 0 ? (
<div className="space-y-3">
{joinRequests.map((request) => {
const driver = requestDrivers[request.driverId] ?? null;
{joinRequests.map((request: TeamJoinRequestViewModel) => {
// Note: Driver hydration is not provided by the API response
// so we only display driverId
return (
<div
key={request.requestId}
@@ -187,30 +184,29 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
>
<div className="flex items-center gap-4 flex-1">
<div className="w-12 h-12 rounded-full bg-primary-blue/20 flex items-center justify-center text-lg font-bold text-white">
{(driver?.name ?? request.driverId).charAt(0)}
{request.driverId.charAt(0)}
</div>
<div className="flex-1">
<h4 className="text-white font-medium">{driver?.name ?? request.driverId}</h4>
<h4 className="text-white font-medium">{request.driverId}</h4>
<p className="text-sm text-gray-400">
{driver?.country ?? 'Unknown'} Requested {new Date(request.requestedAt).toLocaleDateString()}
Requested {new Date(request.requestedAt).toLocaleDateString()}
</p>
{/* Request message is not part of current API contract */}
</div>
</div>
<div className="flex gap-2">
<Button
variant="primary"
onClick={() => handleApprove(request.requestId)}
disabled
disabled={approveJoinRequestMutation.isPending}
>
Approve
{approveJoinRequestMutation.isPending ? 'Approving...' : 'Approve'}
</Button>
<Button
variant="danger"
onClick={() => handleReject(request.requestId)}
disabled
disabled={rejectJoinRequestMutation.isPending}
>
Reject
{rejectJoinRequestMutation.isPending ? 'Rejecting...' : 'Reject'}
</Button>
</div>
</div>
@@ -240,4 +236,4 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
</Card>
</div>
);
}
}