-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
JinJu
committed
Dec 4, 2023
1 parent
121e4f0
commit b093d07
Showing
21 changed files
with
412 additions
and
284 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
37 changes: 37 additions & 0 deletions
37
src/core/components/Calendar/DateSelectCalendar/DateSelectCalendar.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { useState } from "react"; | ||
import dayjs from "dayjs"; | ||
|
||
import { Meta } from "@storybook/react"; | ||
import { PeriodDates } from "./types/CalendarCoimponentProps"; | ||
import DateSelectCalendar from "@/core/components/Calendar/DateSelectCalendar"; | ||
|
||
const meta = { | ||
title: "core/Calendar/DateSelectCalendar", | ||
component: DateSelectCalendar, | ||
} satisfies Meta<typeof DateSelectCalendar>; | ||
|
||
export default meta; | ||
|
||
export const Default = () => { | ||
const [ selectedDate, setSelectedDate ] = useState<string>(""); | ||
const [ periodDates, setPeriodDates ] = useState<PeriodDates>({ | ||
startDate: "", | ||
endDate: "", | ||
}); | ||
|
||
const onDateClick = (date: string, periodDates?: PeriodDates) => { | ||
setSelectedDate(date); | ||
setPeriodDates(periodDates!); | ||
}; | ||
|
||
console.log(periodDates); | ||
return ( | ||
<div className = {"w-[500px] border rounded-3xl py-6"}> | ||
<DateSelectCalendar | ||
selectedDate = {selectedDate} | ||
currentMonth = {dayjs("2023-10-25")} | ||
onDateClick = {onDateClick} | ||
/> | ||
</div> | ||
); | ||
}; |
119 changes: 119 additions & 0 deletions
119
src/core/components/Calendar/DateSelectCalendar/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import clsx from "clsx"; | ||
import dayjs from "dayjs"; | ||
import { useState, useCallback } from "react"; | ||
|
||
import { CalendarWeekDayComponent } from "@/core/components/Calendar/subs/CalendarWeekdayComponent"; | ||
import { CalendarHeader } from "@/core/components/Calendar/subs/CalendarHeader"; | ||
import { CalendarDateDto } from "@/core/components/Calendar/types/CalendarDateDto"; | ||
import { CalendarComponentProps } from "./types/CalendarCoimponentProps"; | ||
import { useCalendar } from "@/core/components/Calendar/hooks/useCalendar"; | ||
import CalendarComponentDayText from "./subs/CalendarComponentDayText"; | ||
import CalendarComponentDaySubText from "./subs/CalendarComponentDaySubText"; | ||
import { PeriodDates } from "./types/CalendarCoimponentProps"; | ||
|
||
export interface UseDeateSelectCalendarResponse { | ||
models: { | ||
periodDateArray: string[]; | ||
}, | ||
operations: { | ||
setCalendarPeriodDates: (periodDates: PeriodDates) => void; | ||
} | ||
} | ||
|
||
export const useDateSelectCalendar = (): UseDeateSelectCalendarResponse => { | ||
const [ periodDateArray, setPeriodDateArray ] = useState<string[]>([]); | ||
|
||
const setCalendarPeriodDates = useCallback((periodDates: PeriodDates) => { | ||
if(!periodDates.endDate || !periodDates.startDate) { | ||
return; | ||
} | ||
const startDate: dayjs.Dayjs = dayjs(periodDates.startDate); | ||
const endDate: dayjs.Dayjs = dayjs(periodDates.endDate); | ||
const diffDate: number = endDate.diff(startDate, "day"); | ||
const newState: string[] = []; | ||
|
||
for (let i = 0; i <= diffDate; i++) { | ||
newState.push(startDate.add(i, "day").format("YYYY-MM-DD")); | ||
} | ||
setPeriodDateArray(newState); | ||
}, [setPeriodDateArray]); | ||
return { | ||
models: { | ||
periodDateArray, | ||
}, | ||
operations: { | ||
setCalendarPeriodDates, | ||
}, | ||
}; | ||
}; | ||
|
||
const DateSelectCalendar = ({ | ||
selectedDate, | ||
currentMonth = dayjs(), | ||
disabledDates, | ||
onDateClick, | ||
}: CalendarComponentProps) => { | ||
const { models: commonModels, operations: commonOperations } = useCalendar(); | ||
const { models, operations } = useDateSelectCalendar(); | ||
return ( | ||
<div className = {"flex flex-col h-full w-full"}> | ||
<CalendarHeader | ||
currentMonth = {currentMonth.locale("ko").format("YYYY. MM")} | ||
onPreviousMonthClick = {commonOperations.onPreviousMonthClick} | ||
onNextMonthClick = {commonOperations.onNextMonthClick} | ||
/> | ||
<CalendarWeekDayComponent /> | ||
<div className = {clsx("mt-4")}> | ||
{ | ||
commonModels.calendarDates.map((calendarWeekDates: CalendarDateDto[], index: number) => { | ||
return ( | ||
<div key = {index} className = {clsx("grid grid-cols-7")}> | ||
{ | ||
calendarWeekDates.map((calendarDate: CalendarDateDto, index: number) => ( | ||
<div key = {index} className = {clsx("h-16")}> | ||
<button | ||
className = {"w-full h-full"} | ||
disabled = {(!calendarDate.isThisMonth || disabledDates?.includes(calendarDate.dayjs.format("YYYY-MM-DD")))} | ||
onClick = {(): void => { | ||
const currentDate = calendarDate.dayjs.format("YYYY-MM-DD"); | ||
if (currentDate === selectedDate) { | ||
return; | ||
} | ||
const prevDate: dayjs.Dayjs = dayjs(selectedDate); | ||
const nowDate: dayjs.Dayjs = calendarDate.dayjs; | ||
const isStartDate: boolean = !prevDate || prevDate <= nowDate; | ||
const periodDates: PeriodDates = { | ||
startDate: isStartDate ? prevDate.format("YYYY-MM-DD") : currentDate, | ||
endDate: isStartDate ? currentDate : selectedDate, | ||
}; | ||
operations.setCalendarPeriodDates(periodDates); | ||
onDateClick(currentDate, periodDates); | ||
return; | ||
}} | ||
> | ||
<div className = {clsx("flex flex-col")}> | ||
<CalendarComponentDayText | ||
selectedDate = {selectedDate} | ||
calendarDate = {calendarDate} | ||
periodDateArray = {models.periodDateArray} | ||
/> | ||
<CalendarComponentDaySubText | ||
selectedDate = {selectedDate} | ||
calendarDate = {calendarDate} | ||
periodDateArray = {models.periodDateArray} | ||
/> | ||
</div> | ||
</button> | ||
</div> | ||
)) | ||
} | ||
</div> | ||
); | ||
}) | ||
} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default DateSelectCalendar; |
30 changes: 30 additions & 0 deletions
30
src/core/components/Calendar/DateSelectCalendar/subs/CalendarComponentDaySubText.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { cn } from "@/utilities/utils"; | ||
import { CalendarDateDto } from "@/core/components/Calendar/types/CalendarDateDto"; | ||
|
||
interface CalendarComponentDaySubTextProps { | ||
selectedDate: string; | ||
calendarDate: CalendarDateDto; | ||
periodDateArray?: string[]; | ||
} | ||
|
||
export default function CalendarComponentDaySubText({ | ||
selectedDate, | ||
calendarDate, | ||
periodDateArray, | ||
}: CalendarComponentDaySubTextProps) { | ||
const currentDate = calendarDate.dayjs.format("YYYY-MM-DD"); | ||
const isPeriod = periodDateArray && periodDateArray.length > 0; | ||
const isStartDate = isPeriod && periodDateArray[0] === currentDate; | ||
const isEndDate = isPeriod && periodDateArray[periodDateArray.length - 1] === currentDate; | ||
const singleSelectedDate = !isPeriod && currentDate === selectedDate; | ||
return ( | ||
<div | ||
className = {cn("flex justify-center items-center text-sm font-light mt-1 z-10 whitespace-nowrap", | ||
(isStartDate || isEndDate || singleSelectedDate) ? "text-[#007BC7]" : "text-black", | ||
)} | ||
> | ||
{isStartDate ? "시작일" : isEndDate ? "종료일" : ""} | ||
{!isPeriod && selectedDate === currentDate ? "시작일" : (calendarDate.isToday ? "오늘" : "")} | ||
</div> | ||
); | ||
} |
38 changes: 38 additions & 0 deletions
38
src/core/components/Calendar/DateSelectCalendar/subs/CalendarComponentDayText.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { cn } from "@/utilities/utils"; | ||
import { CalendarDateDto } from "@/core/components/Calendar/types/CalendarDateDto"; | ||
|
||
interface CalendarComponentDayTextProps { | ||
selectedDate: string; | ||
calendarDate: CalendarDateDto; | ||
periodDateArray?: string[]; | ||
} | ||
|
||
export default function CalendarComponentDayText({ | ||
selectedDate, | ||
calendarDate, | ||
periodDateArray, | ||
}: CalendarComponentDayTextProps) { | ||
const currentDate = calendarDate.dayjs.format("YYYY-MM-DD"); | ||
const isPeriod = periodDateArray && periodDateArray.length > 0; | ||
const isStartDate = isPeriod && periodDateArray[0] === currentDate; | ||
const isEndDate = isPeriod && periodDateArray[periodDateArray.length - 1] === currentDate; | ||
const singleSelectedDate = !isPeriod && currentDate === selectedDate; | ||
return ( | ||
<div className = {cn("flex flex-col justify-between items-center")}> | ||
<div | ||
className = {cn("flex justify-center items-center h-8 leading-none text-xs", | ||
{ | ||
"rounded-s-full w-full bg-[#206FE4] text-white": isStartDate, | ||
"rounded-r-full w-full bg-[#206FE4] text-white": isEndDate, | ||
"w-full bg-[#206FE4] text-white": periodDateArray?.includes(currentDate), | ||
"rounded-full w-8 bg-[#206FE4] text-white": singleSelectedDate, | ||
"bg-[#C9CCCF] text-white rounded-full w-8": calendarDate.isToday, | ||
"text-[#C9CCCF]": !calendarDate.isThisMonth && !periodDateArray?.includes(currentDate) && !calendarDate.isToday!, | ||
}, | ||
)} | ||
> | ||
{calendarDate.dayjs.date()} | ||
</div> | ||
</div> | ||
); | ||
} |
13 changes: 13 additions & 0 deletions
13
src/core/components/Calendar/DateSelectCalendar/types/CalendarCoimponentProps.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import dayjs from "dayjs"; | ||
|
||
export interface PeriodDates { | ||
startDate: string; | ||
endDate: string; | ||
} | ||
|
||
export interface CalendarComponentProps { | ||
selectedDate: string; | ||
currentMonth?: dayjs.Dayjs; | ||
disabledDates?: string[]; | ||
onDateClick: (date: string, periodDates?: PeriodDates) => void; | ||
} |
31 changes: 31 additions & 0 deletions
31
src/core/components/Calendar/ScheduleCalendar/ScheduleCalendar.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Meta } from "@storybook/react"; | ||
|
||
import ScheduleCalendar from "@/core/components/Calendar/ScheduleCalendar"; | ||
|
||
const meta = { | ||
title: "core/Calendar/ScheduleCalendar", | ||
component: ScheduleCalendar, | ||
} satisfies Meta<typeof ScheduleCalendar>; | ||
|
||
export default meta; | ||
|
||
export const DefaultCalendar = () => | ||
<div className = {"w-screen"}> | ||
<ScheduleCalendar | ||
markedDates = {{ | ||
"2023-12-01": ["무료체험"], | ||
"2023-12-02": [undefined], | ||
"2023-12-03": [undefined], | ||
"2023-12-04": [undefined], | ||
"2023-12-05": [undefined], | ||
"2023-12-06": [undefined], | ||
"2023-12-07": [undefined], | ||
"2023-12-08": [undefined], | ||
"2023-12-09": [undefined], | ||
"2023-12-10": [undefined], | ||
"2023-12-11": [undefined], | ||
"2023-12-15": ["정식 전환일"], | ||
}} | ||
/> | ||
</div> | ||
; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { useCalendar } from "@/core/components/Calendar/hooks/useCalendar"; | ||
import { CalendarWeekDayComponent } from "@/core/components/Calendar/subs/CalendarWeekdayComponent"; | ||
import { CalendarHeader } from "@/core/components/Calendar/subs/CalendarHeader"; | ||
import { CalendarDayComponent } from "@/core/components/Calendar/ScheduleCalendar/subs/ComponentDayComponent"; | ||
import { CalendarComponentProps } from "@/core/components/Calendar/ScheduleCalendar/types/CalendarComponentProps"; | ||
|
||
const ScheduleCalendar = ({ | ||
markedDates, | ||
}: CalendarComponentProps) => { | ||
const { models, operations } = useCalendar(); | ||
|
||
return ( | ||
<div className = {"flex flex-col h-full w-full"}> | ||
<CalendarHeader | ||
currentMonth = {models.selectedDayjs.locale("ko").format("YYYY. MM")} | ||
onPreviousMonthClick = {operations.onPreviousMonthClick} | ||
onNextMonthClick = {operations.onNextMonthClick} | ||
/> | ||
<CalendarWeekDayComponent /> | ||
<CalendarDayComponent | ||
markedDates = {markedDates} | ||
calendarDates = {models.calendarDates} | ||
/> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ScheduleCalendar; |
62 changes: 62 additions & 0 deletions
62
src/core/components/Calendar/ScheduleCalendar/subs/ComponentDayComponent.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import clsx from "clsx"; | ||
|
||
import { CalendarComponentProps } from "@/core/components/Calendar/ScheduleCalendar/types/CalendarComponentProps"; | ||
import { CalendarDateDto } from "@/core/components/Calendar/types/CalendarDateDto"; | ||
import Typography from "@/core/components/Typography"; | ||
|
||
interface CalendarDayComponentProps extends CalendarComponentProps { | ||
calendarDates: CalendarDateDto[][]; | ||
} | ||
|
||
export const CalendarDayComponent = ({ | ||
markedDates, | ||
calendarDates, | ||
}: CalendarDayComponentProps) => { | ||
return( | ||
<> | ||
{ calendarDates.map((calendarWeekDates: CalendarDateDto[], index) => ( | ||
<div | ||
key = {index} | ||
className = {"grid grid-cols-7 min-w-full w-full h-28"} | ||
> | ||
{ calendarWeekDates.map((calendarDate: CalendarDateDto, index: number) => | ||
( | ||
<div key = {index} className = "flex-v-stack items-center h-full text-center"> | ||
<div | ||
className = {clsx("flex justify-center items-center h-8", | ||
{ | ||
"w-8 rounded-full bg-gray-03": calendarDate.isToday, | ||
"text-gray-03": !calendarDate.isThisMonth, | ||
}, | ||
)}> | ||
<Typography | ||
theme = "body-01-bold" | ||
text = {`${calendarDate.dayjs.date()}`} | ||
className = "text-inherit" | ||
/> | ||
</div> | ||
{ | ||
markedDates && Object.keys(markedDates).map(markedDate => ( | ||
markedDate === calendarDate.dayjs.format("YYYY-MM-DD") && | ||
<div className = "flex-v-stack gap-1 w-full pt-1" key = {markedDate}> | ||
{markedDates?.[markedDate].map((markedDateValue, index) => | ||
( | ||
(markedDateValue || markedDateValue === undefined) && | ||
<div key = {index} className = "bg-primary-00"> | ||
| ||
<Typography theme = "body-02-bold" color = "primary-02" text = {markedDateValue === undefined ? "" : markedDateValue} /> | ||
| ||
</div> | ||
), | ||
)} | ||
</div> | ||
)) | ||
} | ||
</div> | ||
), | ||
)} | ||
</div> | ||
))} | ||
</> | ||
); | ||
}; |
Oops, something went wrong.