- Integrated multi-language functionality across various user management components, including user list, roles list, and user authorization pages, enhancing accessibility for diverse users. - Updated UI elements to utilize translation keys, ensuring that all text is dynamically translated based on user preferences. - Improved error handling messages to be localized, providing a better user experience in case of issues. These changes significantly enhance the usability and internationalization of the user management features, making the application more inclusive.
168 lines
5.9 KiB
TypeScript
168 lines
5.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { CompanyDeleteState } from "@/types/company";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
} from "@/components/ui/dialog";
|
|
import { LoadingSpinner } from "@/components/common/LoadingSpinner";
|
|
import { AlertTriangle } from "lucide-react";
|
|
|
|
interface CompanyDeleteDialogProps {
|
|
deleteState: CompanyDeleteState;
|
|
isLoading: boolean;
|
|
error: string | null;
|
|
onClose: () => void;
|
|
onConfirm: () => Promise<boolean>;
|
|
onClearError: () => void;
|
|
t?: (key: string, params?: Record<string, string | number>) => string;
|
|
}
|
|
|
|
/**
|
|
* 회사 삭제 확인 다이얼로그 컴포넌트
|
|
*/
|
|
export function CompanyDeleteDialog({
|
|
deleteState,
|
|
isLoading,
|
|
error,
|
|
onClose,
|
|
onConfirm,
|
|
onClearError,
|
|
t,
|
|
}: CompanyDeleteDialogProps) {
|
|
const _t = t || ((key: string) => {
|
|
const defaults: Record<string, string> = {
|
|
"company.delete.title": "회사 삭제 확인",
|
|
"company.delete.description": "선택한 회사를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
|
|
"company.delete.companyName": "회사명",
|
|
"company.delete.companyCode": "회사 코드",
|
|
"company.delete.writer": "등록자",
|
|
"company.delete.regdate": "등록일",
|
|
"company.delete.cancel": "취소",
|
|
"company.delete.confirm": "삭제",
|
|
};
|
|
return defaults[key] || key;
|
|
});
|
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
|
|
// 다이얼로그가 열려있지 않으면 렌더링하지 않음
|
|
if (!deleteState.isOpen || !deleteState.targetCompany) return null;
|
|
|
|
const { targetCompany } = deleteState;
|
|
|
|
// 삭제 확인 처리
|
|
const handleConfirm = async () => {
|
|
setIsDeleting(true);
|
|
onClearError();
|
|
|
|
try {
|
|
const success = await onConfirm();
|
|
if (success) {
|
|
// 성공 시 다이얼로그 닫기
|
|
onClose();
|
|
}
|
|
} catch (err) {
|
|
// 에러는 부모 컴포넌트에서 처리
|
|
} finally {
|
|
setIsDeleting(false);
|
|
}
|
|
};
|
|
|
|
// 취소 처리
|
|
const handleCancel = () => {
|
|
onClearError();
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<Dialog open={deleteState.isOpen} onOpenChange={handleCancel}>
|
|
<DialogContent className="sm:max-w-[425px]">
|
|
<DialogHeader>
|
|
<DialogTitle className="text-destructive flex items-center gap-2">
|
|
<AlertTriangle className="h-5 w-5" />
|
|
{_t("company.delete.title")}
|
|
</DialogTitle>
|
|
<DialogDescription className="text-left">
|
|
{_t("company.delete.description")}
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4 py-4">
|
|
{/* 삭제할 회사 정보 표시 */}
|
|
<div className="border-destructive/20 bg-destructive/5 rounded-md border p-4">
|
|
<div className="space-y-2">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-muted-foreground text-sm font-medium">{_t("company.delete.companyName")}</span>
|
|
<span className="font-medium">{targetCompany.company_name}</span>
|
|
</div>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-muted-foreground text-sm font-medium">{_t("company.delete.companyCode")}</span>
|
|
<span className="font-mono text-sm">{targetCompany.company_code}</span>
|
|
</div>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-muted-foreground text-sm font-medium">{_t("company.delete.writer")}</span>
|
|
<span className="text-sm">{targetCompany.writer}</span>
|
|
</div>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-muted-foreground text-sm font-medium">{_t("company.delete.regdate")}</span>
|
|
<span className="text-sm">
|
|
{new Date(targetCompany.regdate).toLocaleDateString("ko-KR", {
|
|
year: "numeric",
|
|
month: "2-digit",
|
|
day: "2-digit",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
})}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 경고 메시지 */}
|
|
{/* <div className="rounded-md bg-amber-50 p-3 dark:bg-amber-900/20">
|
|
<div className="flex items-start gap-2">
|
|
<AlertTriangle className="mt-0.5 h-4 w-4 text-amber-600 dark:text-amber-400" />
|
|
<div className="text-sm">
|
|
<p className="font-medium text-amber-800 dark:text-amber-200">삭제 시 주의사항</p>
|
|
<p className="mt-1 text-amber-700 dark:text-amber-300">
|
|
• 해당 회사와 연관된 모든 데이터가 함께 삭제될 수 있습니다.
|
|
<br />
|
|
• 삭제된 데이터는 복구할 수 없습니다.
|
|
<br />• 신중하게 검토 후 진행해주세요.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div> */}
|
|
|
|
{/* 에러 메시지 */}
|
|
{error && (
|
|
<div className="bg-destructive/10 rounded-md p-3">
|
|
<p className="text-destructive text-sm">{error}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onClick={handleCancel} disabled={isLoading || isDeleting}>
|
|
{_t("company.delete.cancel")}
|
|
</Button>
|
|
<Button
|
|
variant="destructive"
|
|
onClick={handleConfirm}
|
|
disabled={isLoading || isDeleting}
|
|
className="min-w-[120px]"
|
|
>
|
|
{isLoading || isDeleting ? <LoadingSpinner className="mr-2 h-4 w-4" /> : _t("company.delete.confirm")}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|