/** * 폼 검증 상태 표시 컴포넌트 * 실시간 검증 피드백과 사용자 가이드를 제공 */ import React from "react"; import { AlertCircle, CheckCircle, Clock, AlertTriangle, Info } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Separator } from "@/components/ui/separator"; import { Progress } from "@/components/ui/progress"; import { FormValidationState, SaveState, ValidationError, ValidationWarning } from "@/hooks/useFormValidation"; // Props 타입 export interface FormValidationIndicatorProps { validationState: FormValidationState; saveState: SaveState; onValidate?: () => void; onSave?: () => void; canSave?: boolean; compact?: boolean; showDetails?: boolean; showPerformance?: boolean; } /** * 메인 검증 상태 표시 컴포넌트 */ export const FormValidationIndicator: React.FC = ({ validationState, saveState, onValidate, onSave, canSave = false, compact = false, showDetails = true, showPerformance = false, }) => { if (compact) { return ( ); } return (
폼 검증 상태
{validationState.lastValidated && ( {validationState.lastValidated.toLocaleTimeString()} )}
{/* 검증 요약 */} {/* 액션 버튼들 */}
{/* 상세 정보 */} {showDetails && ( <> )} {/* 성능 정보 */} {showPerformance && saveState.result?.performance && ( <> )}
); }; /** * 간단한 검증 상태 표시 */ const CompactValidationIndicator: React.FC<{ validationState: FormValidationState; saveState: SaveState; onSave?: () => void; canSave: boolean; }> = ({ validationState, saveState, onSave, canSave }) => { return (
{validationState.errors.length > 0 && ( {validationState.errors.length}개 오류 )} {validationState.warnings.length > 0 && ( {validationState.warnings.length}개 경고 )} {validationState.isValid && 검증 통과}
); }; /** * 검증 상태 배지 */ const ValidationStatusBadge: React.FC<{ status: FormValidationState["status"] }> = ({ status }) => { const getStatusConfig = () => { switch (status) { case "idle": return { variant: "secondary" as const, icon: Info, text: "대기중", }; case "validating": return { variant: "secondary" as const, icon: Clock, text: "검증중", animate: true, }; case "valid": return { variant: "default" as const, icon: CheckCircle, text: "유효함", className: "bg-green-500 hover:bg-green-600", }; case "invalid": return { variant: "destructive" as const, icon: AlertCircle, text: "오류", }; default: return { variant: "secondary" as const, icon: Info, text: "알 수 없음", }; } }; const config = getStatusConfig(); const IconComponent = config.icon; return ( {config.text} ); }; /** * 검증 요약 정보 */ const ValidationSummary: React.FC<{ validationState: FormValidationState }> = ({ validationState }) => { const totalFields = Object.keys(validationState.fieldStates).length; const validFields = Object.values(validationState.fieldStates).filter((field) => field.status === "valid").length; const progress = totalFields > 0 ? (validFields / totalFields) * 100 : 0; return (
{/* 진행률 */} {totalFields > 0 && (
검증 진행률 {validFields}/{totalFields} 필드
)} {/* 오류/경고 카운트 */}
{validationState.errors.length > 0 && (
{validationState.errors.length}개 오류
)} {validationState.warnings.length > 0 && (
{validationState.warnings.length}개 경고
)} {validationState.isValid && validationState.errors.length === 0 && validationState.warnings.length === 0 && (
모든 검증 통과
)}
); }; /** * 검증 상세 정보 */ const ValidationDetails: React.FC<{ validationState: FormValidationState }> = ({ validationState }) => { if (validationState.errors.length === 0 && validationState.warnings.length === 0) { return ( 모든 검증이 성공적으로 완료되었습니다. ); } return (
{/* 오류 목록 */} {validationState.errors.map((error, index) => ( ))} {/* 경고 목록 */} {validationState.warnings.map((warning, index) => ( ))}
); }; /** * 개별 오류 아이템 */ const ValidationErrorItem: React.FC<{ error: ValidationError }> = ({ error }) => { return ( {error.field}: {error.message} {error.value !== undefined && ( 입력값: "{String(error.value)}" )} ); }; /** * 개별 경고 아이템 */ const ValidationWarningItem: React.FC<{ warning: ValidationWarning }> = ({ warning }) => { return ( {warning.field}: {warning.message} {warning.suggestion && 💡 {warning.suggestion}} ); }; /** * 성능 정보 표시 */ const PerformanceInfo: React.FC<{ performance: { validationTime: number; saveTime: number; totalTime: number }; }> = ({ performance }) => { return (

성능 정보

검증 시간
{performance.validationTime.toFixed(2)}ms
저장 시간
{performance.saveTime.toFixed(2)}ms
총 시간
{performance.totalTime.toFixed(2)}ms
); }; /** * 필드별 검증 상태 표시 컴포넌트 */ export const FieldValidationIndicator: React.FC<{ fieldName: string; error?: ValidationError; warning?: ValidationWarning; status?: "idle" | "validating" | "valid" | "invalid"; showIcon?: boolean; className?: string; }> = ({ fieldName, error, warning, status = "idle", showIcon = true, className }) => { if (status === "idle" && !error && !warning) { return null; } return (
{showIcon && ( <> {status === "validating" && } {status === "valid" && !error && } {error && } {warning && !error && } )} {error && {error.message}} {warning && !error && {warning.message}}
); };