차량관리(기초데이터) 구현
This commit is contained in:
@@ -11,8 +11,18 @@ import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Camera, X } from "lucide-react";
|
||||
import { Camera, X, Car, Wrench, Clock } from "lucide-react";
|
||||
import { ProfileFormData } from "@/types/profile";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
// 운전자 정보 타입
|
||||
export interface DriverInfo {
|
||||
vehicleNumber: string;
|
||||
vehicleType: string | null;
|
||||
licenseNumber: string;
|
||||
phoneNumber: string;
|
||||
vehicleStatus: string | null;
|
||||
}
|
||||
|
||||
// 알림 모달 컴포넌트
|
||||
interface AlertModalProps {
|
||||
@@ -54,6 +64,14 @@ function AlertModal({ isOpen, onClose, title, message, type = "info" }: AlertMod
|
||||
);
|
||||
}
|
||||
|
||||
// 운전자 폼 데이터 타입
|
||||
export interface DriverFormData {
|
||||
vehicleNumber: string;
|
||||
vehicleType: string;
|
||||
licenseNumber: string;
|
||||
phoneNumber: string;
|
||||
}
|
||||
|
||||
interface ProfileModalProps {
|
||||
isOpen: boolean;
|
||||
user: any;
|
||||
@@ -70,6 +88,13 @@ interface ProfileModalProps {
|
||||
message: string;
|
||||
type: "success" | "error" | "info";
|
||||
};
|
||||
// 운전자 관련 props (선택적)
|
||||
isDriver?: boolean;
|
||||
driverInfo?: DriverInfo | null;
|
||||
driverFormData?: DriverFormData;
|
||||
onDriverFormChange?: (field: keyof DriverFormData, value: string) => void;
|
||||
onDriverStatusChange?: (status: "off" | "maintenance") => void;
|
||||
onDriverAccountDelete?: () => void;
|
||||
onClose: () => void;
|
||||
onFormChange: (field: keyof ProfileFormData, value: string) => void;
|
||||
onImageSelect: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
@@ -89,6 +114,12 @@ export function ProfileModal({
|
||||
isSaving,
|
||||
departments,
|
||||
alertModal,
|
||||
isDriver = false,
|
||||
driverInfo,
|
||||
driverFormData,
|
||||
onDriverFormChange,
|
||||
onDriverStatusChange,
|
||||
onDriverAccountDelete,
|
||||
onClose,
|
||||
onFormChange,
|
||||
onImageSelect,
|
||||
@@ -96,6 +127,21 @@ export function ProfileModal({
|
||||
onSave,
|
||||
onAlertClose,
|
||||
}: ProfileModalProps) {
|
||||
// 차량 상태 한글 변환
|
||||
const getStatusLabel = (status: string | null) => {
|
||||
switch (status) {
|
||||
case "off":
|
||||
return "대기";
|
||||
case "active":
|
||||
return "운행중";
|
||||
case "inactive":
|
||||
return "공차";
|
||||
case "maintenance":
|
||||
return "정비";
|
||||
default:
|
||||
return status || "-";
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<ResizableDialog open={isOpen} onOpenChange={onClose}>
|
||||
@@ -234,6 +280,101 @@ export function ProfileModal({
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 운전자 정보 섹션 (공차중계 사용자만) */}
|
||||
{isDriver && driverFormData && onDriverFormChange && (
|
||||
<>
|
||||
<Separator className="my-4" />
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Car className="h-5 w-5 text-primary" />
|
||||
<h3 className="text-sm font-semibold">차량/운전자 정보</h3>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="vehicleNumber">차량번호</Label>
|
||||
<Input
|
||||
id="vehicleNumber"
|
||||
value={driverFormData.vehicleNumber}
|
||||
onChange={(e) => onDriverFormChange("vehicleNumber", e.target.value)}
|
||||
placeholder="12가1234"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="vehicleType">차종</Label>
|
||||
<Input
|
||||
id="vehicleType"
|
||||
value={driverFormData.vehicleType}
|
||||
onChange={(e) => onDriverFormChange("vehicleType", e.target.value)}
|
||||
placeholder="1톤 카고"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="driverPhone">연락처</Label>
|
||||
<Input
|
||||
id="driverPhone"
|
||||
value={driverFormData.phoneNumber}
|
||||
onChange={(e) => onDriverFormChange("phoneNumber", e.target.value)}
|
||||
placeholder="010-1234-5678"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="licenseNumber">면허번호</Label>
|
||||
<Input
|
||||
id="licenseNumber"
|
||||
value={driverFormData.licenseNumber}
|
||||
onChange={(e) => onDriverFormChange("licenseNumber", e.target.value)}
|
||||
placeholder="12-34-567890-12"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 차량 상태 */}
|
||||
{driverInfo && onDriverStatusChange && (
|
||||
<div className="space-y-2">
|
||||
<Label>현재 차량 상태</Label>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-sm font-medium px-3 py-1 rounded-full bg-muted">
|
||||
{getStatusLabel(driverInfo.vehicleStatus)}
|
||||
</span>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onDriverStatusChange("off")}
|
||||
disabled={driverInfo.vehicleStatus === "off"}
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
<Clock className="h-3 w-3" />
|
||||
대기
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onDriverStatusChange("maintenance")}
|
||||
disabled={driverInfo.vehicleStatus === "maintenance"}
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
<Wrench className="h-3 w-3" />
|
||||
정비
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
* 운행/공차 상태는 공차등록 화면에서 변경하세요
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<ResizableDialogFooter>
|
||||
|
||||
Reference in New Issue
Block a user