website cleanup
This commit is contained in:
@@ -5,21 +5,19 @@ 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 { DriverDTO } from '@core/racing/application/dto/DriverDTO';
|
||||
import type { DriverDTO } from '@/lib/types/generated/DriverDTO';
|
||||
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: {
|
||||
id: string;
|
||||
name: string;
|
||||
tag: string;
|
||||
description: string;
|
||||
ownerId: string;
|
||||
};
|
||||
team: Pick<TeamDetailsViewModel, 'id' | 'name' | 'tag' | 'description' | 'ownerId'>;
|
||||
onUpdate: () => void;
|
||||
}
|
||||
|
||||
export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
|
||||
const [joinRequests, setJoinRequests] = useState<TeamAdminJoinRequestViewModel[]>([]);
|
||||
const { teamJoinService, teamService } = useServices();
|
||||
const [joinRequests, setJoinRequests] = useState<TeamJoinRequestViewModel[]>([]);
|
||||
const [requestDrivers, setRequestDrivers] = useState<Record<string, DriverDTO>>({});
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
@@ -33,22 +31,13 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
|
||||
const load = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const viewModel = await loadTeamAdminViewModel({
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
tag: team.tag,
|
||||
description: team.description,
|
||||
ownerId: team.ownerId,
|
||||
});
|
||||
setJoinRequests(viewModel.requests);
|
||||
|
||||
const driversById: Record<string, DriverDTO> = {};
|
||||
for (const request of viewModel.requests) {
|
||||
if (request.driver) {
|
||||
driversById[request.driverId] = request.driver;
|
||||
}
|
||||
}
|
||||
setRequestDrivers(driversById);
|
||||
// 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);
|
||||
}
|
||||
@@ -59,16 +48,8 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
|
||||
|
||||
const handleApprove = async (requestId: string) => {
|
||||
try {
|
||||
const updated = await approveTeamJoinRequestAndReload(requestId, team.id);
|
||||
setJoinRequests(updated);
|
||||
const driversById: Record<string, DriverDTO> = {};
|
||||
for (const request of updated) {
|
||||
if (request.driver) {
|
||||
driversById[request.driverId] = request.driver;
|
||||
}
|
||||
}
|
||||
setRequestDrivers(driversById);
|
||||
onUpdate();
|
||||
void requestId;
|
||||
await teamJoinService.approveJoinRequest();
|
||||
} catch (error) {
|
||||
alert(error instanceof Error ? error.message : 'Failed to approve request');
|
||||
}
|
||||
@@ -76,15 +57,8 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
|
||||
|
||||
const handleReject = async (requestId: string) => {
|
||||
try {
|
||||
const updated = await rejectTeamJoinRequestAndReload(requestId, team.id);
|
||||
setJoinRequests(updated);
|
||||
const driversById: Record<string, DriverDTO> = {};
|
||||
for (const request of updated) {
|
||||
if (request.driver) {
|
||||
driversById[request.driverId] = request.driver;
|
||||
}
|
||||
}
|
||||
setRequestDrivers(driversById);
|
||||
void requestId;
|
||||
await teamJoinService.rejectJoinRequest();
|
||||
} catch (error) {
|
||||
alert(error instanceof Error ? error.message : 'Failed to reject request');
|
||||
}
|
||||
@@ -92,13 +66,16 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
|
||||
|
||||
const handleSaveChanges = async () => {
|
||||
try {
|
||||
await updateTeamDetails({
|
||||
teamId: team.id,
|
||||
const result: UpdateTeamViewModel = await teamService.updateTeam(team.id, {
|
||||
name: editedTeam.name,
|
||||
tag: editedTeam.tag,
|
||||
description: editedTeam.description,
|
||||
updatedByDriverId: team.ownerId,
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
throw new Error(result.successMessage);
|
||||
}
|
||||
|
||||
setEditMode(false);
|
||||
onUpdate();
|
||||
} catch (error) {
|
||||
@@ -201,40 +178,37 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
|
||||
) : joinRequests.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
{joinRequests.map((request) => {
|
||||
const driver = requestDrivers[request.driverId] ?? request.driver;
|
||||
if (!driver) return null;
|
||||
const driver = requestDrivers[request.driverId] ?? null;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={request.id}
|
||||
key={request.requestId}
|
||||
className="flex items-center justify-between p-4 rounded-lg bg-deep-graphite border border-charcoal-outline"
|
||||
>
|
||||
<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.charAt(0)}
|
||||
{(driver?.name ?? request.driverId).charAt(0)}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h4 className="text-white font-medium">{driver.name}</h4>
|
||||
<h4 className="text-white font-medium">{driver?.name ?? request.driverId}</h4>
|
||||
<p className="text-sm text-gray-400">
|
||||
{driver.country} • Requested {new Date(request.requestedAt).toLocaleDateString()}
|
||||
{driver?.country ?? 'Unknown'} • Requested {new Date(request.requestedAt).toLocaleDateString()}
|
||||
</p>
|
||||
{request.message && (
|
||||
<p className="text-sm text-gray-300 mt-1 italic">
|
||||
"{request.message}"
|
||||
</p>
|
||||
)}
|
||||
{/* Request message is not part of current API contract */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => handleApprove(request.id)}
|
||||
onClick={() => handleApprove(request.requestId)}
|
||||
disabled
|
||||
>
|
||||
Approve
|
||||
</Button>
|
||||
<Button
|
||||
variant="danger"
|
||||
onClick={() => handleReject(request.id)}
|
||||
onClick={() => handleReject(request.requestId)}
|
||||
disabled
|
||||
>
|
||||
Reject
|
||||
</Button>
|
||||
@@ -266,4 +240,4 @@ export default function TeamAdmin({ team, onUpdate }: TeamAdminProps) {
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user