summaryrefslogtreecommitdiff
path: root/lib/vendors/items-table/item-action-dialog.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendors/items-table/item-action-dialog.tsx')
-rw-r--r--lib/vendors/items-table/item-action-dialog.tsx248
1 files changed, 248 insertions, 0 deletions
diff --git a/lib/vendors/items-table/item-action-dialog.tsx b/lib/vendors/items-table/item-action-dialog.tsx
new file mode 100644
index 00000000..19df27f8
--- /dev/null
+++ b/lib/vendors/items-table/item-action-dialog.tsx
@@ -0,0 +1,248 @@
+// components/vendor-items/item-actions-dialogs.tsx
+"use client"
+
+import * as React from "react"
+import type { DataTableRowAction } from "@/types/table"
+import { VendorItemsView } from "@/db/schema/vendors"
+import { toast } from "sonner"
+
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog"
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+} from "@/components/ui/alert-dialog"
+import { Button } from "@/components/ui/button"
+import { Label } from "@/components/ui/label"
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select"
+
+import { updateVendorItem, deleteVendorItem, getItemsForVendor } from "../service"
+
+interface ItemActionsDialogsProps {
+ vendorId: number
+ rowAction: DataTableRowAction<VendorItemsView> | null
+ setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<VendorItemsView> | null>>
+}
+
+export function ItemActionsDialogs({
+ vendorId,
+ rowAction,
+ setRowAction,
+}: ItemActionsDialogsProps) {
+ const [isUpdatePending, startUpdateTransition] = React.useTransition()
+ const [isDeletePending, startDeleteTransition] = React.useTransition()
+ const [availableMaterials, setAvailableMaterials] = React.useState<any[]>([])
+ const [selectedItemCode, setSelectedItemCode] = React.useState<string>("")
+
+ // 사용 가능한 재료 목록 로드
+ React.useEffect(() => {
+ if (rowAction?.type === "update") {
+ getItemsForVendor(vendorId).then((result) => {
+ if (result.data) {
+ setAvailableMaterials(result.data)
+ }
+ })
+ }
+ }, [rowAction, vendorId])
+
+ // Edit Dialog
+ const EditDialog = () => {
+ if (!rowAction || rowAction.type !== "update") return null
+
+ const item = rowAction.row.original
+
+ const handleSubmit = () => {
+ if (!selectedItemCode) {
+ toast.error("Please select a new item")
+ return
+ }
+
+ if (!item.itemCode) {
+ toast.error("Invalid item code")
+ return
+ }
+
+ startUpdateTransition(async () => {
+ const result = await updateVendorItem(vendorId, item.itemCode, selectedItemCode)
+
+ if (result.error) {
+ toast.error(result.error)
+ } else {
+ toast.success("Item updated successfully")
+ setRowAction(null)
+ }
+ })
+ }
+
+ return (
+ <Dialog
+ open={true}
+ onOpenChange={(open) => !open && setRowAction(null)}
+ >
+ <DialogContent className="sm:max-w-[425px]">
+ <DialogHeader>
+ <DialogTitle>Change Item</DialogTitle>
+ <DialogDescription>
+ Select a new item to replace "{item.itemName}" (Code: {item.itemCode || 'N/A'}).
+ </DialogDescription>
+ </DialogHeader>
+
+ <div className="space-y-4">
+ <div className="space-y-2">
+ <Label>Current Item</Label>
+ <div className="p-2 bg-muted rounded-md">
+ <div className="font-medium">{item.itemName}</div>
+ <div className="text-sm text-muted-foreground">Code: {item.itemCode || 'N/A'}</div>
+ </div>
+ </div>
+
+ <div className="space-y-2">
+ <Label htmlFor="newItem">New Item</Label>
+ <Select value={selectedItemCode} onValueChange={setSelectedItemCode}>
+ <SelectTrigger>
+ <SelectValue placeholder="Select a new item" />
+ </SelectTrigger>
+ <SelectContent>
+ {availableMaterials.map((material) => (
+ <SelectItem key={material.itemCode} value={material.itemCode}>
+ <div>
+ <div className="font-medium">{material.itemName}</div>
+ <div className="text-sm text-muted-foreground">Code: {material.itemCode}</div>
+ </div>
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ </div>
+ </div>
+
+ <DialogFooter>
+ <Button
+ type="button"
+ variant="outline"
+ onClick={() => setRowAction(null)}
+ disabled={isUpdatePending}
+ >
+ Cancel
+ </Button>
+ <Button
+ onClick={handleSubmit}
+ disabled={isUpdatePending || !selectedItemCode}
+ >
+ {isUpdatePending ? "Updating..." : "Update Item"}
+ </Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>
+ )
+ }
+
+ // Delete Dialog
+ const DeleteDialog = () => {
+ if (!rowAction || rowAction.type !== "delete") return null
+
+ const item = rowAction.row.original
+
+ const handleDelete = () => {
+ if (!item.itemCode) {
+ toast.error("Invalid item code")
+ return
+ }
+
+ startDeleteTransition(async () => {
+ const result = await deleteVendorItem(vendorId, item.itemCode)
+
+ if (result.error) {
+ toast.error(result.error)
+ } else {
+ toast.success("Item deleted successfully")
+ setRowAction(null)
+ }
+ })
+ }
+
+ return (
+ <AlertDialog
+ open={true}
+ onOpenChange={(open) => !open && setRowAction(null)}
+ >
+ <AlertDialogContent>
+ return (
+ <AlertDialog
+ open={true}
+ onOpenChange={(open) => !open && setRowAction(null)}
+ >
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>Are you sure?</AlertDialogTitle>
+ <AlertDialogDescription>
+ This will permanently delete the item "{item.itemName}" (Code: {item.itemCode || 'N/A'}).
+ This action cannot be undone.
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel disabled={isDeletePending}>
+ Cancel
+ </AlertDialogCancel>
+ <AlertDialogAction
+ onClick={handleDelete}
+ disabled={isDeletePending}
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
+ >
+ {isDeletePending ? "Deleting..." : "Delete"}
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+ )
+ }
+
+ return (
+ <>
+ <EditDialog />
+ <DeleteDialog />
+ </>
+ )
+}
+ <AlertDialogFooter>
+ <AlertDialogCancel disabled={isDeletePending}>
+ Cancel
+ </AlertDialogCancel>
+ <AlertDialogAction
+ onClick={handleDelete}
+ disabled={isDeletePending}
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
+ >
+ {isDeletePending ? "Deleting..." : "Delete"}
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+ )
+ }
+
+ return (
+ <>
+ <EditDialog />
+ <DeleteDialog />
+ </>
+ )
+} \ No newline at end of file