'use client' import * as React from "react" import { zodResolver } from "@hookform/resolvers/zod" import { Loader } from "lucide-react" import { useForm } from "react-hook-form" import { toast } from "sonner" import { z } from "zod" import { useSession } from "next-auth/react" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { updateEmailWhitelistAction, type EmailWhitelist } from "../service" // Validation Schema const updateWhitelistSchema = z.object({ value: z.string() .min(1, "값은 필수입니다") .max(255, "값은 255자를 초과할 수 없습니다") .refine((value) => { // 이메일 형식 또는 도메인 형식 중 하나여야 함 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // 도메인 검증: 최소 하나의 .이 있어야 하고, TLD가 있어야 함 // 예: company.com, sub.company.com, company.co.kr const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$/; return emailRegex.test(value) || domainRegex.test(value); }, "올바른 이메일 주소 또는 도메인 형식이 아닙니다 (도메인은 최소 1개의 TLD가 필요합니다)"), description: z.string().max(500, "설명은 500자 이하여야 합니다").optional(), }) type UpdateWhitelistSchema = z.infer interface UpdateWhitelistDialogProps extends React.ComponentPropsWithRef { whitelist?: EmailWhitelist | null } export function UpdateWhitelistDialog({ whitelist, ...props }: UpdateWhitelistDialogProps) { const [isUpdatePending, startUpdateTransition] = React.useTransition() const { data: session } = useSession(); const form = useForm({ resolver: zodResolver(updateWhitelistSchema), defaultValues: { value: "", description: "", }, }) // 화이트리스트 데이터가 변경되면 폼 초기화 React.useEffect(() => { if (whitelist) { form.reset({ value: whitelist.displayValue || "", description: whitelist.description || "", }) } }, [whitelist, form]) // 입력값 소문자 변환 React.useEffect(() => { const watchedValue = form.watch("value") if (watchedValue && watchedValue !== watchedValue.toLowerCase()) { form.setValue("value", watchedValue.toLowerCase()) } }, [form]) function onSubmit(input: UpdateWhitelistSchema) { startUpdateTransition(async () => { if (!session?.user?.id) { toast.error("로그인이 필요합니다") return } if (!whitelist) { toast.error("수정할 데이터를 찾을 수 없습니다") return } const { error } = await updateEmailWhitelistAction({ id: whitelist.id, value: input.value, description: input.description, }) if (error) { toast.error(error) return } props.onOpenChange?.(false) toast.success("화이트리스트 도메인이 수정되었습니다") }) } return ( 화이트리스트 수정 화이트리스트 정보를 수정합니다.
( 이메일 주소 또는 도메인 이메일 주소나 도메인을 입력하세요. @가 포함되면 개별 이메일로, 그렇지 않으면 도메인 전체로 등록됩니다. 도메인은 최소 1개의 TLD가 필요합니다. )} /> ( 설명 (선택사항)