2025-10-14 11:26:53 +09:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import { DriverInfo, DriverManagementConfig } from "../types";
|
|
|
|
|
import { getStatusColor, getStatusLabel, formatTime, COLUMN_LABELS } from "./driverUtils";
|
|
|
|
|
import { Progress } from "@/components/ui/progress";
|
|
|
|
|
|
|
|
|
|
interface DriverListViewProps {
|
|
|
|
|
drivers: DriverInfo[];
|
|
|
|
|
config: DriverManagementConfig;
|
|
|
|
|
isCompact?: boolean; // 작은 크기 (2x2 등)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function DriverListView({ drivers, config, isCompact = false }: DriverListViewProps) {
|
|
|
|
|
const { visibleColumns } = config;
|
|
|
|
|
|
|
|
|
|
// 컴팩트 모드: 요약 정보만 표시
|
|
|
|
|
if (isCompact) {
|
|
|
|
|
const stats = {
|
|
|
|
|
driving: drivers.filter((d) => d.status === "driving").length,
|
|
|
|
|
standby: drivers.filter((d) => d.status === "standby").length,
|
|
|
|
|
resting: drivers.filter((d) => d.status === "resting").length,
|
|
|
|
|
maintenance: drivers.filter((d) => d.status === "maintenance").length,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex h-full flex-col items-center justify-center space-y-3 p-4">
|
|
|
|
|
<div className="text-center">
|
2025-10-29 17:53:03 +09:00
|
|
|
<div className="text-3xl font-bold text-foreground">{drivers.length}</div>
|
|
|
|
|
<div className="text-sm text-foreground">전체 기사</div>
|
2025-10-14 11:26:53 +09:00
|
|
|
</div>
|
|
|
|
|
<div className="grid w-full grid-cols-2 gap-2 text-center text-xs">
|
2025-10-29 17:53:03 +09:00
|
|
|
<div className="rounded-lg bg-success/10 p-2">
|
|
|
|
|
<div className="font-semibold text-success">{stats.driving}</div>
|
|
|
|
|
<div className="text-success">운행중</div>
|
2025-10-14 11:26:53 +09:00
|
|
|
</div>
|
2025-10-29 17:53:03 +09:00
|
|
|
<div className="rounded-lg bg-muted p-2">
|
|
|
|
|
<div className="font-semibold text-foreground">{stats.standby}</div>
|
|
|
|
|
<div className="text-foreground">대기중</div>
|
2025-10-14 11:26:53 +09:00
|
|
|
</div>
|
2025-10-29 17:53:03 +09:00
|
|
|
<div className="rounded-lg bg-warning/10 p-2">
|
|
|
|
|
<div className="font-semibold text-warning">{stats.resting}</div>
|
|
|
|
|
<div className="text-warning">휴식중</div>
|
2025-10-14 11:26:53 +09:00
|
|
|
</div>
|
2025-10-29 17:53:03 +09:00
|
|
|
<div className="rounded-lg bg-destructive/10 p-2">
|
|
|
|
|
<div className="font-semibold text-destructive">{stats.maintenance}</div>
|
|
|
|
|
<div className="text-destructive">점검중</div>
|
2025-10-14 11:26:53 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 빈 데이터 처리
|
|
|
|
|
if (drivers.length === 0) {
|
|
|
|
|
return (
|
2025-10-29 17:53:03 +09:00
|
|
|
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">조회된 기사 정보가 없습니다</div>
|
2025-10-14 11:26:53 +09:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="h-full w-full overflow-auto">
|
|
|
|
|
<table className="min-w-full divide-y divide-gray-200">
|
2025-10-29 17:53:03 +09:00
|
|
|
<thead className="sticky top-0 z-10 bg-muted">
|
2025-10-14 11:26:53 +09:00
|
|
|
<tr>
|
|
|
|
|
{visibleColumns.includes("status") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.status}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("name") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.name}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("vehicleNumber") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.vehicleNumber}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("vehicleType") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.vehicleType}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("departure") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.departure}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("destination") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.destination}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("departureTime") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.departureTime}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("estimatedArrival") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">
|
2025-10-14 11:26:53 +09:00
|
|
|
{COLUMN_LABELS.estimatedArrival}
|
|
|
|
|
</th>
|
|
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("phone") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.phone}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("progress") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<th className="px-3 py-2 text-left text-xs font-semibold text-foreground">{COLUMN_LABELS.progress}</th>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
2025-10-29 17:53:03 +09:00
|
|
|
<tbody className="divide-y divide-gray-200 bg-background">
|
2025-10-14 11:26:53 +09:00
|
|
|
{drivers.map((driver) => {
|
|
|
|
|
const statusColors = getStatusColor(driver.status);
|
|
|
|
|
return (
|
2025-10-29 17:53:03 +09:00
|
|
|
<tr key={driver.id} className="transition-colors hover:bg-muted">
|
2025-10-14 11:26:53 +09:00
|
|
|
{visibleColumns.includes("status") && (
|
|
|
|
|
<td className="px-3 py-2">
|
|
|
|
|
<span
|
|
|
|
|
className={`inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${statusColors.bg} ${statusColors.text}`}
|
|
|
|
|
>
|
|
|
|
|
{getStatusLabel(driver.status)}
|
|
|
|
|
</span>
|
|
|
|
|
</td>
|
|
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("name") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm font-medium text-foreground">{driver.name}</td>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("vehicleNumber") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm text-foreground">{driver.vehicleNumber}</td>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("vehicleType") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm text-foreground">{driver.vehicleType}</td>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("departure") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm text-foreground">
|
|
|
|
|
{driver.departure || <span className="text-muted-foreground">-</span>}
|
2025-10-14 11:26:53 +09:00
|
|
|
</td>
|
|
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("destination") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm text-foreground">
|
|
|
|
|
{driver.destination || <span className="text-muted-foreground">-</span>}
|
2025-10-14 11:26:53 +09:00
|
|
|
</td>
|
|
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("departureTime") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm text-foreground">{formatTime(driver.departureTime)}</td>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("estimatedArrival") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm text-foreground">{formatTime(driver.estimatedArrival)}</td>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("phone") && (
|
2025-10-29 17:53:03 +09:00
|
|
|
<td className="px-3 py-2 text-sm text-foreground">{driver.phone}</td>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
{visibleColumns.includes("progress") && (
|
|
|
|
|
<td className="px-3 py-2">
|
|
|
|
|
{driver.progress !== undefined ? (
|
|
|
|
|
<div className="flex items-center space-x-2">
|
|
|
|
|
<Progress value={driver.progress} className="h-2 w-16" />
|
2025-10-29 17:53:03 +09:00
|
|
|
<span className="text-xs text-foreground">{driver.progress}%</span>
|
2025-10-14 11:26:53 +09:00
|
|
|
</div>
|
|
|
|
|
) : (
|
2025-10-29 17:53:03 +09:00
|
|
|
<span className="text-muted-foreground">-</span>
|
2025-10-14 11:26:53 +09:00
|
|
|
)}
|
|
|
|
|
</td>
|
|
|
|
|
)}
|
|
|
|
|
</tr>
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|