ProfileModal 의 isDriver 토글 섹션 + 새 차량 등록 모달 + DriverInfo /DriverFormData 타입 + 관련 props 모두 제거. 호출부(AppLayout) 와 useProfile 훅의 driver/vehicle 상태 관리 로직도 함께 정리. 차량/운전자 메뉴 화면(components/vehicle/*) 과 대시보드 위젯 (VehicleListWidget, DriverManagementWidget 등) 은 그대로 유지. 3 files changed, 525 deletions(-). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -414,20 +414,6 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
||||
selectImage,
|
||||
removeImage,
|
||||
saveProfile,
|
||||
isDriver,
|
||||
hasVehicle,
|
||||
driverInfo,
|
||||
driverFormData,
|
||||
updateDriverFormData,
|
||||
handleDriverStatusChange,
|
||||
handleDriverAccountDelete,
|
||||
handleDeleteVehicle,
|
||||
openVehicleRegisterModal,
|
||||
closeVehicleRegisterModal,
|
||||
isVehicleRegisterModalOpen,
|
||||
newVehicleData,
|
||||
updateNewVehicleData,
|
||||
handleRegisterVehicle,
|
||||
} = useProfile(user, refreshUserData, refreshMenus);
|
||||
|
||||
const tabMode = useTabStore((s) => s.mode);
|
||||
@@ -1177,20 +1163,6 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
||||
isSaving={isSaving}
|
||||
departments={departments}
|
||||
alertModal={alertModal}
|
||||
isDriver={isDriver}
|
||||
hasVehicle={hasVehicle}
|
||||
driverInfo={driverInfo}
|
||||
driverFormData={driverFormData}
|
||||
onDriverFormChange={updateDriverFormData}
|
||||
onDriverStatusChange={handleDriverStatusChange}
|
||||
onDriverAccountDelete={handleDriverAccountDelete}
|
||||
onDeleteVehicle={handleDeleteVehicle}
|
||||
onOpenVehicleRegisterModal={openVehicleRegisterModal}
|
||||
isVehicleRegisterModalOpen={isVehicleRegisterModalOpen}
|
||||
newVehicleData={newVehicleData}
|
||||
onCloseVehicleRegisterModal={closeVehicleRegisterModal}
|
||||
onNewVehicleDataChange={updateNewVehicleData}
|
||||
onRegisterVehicle={handleRegisterVehicle}
|
||||
onClose={closeProfileModal}
|
||||
onFormChange={updateFormData}
|
||||
onImageSelect={selectImage}
|
||||
|
||||
@@ -4,18 +4,14 @@ import {
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
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, Car, Wrench, Clock, Plus, Trash2 } from "lucide-react";
|
||||
import { Camera, X } from "lucide-react";
|
||||
import { ProfileFormData } from "@/types/profile";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { VehicleRegisterData } from "@/lib/api/driver";
|
||||
import { apiClient } from "@/lib/api/client";
|
||||
|
||||
// 언어 정보 타입
|
||||
@@ -25,16 +21,6 @@ interface LanguageInfo {
|
||||
langNative: string;
|
||||
}
|
||||
|
||||
// 운전자 정보 타입
|
||||
export interface DriverInfo {
|
||||
vehicleNumber: string;
|
||||
vehicleType: string | null;
|
||||
licenseNumber: string;
|
||||
phoneNumber: string;
|
||||
vehicleStatus: string | null;
|
||||
branchName: string | null;
|
||||
}
|
||||
|
||||
// 알림 모달 컴포넌트
|
||||
interface AlertModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -75,15 +61,6 @@ function AlertModal({ isOpen, onClose, title, message, type = "info" }: AlertMod
|
||||
);
|
||||
}
|
||||
|
||||
// 운전자 폼 데이터 타입
|
||||
export interface DriverFormData {
|
||||
vehicleNumber: string;
|
||||
vehicleType: string;
|
||||
licenseNumber: string;
|
||||
phoneNumber: string;
|
||||
branchName: string;
|
||||
}
|
||||
|
||||
interface ProfileModalProps {
|
||||
isOpen: boolean;
|
||||
user: any;
|
||||
@@ -100,23 +77,6 @@ interface ProfileModalProps {
|
||||
message: string;
|
||||
type: "success" | "error" | "info";
|
||||
};
|
||||
// 운전자 관련 props (선택적)
|
||||
isDriver?: boolean;
|
||||
hasVehicle?: boolean;
|
||||
driverInfo?: DriverInfo | null;
|
||||
driverFormData?: DriverFormData;
|
||||
onDriverFormChange?: (field: keyof DriverFormData, value: string) => void;
|
||||
onDriverStatusChange?: (status: "off" | "maintenance") => void;
|
||||
onDriverAccountDelete?: () => void;
|
||||
// 차량 삭제/등록 관련 props
|
||||
onDeleteVehicle?: () => void;
|
||||
onOpenVehicleRegisterModal?: () => void;
|
||||
// 새 차량 등록 모달 관련 props
|
||||
isVehicleRegisterModalOpen?: boolean;
|
||||
newVehicleData?: VehicleRegisterData;
|
||||
onCloseVehicleRegisterModal?: () => void;
|
||||
onNewVehicleDataChange?: (field: keyof VehicleRegisterData, value: string) => void;
|
||||
onRegisterVehicle?: () => void;
|
||||
onClose: () => void;
|
||||
onFormChange: (field: keyof ProfileFormData, value: string) => void;
|
||||
onImageSelect: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
@@ -136,20 +96,6 @@ export function ProfileModal({
|
||||
isSaving,
|
||||
departments,
|
||||
alertModal,
|
||||
isDriver = false,
|
||||
hasVehicle = false,
|
||||
driverInfo,
|
||||
driverFormData,
|
||||
onDriverFormChange,
|
||||
onDriverStatusChange,
|
||||
onDriverAccountDelete,
|
||||
onDeleteVehicle,
|
||||
onOpenVehicleRegisterModal,
|
||||
isVehicleRegisterModalOpen = false,
|
||||
newVehicleData,
|
||||
onCloseVehicleRegisterModal,
|
||||
onNewVehicleDataChange,
|
||||
onRegisterVehicle,
|
||||
onClose,
|
||||
onFormChange,
|
||||
onImageSelect,
|
||||
@@ -197,21 +143,6 @@ export function ProfileModal({
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
// 차량 상태 한글 변환
|
||||
const getStatusLabel = (status: string | null) => {
|
||||
switch (status) {
|
||||
case "off":
|
||||
return "대기";
|
||||
case "active":
|
||||
return "운행중";
|
||||
case "inactive":
|
||||
return "공차";
|
||||
case "maintenance":
|
||||
return "정비";
|
||||
default:
|
||||
return status || "-";
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Dialog open={isOpen} onOpenChange={onClose}>
|
||||
@@ -356,151 +287,6 @@ export function ProfileModal({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 운전자 정보 섹션 (공차중계 사용자만) */}
|
||||
{isDriver && (
|
||||
<>
|
||||
<Separator className="my-4" />
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Car className="h-5 w-5 text-primary" />
|
||||
<h3 className="text-sm font-semibold">차량/운전자 정보</h3>
|
||||
</div>
|
||||
{/* 차량 유무에 따른 버튼 표시 */}
|
||||
{hasVehicle ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
onClick={onDeleteVehicle}
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
차량 삭제
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
type="button"
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={onOpenVehicleRegisterModal}
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
<Plus className="h-3 w-3" />
|
||||
새 차량 등록
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 운전자 정보 (항상 수정 가능) */}
|
||||
{driverFormData && onDriverFormChange && (
|
||||
<>
|
||||
{/* 차량 정보 - 차량이 있을 때만 수정 가능 */}
|
||||
{hasVehicle ? (
|
||||
<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="text-center py-4 text-muted-foreground border rounded-md bg-muted/30">
|
||||
<Car className="h-8 w-8 mx-auto mb-2 opacity-30" />
|
||||
<p className="text-sm">등록된 차량이 없습니다.</p>
|
||||
<p className="text-xs mt-1">새 차량 등록 버튼을 눌러 차량을 등록하세요.</p>
|
||||
</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>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="branchName">소속 지점</Label>
|
||||
<Input
|
||||
id="branchName"
|
||||
value={driverFormData.branchName}
|
||||
onChange={(e) => onDriverFormChange("branchName", e.target.value)}
|
||||
placeholder="서울 본점"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 차량 상태 - 차량이 있을 때만 표시 */}
|
||||
{hasVehicle && 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>
|
||||
|
||||
<DialogFooter>
|
||||
@@ -523,49 +309,6 @@ export function ProfileModal({
|
||||
type={alertModal.type}
|
||||
/>
|
||||
|
||||
{/* 새 차량 등록 모달 */}
|
||||
{isVehicleRegisterModalOpen && newVehicleData && onNewVehicleDataChange && onRegisterVehicle && onCloseVehicleRegisterModal && (
|
||||
<Dialog open={isVehicleRegisterModalOpen} onOpenChange={onCloseVehicleRegisterModal}>
|
||||
<DialogContent className="sm:max-w-[400px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>새 차량 등록</DialogTitle>
|
||||
<DialogDescription>
|
||||
새로운 차량 정보를 입력해주세요.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="grid gap-4 py-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="newVehicleNumber">차량번호 *</Label>
|
||||
<Input
|
||||
id="newVehicleNumber"
|
||||
value={newVehicleData.vehicleNumber}
|
||||
onChange={(e) => onNewVehicleDataChange("vehicleNumber", e.target.value)}
|
||||
placeholder="12가1234"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="newVehicleType">차종</Label>
|
||||
<Input
|
||||
id="newVehicleType"
|
||||
value={newVehicleData.vehicleType || ""}
|
||||
onChange={(e) => onNewVehicleDataChange("vehicleType", e.target.value)}
|
||||
placeholder="1톤 카고"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="outline" onClick={onCloseVehicleRegisterModal}>
|
||||
취소
|
||||
</Button>
|
||||
<Button type="button" onClick={onRegisterVehicle}>
|
||||
등록
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useCallback, useEffect } from "react";
|
||||
import { useState, useCallback } from "react";
|
||||
import { ProfileFormData, ProfileModalState } from "@/types/profile";
|
||||
import { LAYOUT_CONFIG, MESSAGES } from "@/constants/layout";
|
||||
import { apiCall } from "@/lib/api/client";
|
||||
import {
|
||||
getDriverProfile,
|
||||
updateDriverProfile,
|
||||
updateDriverStatus,
|
||||
deleteDriverAccount,
|
||||
deleteDriverVehicle,
|
||||
registerDriverVehicle,
|
||||
DriverProfile,
|
||||
VehicleRegisterData,
|
||||
} from "@/lib/api/driver";
|
||||
import { DriverInfo, DriverFormData } from "@/components/layout/ProfileModal";
|
||||
|
||||
// 알림 모달 상태 타입
|
||||
interface AlertModalState {
|
||||
@@ -59,26 +48,6 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
}>
|
||||
>([]);
|
||||
|
||||
// 운전자 정보 상태
|
||||
const [isDriver, setIsDriver] = useState(false);
|
||||
const [hasVehicle, setHasVehicle] = useState(false); // 차량 보유 여부
|
||||
const [driverInfo, setDriverInfo] = useState<DriverInfo | null>(null);
|
||||
const [driverFormData, setDriverFormData] = useState<DriverFormData>({
|
||||
vehicleNumber: "",
|
||||
vehicleType: "",
|
||||
licenseNumber: "",
|
||||
phoneNumber: "",
|
||||
branchName: "",
|
||||
});
|
||||
|
||||
// 새 차량 등록 모달 상태
|
||||
const [isVehicleRegisterModalOpen, setIsVehicleRegisterModalOpen] = useState(false);
|
||||
const [newVehicleData, setNewVehicleData] = useState<VehicleRegisterData>({
|
||||
vehicleNumber: "",
|
||||
vehicleType: "",
|
||||
branchName: "",
|
||||
});
|
||||
|
||||
// 알림 모달 표시 함수
|
||||
const showAlert = useCallback((title: string, message: string, type: "success" | "error" | "info" = "info") => {
|
||||
setAlertModal({
|
||||
@@ -106,41 +75,6 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 운전자 정보 로드 함수
|
||||
const loadDriverInfo = useCallback(async () => {
|
||||
try {
|
||||
const response = await getDriverProfile();
|
||||
if (response.success && response.data) {
|
||||
setIsDriver(true);
|
||||
// 차량 보유 여부 확인
|
||||
const vehicleExists = !!response.data.vehicleNumber;
|
||||
setHasVehicle(vehicleExists);
|
||||
setDriverInfo({
|
||||
vehicleNumber: response.data.vehicleNumber,
|
||||
vehicleType: response.data.vehicleType,
|
||||
licenseNumber: response.data.licenseNumber,
|
||||
phoneNumber: response.data.phoneNumber,
|
||||
vehicleStatus: response.data.vehicleStatus,
|
||||
branchName: response.data.branchName,
|
||||
});
|
||||
setDriverFormData({
|
||||
vehicleNumber: response.data.vehicleNumber || "",
|
||||
vehicleType: response.data.vehicleType || "",
|
||||
licenseNumber: response.data.licenseNumber || "",
|
||||
phoneNumber: response.data.phoneNumber || "",
|
||||
branchName: response.data.branchName || "",
|
||||
});
|
||||
} else {
|
||||
setIsDriver(false);
|
||||
setHasVehicle(false);
|
||||
setDriverInfo(null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("운전자 정보 로드 실패:", error);
|
||||
setIsDriver(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 프로필 모달 열기
|
||||
*/
|
||||
@@ -148,8 +82,6 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
if (user) {
|
||||
// 부서 목록 로드
|
||||
loadDepartments();
|
||||
// 운전자 정보 로드
|
||||
loadDriverInfo();
|
||||
|
||||
setModalState((prev) => ({
|
||||
...prev,
|
||||
@@ -166,7 +98,7 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
isSaving: false,
|
||||
}));
|
||||
}
|
||||
}, [user, loadDepartments, loadDriverInfo]);
|
||||
}, [user, loadDepartments]);
|
||||
|
||||
/**
|
||||
* 프로필 모달 닫기
|
||||
@@ -193,138 +125,6 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
}));
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 운전자 폼 데이터 변경
|
||||
*/
|
||||
const updateDriverFormData = useCallback((field: keyof DriverFormData, value: string) => {
|
||||
setDriverFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 차량 상태 변경 (대기/정비)
|
||||
*/
|
||||
const handleDriverStatusChange = useCallback(
|
||||
async (status: "off" | "maintenance") => {
|
||||
try {
|
||||
const response = await updateDriverStatus(status);
|
||||
if (response.success) {
|
||||
showAlert("상태 변경", response.message || "차량 상태가 변경되었습니다.", "success");
|
||||
// 운전자 정보 새로고침
|
||||
await loadDriverInfo();
|
||||
} else {
|
||||
showAlert("상태 변경 실패", response.message || "상태 변경에 실패했습니다.", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("차량 상태 변경 실패:", error);
|
||||
showAlert("오류", "상태 변경 중 오류가 발생했습니다.", "error");
|
||||
}
|
||||
},
|
||||
[showAlert, loadDriverInfo]
|
||||
);
|
||||
|
||||
/**
|
||||
* 회원 탈퇴
|
||||
*/
|
||||
const handleDriverAccountDelete = useCallback(async () => {
|
||||
if (!confirm("정말로 탈퇴하시겠습니까?\n차량 정보가 함께 삭제되며, 이 작업은 되돌릴 수 없습니다.")) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await deleteDriverAccount();
|
||||
if (response.success) {
|
||||
showAlert("탈퇴 완료", "회원 탈퇴가 완료되었습니다.", "success");
|
||||
// 로그아웃 처리
|
||||
window.location.href = "/login";
|
||||
} else {
|
||||
showAlert("탈퇴 실패", response.message || "회원 탈퇴에 실패했습니다.", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("회원 탈퇴 실패:", error);
|
||||
showAlert("오류", "회원 탈퇴 중 오류가 발생했습니다.", "error");
|
||||
}
|
||||
}, [showAlert]);
|
||||
|
||||
/**
|
||||
* 차량 삭제
|
||||
*/
|
||||
const handleDeleteVehicle = useCallback(async () => {
|
||||
if (!confirm("이 차량을 더 이상 사용하지 않습니까?\n차량 정보가 삭제됩니다.")) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await deleteDriverVehicle();
|
||||
if (response.success) {
|
||||
showAlert("삭제 완료", "차량이 삭제되었습니다.", "success");
|
||||
// 운전자 정보 새로고침
|
||||
await loadDriverInfo();
|
||||
} else {
|
||||
showAlert("삭제 실패", response.message || "차량 삭제에 실패했습니다.", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("차량 삭제 실패:", error);
|
||||
showAlert("오류", "차량 삭제 중 오류가 발생했습니다.", "error");
|
||||
}
|
||||
}, [showAlert, loadDriverInfo]);
|
||||
|
||||
/**
|
||||
* 새 차량 등록 모달 열기
|
||||
*/
|
||||
const openVehicleRegisterModal = useCallback(() => {
|
||||
setNewVehicleData({
|
||||
vehicleNumber: "",
|
||||
vehicleType: "",
|
||||
branchName: driverFormData.branchName || "", // 기존 소속 지점 유지
|
||||
});
|
||||
setIsVehicleRegisterModalOpen(true);
|
||||
}, [driverFormData.branchName]);
|
||||
|
||||
/**
|
||||
* 새 차량 등록 모달 닫기
|
||||
*/
|
||||
const closeVehicleRegisterModal = useCallback(() => {
|
||||
setIsVehicleRegisterModalOpen(false);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 새 차량 데이터 변경
|
||||
*/
|
||||
const updateNewVehicleData = useCallback((field: keyof VehicleRegisterData, value: string) => {
|
||||
setNewVehicleData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 새 차량 등록 처리
|
||||
*/
|
||||
const handleRegisterVehicle = useCallback(async () => {
|
||||
if (!newVehicleData.vehicleNumber) {
|
||||
showAlert("입력 오류", "차량번호는 필수입니다.", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await registerDriverVehicle(newVehicleData);
|
||||
if (response.success) {
|
||||
showAlert("등록 완료", "차량이 등록되었습니다.", "success");
|
||||
setIsVehicleRegisterModalOpen(false);
|
||||
// 운전자 정보 새로고침
|
||||
await loadDriverInfo();
|
||||
} else {
|
||||
showAlert("등록 실패", response.message || "차량 등록에 실패했습니다.", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("차량 등록 실패:", error);
|
||||
showAlert("오류", "차량 등록 중 오류가 발생했습니다.", "error");
|
||||
}
|
||||
}, [newVehicleData, showAlert, loadDriverInfo]);
|
||||
|
||||
/**
|
||||
* 이미지 선택 처리
|
||||
*/
|
||||
@@ -429,22 +229,6 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
// API 호출 (JWT 토큰 자동 포함)
|
||||
const response = await apiCall("PUT", "/admin/profile", updateData);
|
||||
|
||||
// 운전자 정보도 저장 (운전자인 경우)
|
||||
if (isDriver) {
|
||||
const driverResponse = await updateDriverProfile({
|
||||
userName: modalState.form_data.user_name,
|
||||
phoneNumber: driverFormData.phoneNumber,
|
||||
licenseNumber: driverFormData.licenseNumber,
|
||||
vehicleNumber: driverFormData.vehicleNumber,
|
||||
vehicleType: driverFormData.vehicleType,
|
||||
branchName: driverFormData.branchName,
|
||||
});
|
||||
|
||||
if (!driverResponse.success) {
|
||||
console.warn("운전자 정보 저장 실패:", driverResponse.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (response.success || (response as any).result) {
|
||||
// locale이 변경된 경우 전역 변수와 localStorage 업데이트
|
||||
const localeChanged = modalState.form_data.locale && modalState.form_data.locale !== user.locale;
|
||||
@@ -481,7 +265,7 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
} finally {
|
||||
setModalState((prev) => ({ ...prev, isSaving: false }));
|
||||
}
|
||||
}, [user, modalState.selected_file, modalState.selected_image, modalState.form_data, refreshUserData, showAlert, isDriver, driverFormData]);
|
||||
}, [user, modalState.selected_file, modalState.selected_image, modalState.form_data, refreshUserData, showAlert]);
|
||||
|
||||
return {
|
||||
// 상태
|
||||
@@ -495,16 +279,6 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
alertModal,
|
||||
closeAlert,
|
||||
|
||||
// 운전자 관련 상태
|
||||
isDriver,
|
||||
hasVehicle,
|
||||
driverInfo,
|
||||
driverFormData,
|
||||
|
||||
// 새 차량 등록 모달 상태
|
||||
isVehicleRegisterModalOpen,
|
||||
newVehicleData,
|
||||
|
||||
// 액션
|
||||
openProfileModal,
|
||||
closeProfileModal,
|
||||
@@ -512,15 +286,5 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>, refr
|
||||
selectImage,
|
||||
removeImage,
|
||||
saveProfile,
|
||||
|
||||
// 운전자 관련 액션
|
||||
updateDriverFormData,
|
||||
handleDriverStatusChange,
|
||||
handleDriverAccountDelete,
|
||||
handleDeleteVehicle,
|
||||
openVehicleRegisterModal,
|
||||
closeVehicleRegisterModal,
|
||||
updateNewVehicleData,
|
||||
handleRegisterVehicle,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user