From a070f833d132e6370311c0bbdad03beb51d595df Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Wed, 15 Oct 2025 21:38:21 +0900
Subject: (김준회) 이메일 화이트리스트 (SMS 우회) 기능 추가 및 기존 로그인 과정
 통합
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../table/delete-whitelist-dialog.tsx              | 137 +++++++++++++++++++++
 1 file changed, 137 insertions(+)
 create mode 100644 lib/email-whitelist/table/delete-whitelist-dialog.tsx

(limited to 'lib/email-whitelist/table/delete-whitelist-dialog.tsx')

diff --git a/lib/email-whitelist/table/delete-whitelist-dialog.tsx b/lib/email-whitelist/table/delete-whitelist-dialog.tsx
new file mode 100644
index 00000000..c01e675b
--- /dev/null
+++ b/lib/email-whitelist/table/delete-whitelist-dialog.tsx
@@ -0,0 +1,137 @@
+// delete-whitelist-dialog.tsx
+"use client"
+
+import * as React from "react"
+import { Loader, Trash } from "lucide-react"
+import { toast } from "sonner"
+
+import { Button } from "@/components/ui/button"
+import {
+  Dialog,
+  DialogContent,
+  DialogDescription,
+  DialogFooter,
+  DialogHeader,
+  DialogTitle,
+  DialogTrigger,
+} from "@/components/ui/dialog"
+import { type EmailWhitelist } from "../service"
+
+import { deleteEmailWhitelistAction } from "../service"
+
+interface DeleteWhitelistDialogProps
+  extends React.ComponentPropsWithRef<typeof Dialog> {
+  whitelists: EmailWhitelist[]
+  showTrigger?: boolean
+  onSuccess?: () => void
+}
+
+export function DeleteWhitelistDialog({
+  whitelists,
+  showTrigger = true,
+  onSuccess,
+  ...props
+}: DeleteWhitelistDialogProps) {
+  const [isDeletePending, startDeleteTransition] = React.useTransition()
+
+  const isMultiple = whitelists.length > 1
+  const whitelistInfo = isMultiple ? `${whitelists.length}개 도메인` : whitelists[0]?.domain
+
+  function onDelete() {
+    startDeleteTransition(async () => {
+      const ids = whitelists.map(w => w.id)
+      const { error } = await deleteEmailWhitelistAction(ids)
+
+      if (error) {
+        toast.error(error)
+        return
+      }
+
+      props.onOpenChange?.(false)
+      onSuccess?.()
+      toast.success(
+        isMultiple
+          ? `${whitelists.length}개 도메인이 삭제되었습니다`
+          : "도메인이 삭제되었습니다"
+      )
+    })
+  }
+
+  return (
+    <Dialog {...props}>
+      {showTrigger && (
+        <DialogTrigger asChild>
+          <Button
+            variant="outline"
+            size="sm"
+            className="text-destructive hover:text-destructive"
+          >
+            <Trash className="mr-2 size-4" aria-hidden="true" />
+            삭제
+          </Button>
+        </DialogTrigger>
+      )}
+      <DialogContent>
+        <DialogHeader>
+          <DialogTitle>화이트리스트 도메인 삭제 확인</DialogTitle>
+          <DialogDescription>
+            정말로 <strong>{whitelistInfo}</strong>을(를) 삭제하시겠습니까?
+            {!isMultiple && (
+              <>
+                <br />
+                이 작업은 되돌릴 수 없습니다.
+              </>
+            )}
+          </DialogDescription>
+        </DialogHeader>
+
+        {/* 삭제될 도메인 목록 표시 */}
+        {whitelists.length > 0 && (
+          <div className="rounded-lg bg-muted p-3 max-h-40 overflow-y-auto">
+            <h4 className="text-sm font-medium mb-2">삭제될 항목</h4>
+            <div className="space-y-1">
+              {whitelists.map((whitelist) => {
+                const displayValue = whitelist.email || whitelist.domain || '';
+                const isEmail = displayValue.includes('@');
+
+                return (
+                  <div key={whitelist.id} className="text-xs text-muted-foreground">
+                    <div className="font-medium font-mono">
+                      {isEmail ? displayValue : `@${displayValue}`}
+                    </div>
+                    {whitelist.description && (
+                      <div className="text-xs">{whitelist.description}</div>
+                    )}
+                  </div>
+                );
+              })}
+            </div>
+          </div>
+        )}
+
+        <DialogFooter>
+          <Button
+            variant="outline"
+            onClick={() => props.onOpenChange?.(false)}
+            disabled={isDeletePending}
+          >
+            취소
+          </Button>
+          <Button
+            variant="destructive"
+            onClick={onDelete}
+            disabled={isDeletePending}
+          >
+            {isDeletePending && (
+              <Loader
+                className="mr-2 size-4 animate-spin"
+                aria-hidden="true"
+              />
+            )}
+            {isMultiple ? `${whitelists.length}개 삭제` : "삭제"}
+          </Button>
+        </DialogFooter>
+      </DialogContent>
+    </Dialog>
+  )
+}
-- 
cgit v1.2.3

