ERP-node/frontend/components/admin/dashboard/widgets/driverUtils.ts

267 lines
6.3 KiB
TypeScript

import { DriverInfo, DriverManagementConfig } from "../types";
/**
* 운행 상태별 색상 반환
*/
export function getStatusColor(status: DriverInfo["status"]) {
switch (status) {
case "driving":
return {
bg: "bg-success/10",
text: "text-success",
border: "border-success",
badge: "bg-success",
};
case "standby":
return {
bg: "bg-muted",
text: "text-foreground",
border: "border-border",
badge: "bg-muted0",
};
case "resting":
return {
bg: "bg-warning/10",
text: "text-warning",
border: "border-warning",
badge: "bg-warning",
};
case "maintenance":
return {
bg: "bg-destructive/10",
text: "text-destructive",
border: "border-destructive",
badge: "bg-destructive",
};
default:
return {
bg: "bg-muted",
text: "text-foreground",
border: "border-border",
badge: "bg-muted0",
};
}
}
/**
* 운행 상태 한글 변환
*/
export function getStatusLabel(status: DriverInfo["status"]) {
switch (status) {
case "driving":
return "운행중";
case "standby":
return "대기중";
case "resting":
return "휴식중";
case "maintenance":
return "점검중";
default:
return "알 수 없음";
}
}
/**
* 시간 포맷팅 (HH:MM)
*/
export function formatTime(dateString?: string): string {
if (!dateString) return "-";
const date = new Date(dateString);
return date.toLocaleTimeString("ko-KR", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
});
}
/**
* 날짜 시간 포맷팅 (MM/DD HH:MM)
*/
export function formatDateTime(dateString?: string): string {
if (!dateString) return "-";
const date = new Date(dateString);
return date.toLocaleString("ko-KR", {
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
hour12: false,
});
}
/**
* 운행 진행률 계산 (실제로는 GPS 데이터 기반)
*/
export function calculateProgress(driver: DriverInfo): number {
if (!driver.departureTime || !driver.estimatedArrival) return 0;
const now = new Date();
const departure = new Date(driver.departureTime);
const arrival = new Date(driver.estimatedArrival);
const totalTime = arrival.getTime() - departure.getTime();
const elapsedTime = now.getTime() - departure.getTime();
const progress = Math.min(100, Math.max(0, (elapsedTime / totalTime) * 100));
return Math.round(progress);
}
/**
* 기사 필터링
*/
export function filterDrivers(
drivers: DriverInfo[],
statusFilter: DriverManagementConfig["statusFilter"],
searchTerm: string,
): DriverInfo[] {
let filtered = drivers;
// 상태 필터
if (statusFilter !== "all") {
filtered = filtered.filter((driver) => driver.status === statusFilter);
}
// 검색어 필터
if (searchTerm.trim()) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(
(driver) =>
driver.name.toLowerCase().includes(term) ||
driver.vehicleNumber.toLowerCase().includes(term) ||
driver.phone.includes(term),
);
}
return filtered;
}
/**
* 기사 정렬
*/
export function sortDrivers(
drivers: DriverInfo[],
sortBy: DriverManagementConfig["sortBy"],
sortOrder: DriverManagementConfig["sortOrder"],
): DriverInfo[] {
const sorted = [...drivers];
sorted.sort((a, b) => {
let compareResult = 0;
switch (sortBy) {
case "name":
compareResult = a.name.localeCompare(b.name, "ko-KR");
break;
case "vehicleNumber":
compareResult = a.vehicleNumber.localeCompare(b.vehicleNumber);
break;
case "status":
const statusOrder = { driving: 0, resting: 1, standby: 2, maintenance: 3 };
compareResult = statusOrder[a.status] - statusOrder[b.status];
break;
case "departureTime":
const timeA = a.departureTime ? new Date(a.departureTime).getTime() : 0;
const timeB = b.departureTime ? new Date(b.departureTime).getTime() : 0;
compareResult = timeA - timeB;
break;
}
return sortOrder === "asc" ? compareResult : -compareResult;
});
return sorted;
}
/**
* 테마별 색상 반환
*/
export function getThemeColors(theme: string, customColor?: string) {
if (theme === "custom" && customColor) {
const lighterColor = adjustColor(customColor, 40);
const darkerColor = adjustColor(customColor, -40);
return {
background: lighterColor,
text: darkerColor,
border: customColor,
hover: customColor,
};
}
if (theme === "dark") {
return {
background: "#1f2937",
text: "#f3f4f6",
border: "#374151",
hover: "#374151",
};
}
// light theme (default)
const getCSSVariable = (varName: string): string => {
if (typeof window !== "undefined") {
const value = getComputedStyle(document.documentElement)
.getPropertyValue(varName)
.trim();
return value ? `hsl(${value})` : "#ffffff";
}
return "#ffffff";
};
return {
background: getCSSVariable("--background"),
text: getCSSVariable("--foreground"),
border: getCSSVariable("--border"),
hover: getCSSVariable("--muted"),
};
}
/**
* 색상 밝기 조정
*/
function adjustColor(color: string, amount: number): string {
const clamp = (num: number) => Math.min(255, Math.max(0, num));
const hex = color.replace("#", "");
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
const newR = clamp(r + amount);
const newG = clamp(g + amount);
const newB = clamp(b + amount);
return `#${newR.toString(16).padStart(2, "0")}${newG.toString(16).padStart(2, "0")}${newB.toString(16).padStart(2, "0")}`;
}
/**
* 기본 표시 컬럼 목록
*/
export const DEFAULT_VISIBLE_COLUMNS = [
"status",
"name",
"vehicleNumber",
"vehicleType",
"departure",
"destination",
"departureTime",
"estimatedArrival",
"phone",
];
/**
* 컬럼 라벨 매핑
*/
export const COLUMN_LABELS: Record<string, string> = {
status: "상태",
name: "기사명",
vehicleNumber: "차량번호",
vehicleType: "차량유형",
departure: "출발지",
destination: "목적지",
departureTime: "출발시간",
estimatedArrival: "도착예정",
phone: "연락처",
progress: "진행률",
};