Skip to content

Commit dc0dff2

Browse files
committed
(#246) monthViewWithData 컴포넌트 설계 변경
1 parent cd07886 commit dc0dff2

4 files changed

Lines changed: 97 additions & 52 deletions

File tree

src/components/commons/exerciseCalendar/exerciseCalendar.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client'
22

3+
import { useQueryState } from 'nuqs'
34
import { useState, useMemo, useRef, forwardRef } from 'react'
45
import { startOfMonth, subMonths, addMonths, format } from 'date-fns'
56
import { ko } from 'date-fns/locale'
@@ -31,6 +32,7 @@ const ExerciseCalendar = forwardRef<HTMLDivElement, Props>(
3132
},
3233
ref,
3334
) => {
35+
const [memberId] = useQueryState('memberId')
3436
const today = new Date()
3537
const [currentMonth, setCurrentMonth] = useState<Date>(startOfMonth(today))
3638
const prevMonth = useMemo(() => subMonths(currentMonth, 1), [currentMonth])
@@ -149,6 +151,7 @@ const ExerciseCalendar = forwardRef<HTMLDivElement, Props>(
149151
isReadOnly={isReadOnly}
150152
isOthers={isOthers}
151153
showStamps={showStamps}
154+
memberId={memberId ?? undefined}
152155
/>
153156
<MonthViewWithData
154157
today={today}
@@ -159,6 +162,7 @@ const ExerciseCalendar = forwardRef<HTMLDivElement, Props>(
159162
isReadOnly={isReadOnly}
160163
isOthers={isOthers}
161164
showStamps={showStamps}
165+
memberId={memberId ?? undefined}
162166
/>
163167
<MonthViewWithData
164168
today={today}
@@ -169,6 +173,7 @@ const ExerciseCalendar = forwardRef<HTMLDivElement, Props>(
169173
isReadOnly={isReadOnly}
170174
isOthers={isOthers}
171175
showStamps={showStamps}
176+
memberId={memberId ?? undefined}
172177
/>
173178
</animated.div>
174179
</div>

src/components/commons/exerciseCalendar/monthView.tsx

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import { memo, useMemo, useRef } from 'react'
44

55
import {
6+
eachWeekOfInterval,
7+
eachDayOfInterval,
68
format,
79
isSameMonth,
810
isSameDay,
@@ -48,19 +50,22 @@ const MonthView = memo(function MonthView({
4850
}, [counts])
4951

5052
const weeks = useMemo(() => {
51-
const gridStart = startOfWeek(startOfMonth(month), { weekStartsOn: 0 })
52-
const gridEnd = endOfWeek(endOfMonth(month), { weekStartsOn: 0 })
53-
const newWeeks: Date[][] = []
54-
let cursor = gridStart
55-
while (cursor <= gridEnd) {
56-
const days: Date[] = []
57-
for (let i = 0; i < 7; i++) {
58-
days.push(cursor)
59-
cursor = addDays(cursor, 1)
60-
}
61-
newWeeks.push(days)
62-
}
63-
return newWeeks
53+
const monthStart = startOfMonth(month)
54+
const monthEnd = endOfMonth(month)
55+
const gridStart = startOfWeek(monthStart, { weekStartsOn: 0 })
56+
const gridEnd = endOfWeek(monthEnd, { weekStartsOn: 0 })
57+
58+
const weekStarts = eachWeekOfInterval(
59+
{ start: gridStart, end: gridEnd },
60+
{ weekStartsOn: 0 },
61+
)
62+
63+
return weekStarts.map((weekStart) =>
64+
eachDayOfInterval({
65+
start: weekStart,
66+
end: addDays(weekStart, 6),
67+
}),
68+
)
6469
}, [month])
6570

6671
return (
@@ -87,7 +92,7 @@ const MonthView = memo(function MonthView({
8792
!isCurrent && styles['empty'],
8893
isFuture && styles['disabled'],
8994
isSelected && styles['selected'],
90-
!showStamps && styles['is-picker']
95+
!showStamps && styles['is-picker'],
9196
)}
9297
onClick={() => {
9398
if (!isCurrent || isFuture || isReadOnly) return

src/components/commons/exerciseCalendar/monthViewWithData.tsx

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
'use client'
22

3-
import { useQueryState } from 'nuqs'
4-
import useSWR from 'swr'
5-
import { format, isSameMonth, startOfMonth, endOfMonth } from 'date-fns'
6-
7-
import { useReadExerciseRange } from '@/hooks/api/useExerciseApi'
8-
import { useReadMemberExerciseRange } from '@/hooks/api/useMemberApi'
9-
import { ExerciseRange } from '@/types/exercise'
3+
import { useExerciseCalendarData } from '@/hooks/useExerciseCalendar'
104

115
import MonthView from './monthView'
126
import styles from './monthViewWithData.module.css'
@@ -20,6 +14,7 @@ type Props = {
2014
isReadOnly: boolean
2115
isOthers: boolean
2216
showStamps: boolean
17+
memberId?: string
2318
}
2419

2520
const MonthViewWithData = ({
@@ -31,38 +26,16 @@ const MonthViewWithData = ({
3126
isReadOnly,
3227
isOthers,
3328
showStamps,
29+
memberId,
3430
}: Props) => {
35-
const isFutureMonth = monthToShow.getTime() > startOfMonth(today).getTime()
36-
const shouldFetch = !isFutureMonth && isActive && showStamps
37-
const startDate = format(startOfMonth(monthToShow), 'yyyy-MM-dd')
38-
const endDate = isSameMonth(monthToShow, today)
39-
? format(today, 'yyyy-MM-dd')
40-
: format(endOfMonth(monthToShow), 'yyyy-MM-dd')
41-
const [memberId] = useQueryState('memberId')
42-
const { data: myData } = useReadExerciseRange(
43-
startDate,
44-
endDate,
45-
shouldFetch && !isOthers,
46-
)
47-
const { data: othersData } = useReadMemberExerciseRange(
48-
memberId!,
49-
startDate,
50-
endDate,
51-
shouldFetch && isOthers,
52-
)
53-
const fetchedData = isOthers ? othersData : myData
54-
const swrKey = isOthers
55-
? ['member/exerciseRange', memberId, startDate.substring(0, 7)]
56-
: ['exercise/range', startDate.substring(0, 7)]
57-
const { data: cachedData } = useSWR<ExerciseRange[]>(swrKey, null)
58-
const data = fetchedData || cachedData
59-
const counts: Record<string, number> = {}
60-
61-
if (data) {
62-
data.forEach(({ date, record }) => {
63-
counts[date] = record
64-
})
65-
}
31+
const { counts } = useExerciseCalendarData({
32+
monthToShow,
33+
today,
34+
isOthers,
35+
memberId,
36+
isActive,
37+
showStamps,
38+
})
6639

6740
const handleDateClick = (date: Date) => {
6841
if (onDateSelect) {

src/hooks/useExerciseCalendar.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { useMemo } from 'react'
2+
import { format, startOfMonth, endOfMonth, isSameMonth } from 'date-fns'
3+
import useSWR from 'swr'
4+
5+
import { useReadExerciseRange } from '@/hooks/api/useExerciseApi'
6+
import { useReadMemberExerciseRange } from '@/hooks/api/useMemberApi'
7+
import type { ExerciseRange } from '@/types/exercise'
8+
9+
type Props = {
10+
monthToShow: Date
11+
today: Date
12+
isOthers: boolean
13+
memberId?: string
14+
isActive: boolean
15+
showStamps: boolean
16+
}
17+
18+
export const useExerciseCalendarData = ({
19+
monthToShow,
20+
today,
21+
isOthers,
22+
memberId,
23+
isActive,
24+
showStamps,
25+
}: Props) => {
26+
const isFutureMonth = monthToShow.getTime() > startOfMonth(today).getTime()
27+
const startDate = format(startOfMonth(monthToShow), 'yyyy-MM-dd')
28+
const endDate = isSameMonth(monthToShow, today)
29+
? format(today, 'yyyy-MM-dd')
30+
: format(endOfMonth(monthToShow), 'yyyy-MM-dd')
31+
32+
const shouldFetch = !isFutureMonth && isActive && showStamps
33+
34+
const { data: myData } = useReadExerciseRange(
35+
startDate,
36+
endDate,
37+
shouldFetch && !isOthers,
38+
)
39+
const { data: othersData } = useReadMemberExerciseRange(
40+
memberId!,
41+
startDate,
42+
endDate,
43+
shouldFetch && isOthers,
44+
)
45+
46+
const fetchedData = isOthers ? othersData : myData
47+
48+
const swrKey = isOthers
49+
? ['member/exerciseRange', memberId, startDate.substring(0, 7)]
50+
: ['exercise/range', startDate.substring(0, 7)]
51+
52+
const { data: cachedData } = useSWR<ExerciseRange[]>(swrKey, null)
53+
const data = fetchedData || cachedData
54+
55+
const counts = useMemo(() => {
56+
if (!data) return {}
57+
58+
return Object.fromEntries(data.map(({ date, record }) => [date, record]))
59+
}, [data])
60+
61+
return { counts }
62+
}

0 commit comments

Comments
 (0)