62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
|
|
/**
|
||
|
|
* FormSection - 폼 섹션 카드 컴포넌트
|
||
|
|
*
|
||
|
|
* 등록 페이지의 각 섹션을 카드로 감싸는 컴포넌트
|
||
|
|
* 제목, 설명, 아이콘을 포함할 수 있습니다.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { ReactNode } from "react";
|
||
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card";
|
||
|
|
import { LucideIcon } from "lucide-react";
|
||
|
|
|
||
|
|
export interface FormSectionProps {
|
||
|
|
title?: string;
|
||
|
|
description?: string;
|
||
|
|
icon?: LucideIcon;
|
||
|
|
children: ReactNode;
|
||
|
|
className?: string;
|
||
|
|
headerAction?: ReactNode;
|
||
|
|
variant?: 'default' | 'highlighted';
|
||
|
|
}
|
||
|
|
|
||
|
|
export function FormSection({
|
||
|
|
title,
|
||
|
|
description,
|
||
|
|
icon: Icon,
|
||
|
|
children,
|
||
|
|
className = "",
|
||
|
|
headerAction,
|
||
|
|
variant = 'default',
|
||
|
|
}: FormSectionProps) {
|
||
|
|
|
||
|
|
const variantClasses = {
|
||
|
|
default: "",
|
||
|
|
highlighted: "border-blue-200 bg-blue-50/30",
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Card className={`${variantClasses[variant]} ${className}`}>
|
||
|
|
{(title || description) && (
|
||
|
|
<CardHeader>
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<div className="flex items-center gap-2">
|
||
|
|
{Icon && <Icon className="h-5 w-5 text-primary" />}
|
||
|
|
<div>
|
||
|
|
{title && <CardTitle>{title}</CardTitle>}
|
||
|
|
{description && (
|
||
|
|
<CardDescription className="mt-1">{description}</CardDescription>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
{headerAction && (
|
||
|
|
<div>{headerAction}</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</CardHeader>
|
||
|
|
)}
|
||
|
|
<CardContent className={title || description ? "" : "pt-6"}>
|
||
|
|
{children}
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
);
|
||
|
|
}
|