"use client"; import { useState } from "react"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { Switch } from "@/components/ui/switch"; import { CustomCalendar } from "@/components/ui/custom-calendar"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { AlertCircle, CheckCircle, Calendar as CalendarIcon } from "lucide-react"; import { cn } from "@/lib/utils"; interface FormData { name: string; email: string; phone: string; category: string; priority: string; startDate?: Date; endDate?: Date; description: string; isActive: boolean; } interface FormErrors { name?: string; email?: string; phone?: string; category?: string; startDate?: string; } export function ExampleFormDialog() { const [isOpen, setIsOpen] = useState(false); const [formData, setFormData] = useState({ name: "", email: "", phone: "", category: "", priority: "medium", description: "", isActive: true, }); const [errors, setErrors] = useState({}); const [isSubmitting, setIsSubmitting] = useState(false); // 폼 유효성 검사 const validateForm = (): boolean => { const newErrors: FormErrors = {}; // 이름 검증 if (!formData.name.trim()) { newErrors.name = "이름을 입력해주세요"; } else if (formData.name.length < 2) { newErrors.name = "이름은 2자 이상이어야 합니다"; } // 이메일 검증 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!formData.email.trim()) { newErrors.email = "이메일을 입력해주세요"; } else if (!emailRegex.test(formData.email)) { newErrors.email = "올바른 이메일 형식이 아닙니다"; } // 전화번호 검증 const phoneRegex = /^[0-9-]+$/; if (formData.phone && !phoneRegex.test(formData.phone)) { newErrors.phone = "올바른 전화번호 형식이 아닙니다"; } // 카테고리 검증 if (!formData.category) { newErrors.category = "카테고리를 선택해주세요"; } // 날짜 검증 if (formData.startDate && formData.endDate) { if (formData.startDate > formData.endDate) { newErrors.startDate = "시작일은 종료일보다 이전이어야 합니다"; } } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; // 폼 제출 const handleSubmit = async () => { if (!validateForm()) { return; } setIsSubmitting(true); // API 호출 시뮬레이션 (실제로는 API 호출) await new Promise((resolve) => setTimeout(resolve, 1500)); console.log("폼 데이터:", formData); setIsSubmitting(false); setIsOpen(false); // 폼 초기화 setFormData({ name: "", email: "", phone: "", category: "", priority: "medium", description: "", isActive: true, }); setErrors({}); }; // 폼 필드 변경 const handleChange = (field: keyof FormData, value: any) => { setFormData((prev) => ({ ...prev, [field]: value })); // 해당 필드의 에러 제거 if (errors[field as keyof FormErrors]) { setErrors((prev) => { const newErrors = { ...prev }; delete newErrors[field as keyof FormErrors]; return newErrors; }); } }; // 취소 const handleCancel = () => { setIsOpen(false); setFormData({ name: "", email: "", phone: "", category: "", priority: "medium", description: "", isActive: true, }); setErrors({}); }; return ( <> {/* 트리거 버튼 */} {/* 폼 Dialog */} 사용자 정보 등록 아래 정보를 입력하여 새로운 사용자를 등록하세요. 필수 항목은 * 표시되어 있습니다. {/* 폼 컨텐츠 */}
{/* 이름 (필수) */}
handleChange("name", e.target.value)} placeholder="홍길동" className={cn("h-8 text-xs sm:h-10 sm:text-sm", errors.name && "border-destructive")} /> {errors.name && (

{errors.name}

)}
{/* 이메일 (필수) */}
handleChange("email", e.target.value)} placeholder="example@email.com" className={cn("h-8 text-xs sm:h-10 sm:text-sm", errors.email && "border-destructive")} /> {errors.email && (

{errors.email}

)} {!errors.email && formData.email && formData.email.includes("@") && (

올바른 형식입니다

)}
{/* 전화번호 (선택) */}
handleChange("phone", e.target.value)} placeholder="010-1234-5678" className={cn("h-8 text-xs sm:h-10 sm:text-sm", errors.phone && "border-destructive")} /> {errors.phone && (

{errors.phone}

)}
{/* 카테고리 & 우선순위 (같은 줄) */}
{/* 카테고리 (필수) */}
{errors.category && (

{errors.category}

)}
{/* 우선순위 */}
{/* 시작일 & 종료일 (같은 줄) */}
{/* 시작일 */}
handleChange("startDate", date)} /> {errors.startDate && (

{errors.startDate}

)}
{/* 종료일 */}
handleChange("endDate", date)} />
{/* 설명 */}