summaryrefslogtreecommitdiff
path: root/lib/vendors
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendors')
-rw-r--r--lib/vendors/contacts-table/contact-table.tsx77
-rw-r--r--lib/vendors/service.ts30
-rw-r--r--lib/vendors/validations.ts7
3 files changed, 113 insertions, 1 deletions
diff --git a/lib/vendors/contacts-table/contact-table.tsx b/lib/vendors/contacts-table/contact-table.tsx
index 65b12451..c0e76292 100644
--- a/lib/vendors/contacts-table/contact-table.tsx
+++ b/lib/vendors/contacts-table/contact-table.tsx
@@ -13,10 +13,20 @@ import { DataTable } from "@/components/data-table/data-table"
import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
import { useFeatureFlags } from "./feature-flags-provider"
import { getColumns } from "./contact-table-columns"
-import { getVendorContacts, } from "../service"
+import { getVendorContacts, deleteVendorContact } from "../service"
import { VendorContact, vendors } from "@/db/schema/vendors"
import { VendorsTableToolbarActions } from "./contact-table-toolbar-actions"
import { EditContactDialog } from "./edit-contact-dialog"
+import { toast } from "sonner"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog"
+import { Button } from "@/components/ui/button"
interface VendorsTableProps {
promises: Promise<
@@ -36,6 +46,8 @@ export function VendorContactsTable({ promises , vendorId}: VendorsTableProps) {
const [rowAction, setRowAction] = React.useState<DataTableRowAction<VendorContact> | null>(null)
const [editDialogOpen, setEditDialogOpen] = React.useState(false)
const [selectedContact, setSelectedContact] = React.useState<VendorContact | null>(null)
+ const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false)
+ const [isDeleting, setIsDeleting] = React.useState(false)
// Edit 액션 처리
React.useEffect(() => {
@@ -43,9 +55,41 @@ export function VendorContactsTable({ promises , vendorId}: VendorsTableProps) {
setSelectedContact(rowAction.row.original)
setEditDialogOpen(true)
setRowAction(null)
+ } else if (rowAction?.type === "delete") {
+ setSelectedContact(rowAction.row.original)
+ setDeleteDialogOpen(true)
+ setRowAction(null)
}
}, [rowAction])
+ // Delete 액션 처리 함수
+ const handleDelete = React.useCallback(async () => {
+ if (!selectedContact) return
+
+ setIsDeleting(true)
+ try {
+ const result = await deleteVendorContact({
+ id: selectedContact.id,
+ vendorId: vendorId
+ })
+
+ if (result.success) {
+ toast.success(result.message)
+ // 페이지를 새로고침하거나 데이터를 다시 가져오기
+ window.location.reload()
+ } else {
+ toast.error(result.message)
+ }
+ } catch (error) {
+ toast.error("Failed to delete contact")
+ console.error("Error deleting contact:", error)
+ } finally {
+ setIsDeleting(false)
+ setDeleteDialogOpen(false)
+ setSelectedContact(null)
+ }
+ }, [selectedContact, vendorId])
+
// 데이터 새로고침 함수
const handleEditSuccess = React.useCallback(() => {
// 페이지를 새로고침하거나 데이터를 다시 가져오기
@@ -107,6 +151,37 @@ export function VendorContactsTable({ promises , vendorId}: VendorsTableProps) {
onOpenChange={setEditDialogOpen}
onSuccess={handleEditSuccess}
/>
+
+ {/* Delete 확인 다이얼로그 */}
+ {selectedContact && (
+ <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>연락처 삭제</DialogTitle>
+ <DialogDescription>
+ 정말로 "{selectedContact.contactName}" 연락처를 삭제하시겠습니까?
+ 이 작업은 되돌릴 수 없습니다.
+ </DialogDescription>
+ </DialogHeader>
+ <DialogFooter>
+ <Button
+ variant="outline"
+ onClick={() => setDeleteDialogOpen(false)}
+ disabled={isDeleting}
+ >
+ 취소
+ </Button>
+ <Button
+ variant="destructive"
+ onClick={handleDelete}
+ disabled={isDeleting}
+ >
+ {isDeleting ? "삭제 중..." : "삭제"}
+ </Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>
+ )}
</>
)
} \ No newline at end of file
diff --git a/lib/vendors/service.ts b/lib/vendors/service.ts
index 98c72349..6813f717 100644
--- a/lib/vendors/service.ts
+++ b/lib/vendors/service.ts
@@ -45,6 +45,7 @@ import type {
GetVendorContactsSchema,
CreateVendorContactSchema,
UpdateVendorContactSchema,
+ DeleteVendorContactSchema,
GetVendorItemsSchema,
CreateVendorItemSchema,
GetRfqHistorySchema,
@@ -3680,4 +3681,33 @@ export async function getBidHistory(input: GetBidHistorySchema, vendorId: number
console.error("Error fetching bid history:", err);
return { data: [], pageCount: 0 };
}
+}
+
+// deleteVendorContact 함수 추가
+export async function deleteVendorContact(input: DeleteVendorContactSchema) {
+ unstable_noStore(); // Next.js 서버 액션 캐싱 방지
+ try {
+ await db.transaction(async (tx) => {
+ // DB Delete
+ await tx
+ .delete(vendorContacts)
+ .where(and(
+ eq(vendorContacts.id, input.id),
+ eq(vendorContacts.vendorId, input.vendorId)
+ ));
+ });
+
+ // 캐시 무효화 (협력업체 연락처 목록 등)
+ revalidateTag(`vendor-contacts-${input.vendorId}`);
+
+ return { success: true, message: "Contact deleted successfully" };
+ } catch (error) {
+ console.error("Error deleting vendor contact:", error);
+ return {
+ success: false,
+ message: error instanceof z.ZodError
+ ? error.errors[0].message
+ : "Failed to delete contact"
+ };
+ }
} \ No newline at end of file
diff --git a/lib/vendors/validations.ts b/lib/vendors/validations.ts
index 88a39651..4a165f03 100644
--- a/lib/vendors/validations.ts
+++ b/lib/vendors/validations.ts
@@ -372,6 +372,12 @@ export const updateVendorItemSchema = z.object({
description: z.string().optional()
});
+// DeleteVendorContactSchema 추가
+export const deleteVendorContactSchema = z.object({
+ id: z.number().min(1, "Contact ID is required"),
+ vendorId: z.number().min(1, "Vendor ID is required"),
+})
+
export const searchParamsRfqHistoryCache = createSearchParamsCache({
// 공통 플래그
flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault(
@@ -413,6 +419,7 @@ export type CreateVendorContactSchema = z.infer<typeof createVendorContactSchema
export type UpdateVendorContactSchema = z.infer<typeof updateVendorContactSchema>
export type CreateVendorItemSchema = z.infer<typeof createVendorItemSchema>
export type UpdateVendorItemSchema = z.infer<typeof updateVendorItemSchema>
+export type DeleteVendorContactSchema = z.infer<typeof deleteVendorContactSchema>
export type GetRfqHistorySchema = Awaited<ReturnType<typeof searchParamsRfqHistoryCache.parse>>