Files
frontend/apps/sn/app/components/ui/YearRangeSelectBox.tsx
T

125 lines
3.4 KiB
TypeScript

/**
* 📄 YearRangeSelectBox Component
* 년도 범위 선택 컴포넌트
*
* - 시작년도와 종료년도 선택 기능
* - 년도 범위 유효성 검증 (시작년도 <= 종료년도)
* - 동적 옵션 생성 및 필터링
* - 전체 선택 옵션 제공
* - 커스텀 라벨 및 스타일링 지원
* - 콜백 함수를 통한 선택 값 전달
*/
import React from "react";
import { SelectBox } from "@common/business_components/ui";
interface YearRangeSelectBoxProps {
start: string;
end: string;
onChange: (range: { start: string; end: string }) => void;
startLabel?: string;
endLabel?: string;
minYear?: number;
maxYear?: number;
className?: string;
selectClass?: string;
}
// 시작년도 selectArray 생성 함수
export function getStartYearArray({
minYear = 1900,
maxYear = new Date().getFullYear(),
placeholder = "년",
endYear,
}: {
minYear?: number;
maxYear?: number;
placeholder?: string;
endYear?: string;
} = {}) {
const years = Array.from({ length: maxYear - minYear + 1 }, (_, i) =>
(maxYear - i).toString(),
).filter((y) => !endYear || parseInt(y) <= parseInt(endYear));
return [
{ val: "0", text: placeholder },
...years.map((y) => ({ val: y, text: y })),
];
}
// 종료년도 selectArray 생성 함수
export function getEndYearArray({
minYear = 1900,
maxYear = new Date().getFullYear(),
placeholder = "년",
startYear,
}: {
minYear?: number;
maxYear?: number;
placeholder?: string;
startYear?: string;
} = {}) {
const years = Array.from({ length: maxYear - minYear + 1 }, (_, i) =>
(maxYear - i).toString(),
).filter((y) => !startYear || parseInt(y) >= parseInt(startYear));
return [
{ val: "9999", text: placeholder },
...years.map((y) => ({ val: y, text: y })),
];
}
export function YearRangeSelectBox({
start,
end,
onChange,
startLabel = "시작년도",
endLabel = "",
minYear = 1900,
maxYear = new Date().getFullYear(),
className = "",
selectClass = "rounded-lg bg-background flex-shrink-0 w-[70px]",
}: YearRangeSelectBoxProps) {
// 시작년도 배열
const getStartYearArray = () => {
const years = Array.from({ length: maxYear - minYear + 1 }, (_, i) =>
(maxYear - i).toString(),
).filter((y) => !end || parseInt(y) <= parseInt(end));
return [
{ val: "0", text: "전체" },
...years.map((y) => ({ val: y, text: y })),
];
};
// 종료년도 배열
const getEndYearArray = () => {
const years = Array.from({ length: maxYear - minYear + 1 }, (_, i) =>
(maxYear - i).toString(),
).filter((y) => !start || parseInt(y) >= parseInt(start));
return [
{ val: "9999", text: "전체" },
...years.map((y) => ({ val: y, text: y })),
];
};
return (
<div className={`mr-8 flex items-center ${className}`}>
<SelectBox
className="flex-1"
selectClass={selectClass}
label={startLabel}
selectArray={getStartYearArray()}
onSelectValue={(val) => onChange({ start: String(val), end })}
value={start}
selectContentClass="z-[101]"
/>
<span className="mx-2 text-xl font-semibold">~</span>
<SelectBox
className="flex-1"
selectClass={selectClass}
label={endLabel}
selectArray={getEndYearArray()}
onSelectValue={(val) => onChange({ start, end: String(val) })}
value={end}
selectContentClass="z-[101]"
/>
</div>
);
}