Files
nice-app-web/src/shared/ui/calendar/nice-calendar-month.tsx
focp212@naver.com 1fcbc35aab 달력 관련 수정
2025-11-07 12:36:58 +09:00

178 lines
5.2 KiB
TypeScript

import moment, { locale } from 'moment';
import styled from "styled-components";
import { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
import { useEffect } from 'react';
import { CalendarType } from '@/entities/common/model/types';
import { useTranslation } from 'react-i18next';
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
interface NiceCalendarProps {
calendarOpen: boolean;
setCalendarOpen: (calendarOpen: boolean) => void;
startMonth?: string;
endMonth?: string;
singleMonth?: string;
calendarType: CalendarType;
setNewMonth: (month: string) => void;
searchPeriod?: number;
periodType?: 'year' | 'month';
};
const NiceCalendarMonth = ({
calendarOpen,
setCalendarOpen,
startMonth,
endMonth,
singleMonth,
calendarType,
setNewMonth,
searchPeriod,
periodType
}: NiceCalendarProps) => {
const { i18n } = useTranslation();
const currentLocale = i18n.language || 'en';
const [valueMonth, setValueMonth] = useState<Date | undefined>();
const [minMonth, setMinMonth] = useState<Date | undefined>();
const [maxMonth, setMaxMonth] = useState<Date | undefined>();
const onChangeToMonth = (selectedMonth: any) => {
setNewMonth(moment(selectedMonth).format('YYYY.MM'));
setCalendarOpen(false);
};
const onClickToClose = () => {
setCalendarOpen(false);
};
const setMinMaxValueDate = () => {
if(calendarType === CalendarType.Start){
if(!searchPeriod){
searchPeriod = 3;
}
if(!periodType){
periodType = 'year';
}
if(periodType && searchPeriod && searchPeriod > 0){
const endDate = moment(endMonth, ['YYYY.MM', 'YYYYMM'], true);
setMinMonth(moment(endDate, 'YYYY.MM.DD').subtract(searchPeriod, periodType).toDate());
}
// setMinMonth(undefined);
if(!!endMonth){
// Parse endMonth with moment, handling both YYYY.MM and YYYYMM formats
const endDate = moment(endMonth, ['YYYY.MM', 'YYYYMM'], true);
if (endDate.isValid()) {
setMaxMonth(endDate.toDate());
}
}
if (startMonth) {
const startDate = moment(startMonth, ['YYYY.MM', 'YYYYMM'], true);
if (startDate.isValid()) {
setValueMonth(startDate.toDate());
}
} else {
setValueMonth(undefined);
}
}
else if(calendarType === CalendarType.End){
if(!!startMonth){
// Parse startMonth with moment, handling both YYYY.MM and YYYYMM formats
const startDate = moment(startMonth, ['YYYY.MM', 'YYYYMM'], true);
if (startDate.isValid()) {
setMinMonth(startDate.toDate());
}
}
setMaxMonth(new Date());
if (endMonth) {
const endDate = moment(endMonth, ['YYYY.MM', 'YYYYMM'], true);
if (endDate.isValid()) {
setValueMonth(endDate.toDate());
}
} else {
setValueMonth(undefined);
}
}
else if(calendarType === CalendarType.Single){
if (singleMonth) {
const singleDate = moment(singleMonth, ['YYYY.MM', 'YYYYMM'], true);
if (singleDate.isValid()) {
setValueMonth(singleDate.toDate());
}
} else {
setValueMonth(undefined);
}
}
};
const formatMonthYear = (locale: string | undefined, date: Date) => {
return date.toLocaleDateString(currentLocale, {
month: 'long',
year: 'numeric'
});
};
const formatYear = (locale: string | undefined, date: Date) => {
return date.toLocaleDateString(currentLocale, {
year: 'numeric'
});
};
const formmatMonth = (locale: string | undefined, date: Date) => {
return date.toLocaleDateString(currentLocale, {
month: 'short'
});
};
const formatDay = (locale: string | undefined, date: Date) => {
// For Korean locale, return only the day number without '일'
if (currentLocale === 'ko') {
return date.getDate().toString();
}
return date.toLocaleString(currentLocale, {
day: 'numeric'
});
};
const formatShortWeekday = (locale: string | undefined, date: Date) => {
return date.toLocaleString(currentLocale, {
weekday: 'short'
});
};
useEffect(() => {
setMinMaxValueDate();
}, [calendarOpen])
return (
<>
{ (calendarOpen) &&
<>
<div className="bg-dim"></div>
<CalendarWrapper className="calendar-container calendar-style">
<FullMenuClose
addClass='filter-calendar-close'
onClickToCallback={ onClickToClose }
></FullMenuClose>
<Calendar
locale={currentLocale}
minDate={ minMonth }
maxDate={ maxMonth }
onClickMonth={ onChangeToMonth }
value={ valueMonth }
formatMonthYear={ formatMonthYear }
formatYear= { formatYear }
formatMonth={ formmatMonth }
formatDay={ formatDay }
formatShortWeekday={ formatShortWeekday }
showNeighboringMonth={ true }
defaultView='year'
view='year'
></Calendar>
</CalendarWrapper>
</>
}
</>
);
};
const CalendarWrapper = styled.div`
z-index: 1100;
`;
export default NiceCalendarMonth;