- 공통 컴포넌트 11개 생성 (PageHeader, StatusBadge, CategoryBadge, FilterDropdown, DateRangeInput, SearchInput, FilterResetButton, Pagination, EmptyState, CopyButton, PlatformBadge) - AppHeader: 다단계 breadcrumb, 알림 드롭다운 구현 - AppLayout: 푸터 개인정보처리방침/이용약관 모달 추가 - AppSidebar: 이메일 폰트 자동 축소 (clamp) - SignupPage: 모달 닫기 버튼 x 아이콘으로 통일 - Suspense fallback SVG 스피너로 변경 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
interface DateRangeInputProps {
|
|
startDate: string;
|
|
endDate: string;
|
|
onStartChange: (value: string) => void;
|
|
onEndChange: (value: string) => void;
|
|
startLabel?: string;
|
|
endLabel?: string;
|
|
}
|
|
|
|
/** 시작일~종료일 날짜 입력 (자동 보정) */
|
|
export default function DateRangeInput({
|
|
startDate,
|
|
endDate,
|
|
onStartChange,
|
|
onEndChange,
|
|
startLabel = "시작일",
|
|
endLabel = "종료일",
|
|
}: DateRangeInputProps) {
|
|
const handleStartChange = (value: string) => {
|
|
onStartChange(value);
|
|
if (endDate && value > endDate) onEndChange(value);
|
|
};
|
|
|
|
const handleEndChange = (value: string) => {
|
|
onEndChange(value);
|
|
if (startDate && value < startDate) onStartChange(value);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{/* 시작일 */}
|
|
<div className="flex-1">
|
|
<label className="block text-xs font-medium text-gray-600 mb-1.5">
|
|
{startLabel}
|
|
</label>
|
|
<div className="relative">
|
|
<span className="absolute left-3 top-1/2 -translate-y-1/2 material-symbols-outlined text-gray-400 text-base">
|
|
calendar_today
|
|
</span>
|
|
<input
|
|
type="date"
|
|
value={startDate}
|
|
onChange={(e) => handleStartChange(e.target.value)}
|
|
className="w-full h-[38px] pl-10 pr-3 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-primary/20 focus:border-primary transition-colors"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<span className="text-gray-400 text-sm font-medium pb-2">~</span>
|
|
|
|
{/* 종료일 */}
|
|
<div className="flex-1">
|
|
<label className="block text-xs font-medium text-gray-600 mb-1.5">
|
|
{endLabel}
|
|
</label>
|
|
<div className="relative">
|
|
<span className="absolute left-3 top-1/2 -translate-y-1/2 material-symbols-outlined text-gray-400 text-base">
|
|
calendar_today
|
|
</span>
|
|
<input
|
|
type="date"
|
|
value={endDate}
|
|
onChange={(e) => handleEndChange(e.target.value)}
|
|
className="w-full h-[38px] pl-10 pr-3 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-primary/20 focus:border-primary transition-colors"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|