[ST] - fix: 입력관리 기간 연도 입력 오류 수정
This commit is contained in:
@@ -19,7 +19,6 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
Input,
|
||||
InputDatePicker,
|
||||
Label,
|
||||
Select,
|
||||
SelectContent,
|
||||
@@ -48,9 +47,32 @@ function normalizeStatsYrInput(raw: string): string {
|
||||
function formatDateToYmd(d: Date | undefined): string | null {
|
||||
if (!d || Number.isNaN(d.getTime())) return null;
|
||||
const y = d.getFullYear();
|
||||
if (y < 1000 || y > 9999) return null;
|
||||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
return `${y}${m}${day}`;
|
||||
return `${String(y).padStart(4, "0")}${m}${day}`;
|
||||
}
|
||||
|
||||
/** Chrome `type="date"`는 max가 없으면 연도를 6자리까지 받음 */
|
||||
const PERIOD_DATE_INPUT_MIN = "1000-01-01";
|
||||
const PERIOD_DATE_INPUT_MAX = "9999-12-31";
|
||||
|
||||
function formatDateToInputValue(d: Date | undefined): string {
|
||||
if (!d || Number.isNaN(d.getTime())) return "";
|
||||
const ymd = formatDateToYmd(d);
|
||||
if (!ymd) return "";
|
||||
return `${ymd.slice(0, 4)}-${ymd.slice(4, 6)}-${ymd.slice(6, 8)}`;
|
||||
}
|
||||
|
||||
function parseFourDigitYearDate(raw: string): Date | undefined {
|
||||
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw);
|
||||
if (!match) return undefined;
|
||||
const year = Number(match[1]);
|
||||
const month = Number(match[2]);
|
||||
const day = Number(match[3]);
|
||||
const parsed = new Date(year, month - 1, day);
|
||||
if (Number.isNaN(parsed.getTime()) || parsed.getFullYear() !== year) return undefined;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
export interface StatisticsInputPeriodDialogProps {
|
||||
@@ -281,18 +303,26 @@ export function StatisticsInputPeriodDialog({
|
||||
)}
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label className="text-label">시작일</Label>
|
||||
<InputDatePicker
|
||||
value={bgngYmd}
|
||||
onChange={setBgngYmd}
|
||||
className="w-full"
|
||||
<Input
|
||||
type="date"
|
||||
min={PERIOD_DATE_INPUT_MIN}
|
||||
max={PERIOD_DATE_INPUT_MAX}
|
||||
value={formatDateToInputValue(bgngYmd)}
|
||||
onChange={(e) => setBgngYmd(parseFourDigitYearDate(e.target.value))}
|
||||
disabled={isSubmitting}
|
||||
className="!text-[1.3rem] w-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label className="text-label">종료일</Label>
|
||||
<InputDatePicker
|
||||
value={endYmd}
|
||||
onChange={setEndYmd}
|
||||
className="w-full"
|
||||
<Input
|
||||
type="date"
|
||||
min={PERIOD_DATE_INPUT_MIN}
|
||||
max={PERIOD_DATE_INPUT_MAX}
|
||||
value={formatDateToInputValue(endYmd)}
|
||||
onChange={(e) => setEndYmd(parseFourDigitYearDate(e.target.value))}
|
||||
disabled={isSubmitting}
|
||||
className="!text-[1.3rem] w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user