feat: add ScheduleCrewPage and integrate crew assignment functionality

- Introduced ScheduleCrewPage for assigning train crew to schedules.
- Updated routing in App.tsx to include crew assignment path.
- Enhanced TrainScheduleV2ListPage with a button to navigate to crew assignment.
- Added new chart components and styles for improved wagon performance reporting.
- Refactored existing styles and components for better visual feedback and usability.
This commit is contained in:
marshalyordanos
2026-09-05 08:36:36 +03:00
parent 8437a6d5f1
commit 63ccb060c6
6 changed files with 861 additions and 239 deletions

View File

@@ -0,0 +1,23 @@
import { useParams } from "react-router-dom";
import { PageContainer, PageHeader } from "@/components/page";
/**
* Train crew assignment for one schedule.
*
* Intentionally blank: the assignment rules — crew counts per role, the driver
* pairing cases, and which corridor segment each driver covers — are still to
* be specified, so only the route and header exist so far.
*/
export default function ScheduleCrewPage() {
const { scheduleId = "" } = useParams();
return (
<PageContainer>
<PageHeader
title="Assign Train Crew"
backTo={`/dashboard/operations/train-scheduling-v2/${scheduleId}`}
/>
</PageContainer>
);
}

View File

@@ -37,6 +37,7 @@ import {
Send,
Table2,
Train,
Users,
Weight,
} from "lucide-react";
import { useEffect, useMemo, useState } from "react";
@@ -372,12 +373,26 @@ export default function TrainScheduleV2ListPage() {
},
{
id: "actions",
size: 32,
size: 210,
meta: { headerClassName, cellClassName: `${cellClassName} whitespace-nowrap` },
cell: ({ row }) => {
const schedule = row.original;
return (
<Group justify="flex-end" onClick={(e) => e.stopPropagation()}>
<Group gap="xs" justify="flex-end" wrap="nowrap" onClick={(e) => e.stopPropagation()}>
<Button
variant="light"
color="indigo"
size="xs"
radius="md"
leftSection={<Users size={14} />}
onClick={() =>
navigate(
`/dashboard/operations/train-scheduling-v2/${schedule.id}/crew`,
)
}
>
Assign Train Crew
</Button>
<Menu position="bottom-end" withinPortal shadow="md" width={190}>
<Menu.Target>
<ActionIcon variant="subtle" color="gray" aria-label="Row actions">
@@ -639,6 +654,9 @@ export default function TrainScheduleV2ListPage() {
onTrack={() =>
navigate(`/dashboard/operations/train-scheduling-v2/${schedule.id}/track`)
}
onAssignCrew={() =>
navigate(`/dashboard/operations/train-scheduling-v2/${schedule.id}/crew`)
}
/>
))}
</SimpleGrid>
@@ -1053,10 +1071,12 @@ function ScheduleCard({
schedule,
onOpen,
onTrack,
onAssignCrew,
}: {
schedule: TrainScheduleListItem;
onOpen: () => void;
onTrack: () => void;
onAssignCrew: () => void;
}) {
const { day, time } = splitDate(schedule.scheduleDate);
const canTrack = ["DISPATCHED", "ARRIVED"].includes(schedule.status);
@@ -1153,6 +1173,19 @@ function ScheduleCard({
Track
</Button>
) : null}
<Button
variant="light"
color="indigo"
size="sm"
radius="md"
leftSection={<Users size={15} />}
onClick={(e) => {
e.stopPropagation();
onAssignCrew();
}}
>
Assign Train Crew
</Button>
</Group>
</Stack>
</Card>