di usage in website
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user