Skip to content
Merged
3 changes: 3 additions & 0 deletions src/assets/icons/schedule/schedule_calendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 0 additions & 16 deletions src/features/home/common/schedule/constants/calendar.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
export const WEEKDAY_LABELS = [
'일',
'월',
'화',
'수',
'목',
'금',
'토',
] as const

/** 월요일 시작 주( date-fns weekStartsOn: 1 )와 그리드 열 순서를 맞춤 */
export const WEEKDAY_LABELS_MONDAY_FIRST = [
...WEEKDAY_LABELS.slice(1),
WEEKDAY_LABELS[0],
] as const

export const DATE_KEY_FORMAT = 'yyyy-MM-dd'
export const MONTH_LABEL_FORMAT = 'yyyy년 M월'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,19 @@
import {
addDays,
eachDayOfInterval,
endOfMonth,
endOfWeek,
format,
isSameMonth,
startOfDay,
startOfMonth,
startOfWeek,
} from 'date-fns'
import { addDays, format, startOfDay } from 'date-fns'
import { getCalendarCells } from '@/shared/lib/calendarUtils'
import { useMemo } from 'react'
import {
DATE_KEY_FORMAT,
MONTH_LABEL_FORMAT,
WEEKDAY_LABELS,
} from '@/features/home/common/schedule/constants/calendar'
import { WEEKDAY_LABELS } from '@/shared/constants/calendar'
import { useMonthlyDateCellsState } from '@/features/home/common/schedule/hooks/useMonthlyDateCellsState'
import type {
MonthlyCalendarViewModel,
MonthlyCellInput,
MonthlyDayMetrics,
MonthlyCalendarPropsBase,
} from '@/features/home/common/schedule/types/monthlyCalendar'
import type { CalendarViewData } from '@/features/home/common/schedule/types/calendarView'

function getMonthlyCells(baseDate: Date): MonthlyCellInput[] {
const monthStart = startOfMonth(baseDate)
const monthEnd = endOfMonth(baseDate)
const intervalStart = startOfWeek(monthStart, { weekStartsOn: 0 })
const intervalEnd = endOfWeek(monthEnd, { weekStartsOn: 0 })

return eachDayOfInterval({ start: intervalStart, end: intervalEnd }).map(
date => ({
dateKey: format(date, DATE_KEY_FORMAT),
dayText: format(date, 'd'),
isCurrentMonth: isSameMonth(date, baseDate),
weekDay: date.getDay(),
})
)
}

type MinuteRange = [number, number]

function mergeMinuteRanges(ranges: MinuteRange[]) {
Expand Down Expand Up @@ -116,7 +90,16 @@ export function useMonthlyCalendarViewModel({
workspaceName,
selectedDateKey,
}: MonthlyCalendarPropsBase): MonthlyCalendarViewModel {
const cells = useMemo(() => getMonthlyCells(baseDate), [baseDate])
const cells = useMemo(
() =>
getCalendarCells(baseDate, 0).map(({ date, isCurrentMonth }) => ({
dateKey: format(date, DATE_KEY_FORMAT),
dayText: format(date, 'd'),
isCurrentMonth,
weekDay: date.getDay(),
})),
[baseDate]
)
const selectedKey = selectedDateKey ?? format(baseDate, DATE_KEY_FORMAT)

const dayMetricsByDate = useMemo(() => getDayMetricsByDate(data), [data])
Expand Down
2 changes: 1 addition & 1 deletion src/features/home/common/schedule/types/monthlyCalendar.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { WEEKDAY_LABELS } from '@/features/home/common/schedule/constants/calendar'
import type { WEEKDAY_LABELS } from '@/shared/constants/calendar'
import type { BaseCalendarProps } from '@/features/home/common/schedule/types/calendarBase'

export interface MonthlyCellInput {
Expand Down
2 changes: 1 addition & 1 deletion src/features/home/common/schedule/ui/MonthlyCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export function MonthlyCalendar({
className={layout === 'manager' ? 'mt-5 px-[11px] pb-4' : 'mt-4'}
>
<div className="grid grid-cols-7 text-center">
{weekdayLabels.map((label, index) => (
{weekdayLabels.map((label: string, index: number) => (
<span
key={label}
className={cn(
Expand Down
50 changes: 31 additions & 19 deletions src/features/manager/home/hooks/useWorkerScheduleManageViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,31 @@ const WORKDAY_OPTIONS = ['월', '화', '수', '목', '금', '토', '일'] as con

const DEFAULT_SELECTED_DAYS = ['수', '금']

const DEFAULT_TIME = {
startHour: '00',
startMinute: '00',
endHour: '00',
endMinute: '00',
}
const MOCK_WORKERS = [
{ name: '이름임', role: 'manager' as const },
{ name: '김민준', role: 'staff' as const },
{ name: '박지은', role: 'staff' as const },
{ name: '이수호', role: 'staff' as const },
{ name: '정하나', role: 'manager' as const },
]

export function useWorkerScheduleManageViewModel() {
const [selectedDays, setSelectedDays] = useState<string[]>(
DEFAULT_SELECTED_DAYS
)
const [startHour, setStartHour] = useState('')
const [startMinute, setStartMinute] = useState('')
const [endHour, setEndHour] = useState('')
const [endMinute, setEndMinute] = useState('')
const [selectedWorkerIndex, setSelectedWorkerIndex] = useState(0)

const workTimeRangeLabel = useMemo(
() =>
`${DEFAULT_TIME.startHour}:${DEFAULT_TIME.startMinute} ~ ${DEFAULT_TIME.endHour}:${DEFAULT_TIME.endMinute}`,
[]
)
const workTimeRangeLabel = useMemo(() => {
const sh = startHour || '00'
const sm = startMinute || '00'
const eh = endHour || '00'
const em = endMinute || '00'
return `${sh}:${sm} ~ ${eh}:${em}`
}, [startHour, startMinute, endHour, endMinute])

function toggleDay(day: string) {
setSelectedDays(prev =>
Expand All @@ -29,17 +37,21 @@ export function useWorkerScheduleManageViewModel() {
}

return {
worker: {
name: '이름임',
role: 'manager' as const,
},
worker: MOCK_WORKERS[selectedWorkerIndex],
workers: MOCK_WORKERS,
selectedWorkerIndex,
setSelectedWorkerIndex,
workdayOptions: WORKDAY_OPTIONS,
selectedDays,
workTimeRangeLabel,
startHour: DEFAULT_TIME.startHour,
startMinute: DEFAULT_TIME.startMinute,
endHour: DEFAULT_TIME.endHour,
endMinute: DEFAULT_TIME.endMinute,
startHour,
startMinute,
endHour,
endMinute,
setStartHour,
setStartMinute,
setEndHour,
setEndMinute,
toggleDay,
}
}
2 changes: 2 additions & 0 deletions src/features/manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export { WorkspaceChangeList } from '@/features/manager/home/ui/WorkspaceChangeL
export { WorkspaceChangeCard } from '@/features/manager/home/ui/WorkspaceChangeCard'
export { TodayWorkerList } from '@/features/manager/home/ui/TodayWorkerList'
export { useManagerHomeViewModel } from '@/features/manager/home/hooks/useManagerHomeViewModel'
export type { ScheduleTab } from '@/features/manager/schedule/types/workerSchedule'
export { SCHEDULE_TABS } from '@/features/manager/schedule/constants/workerSchedule'
3 changes: 3 additions & 0 deletions src/features/manager/schedule/constants/workerSchedule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { ScheduleTab } from '@/features/manager/schedule/types/workerSchedule'

export const SCHEDULE_TABS: ScheduleTab[] = ['고정', '일반']
1 change: 1 addition & 0 deletions src/features/manager/schedule/types/workerSchedule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type ScheduleTab = '고정' | '일반'
12 changes: 12 additions & 0 deletions src/features/manager/worker-schedule/types/scheduleColor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const ScheduleColor = {
Pink: '#EB98AD',
Purple: '#9FA4F8',
Blue: '#9EC9FD',
Yellow: '#FCD680',
LightPink: '#F0BFC0',
LightPurple: '#CCBAF9',
Gray: '#C8D2E1',
DarkGray: '#9E9EA3',
} as const

export type ScheduleColor = (typeof ScheduleColor)[keyof typeof ScheduleColor]
2 changes: 1 addition & 1 deletion src/features/user/home/schedule/api/schedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
getDurationHours,
toDateKey,
toTimeLabel,
} from '@/features/user/home/schedule/lib/date'
} from '@/features/home/common/schedule/lib/date'
import type { SelfScheduleQueryParams } from '@/shared/types/schedule'

function mapToCalendarEvent(
Expand Down
3 changes: 0 additions & 3 deletions src/features/user/home/schedule/constants/calendar.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// constants는 common으로 이동 — 하위 호환 re-export
export {
WEEKDAY_LABELS,
WEEKDAY_LABELS_MONDAY_FIRST,
DATE_KEY_FORMAT,
MONTH_LABEL_FORMAT,
DAILY_TIMELINE_HEIGHT,
Expand Down
7 changes: 5 additions & 2 deletions src/features/user/home/schedule/lib/date.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import { StatusEnum } from '@/shared/types/enums'
import {
getDailyHourTicks,
getDayHours,
getDurationHours,
getMonthlyDateCells,
getScheduleParamsByMode,
getWeekRangeLabel,
getWeeklyDateCells,
moveDateByMode,
} from './date'

import {
toDateKey,
toTimeLabel,
} from './date'
getDurationHours,
} from '@/features/home/common/schedule/lib/date'

describe('toDateKey', () => {
it('ISO 문자열에서 날짜 부분만 반환한다', () => {
Expand Down
5 changes: 1 addition & 4 deletions src/features/user/home/schedule/lib/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,13 @@ import type { ScheduleDataDto } from '@/features/user/home/schedule/types/schedu
import type { HomeCalendarMode } from '@/features/user/home/schedule/types/schedule'
import type { SelfScheduleQueryParams } from '@/shared/types/schedule'
import type { ScheduleListItem } from '@/features/user/home/schedule/types/scheduleList'
import { WEEKDAY_LABELS } from '@/features/user/home/schedule/constants/calendar'
import { WEEKDAY_LABELS } from '@/shared/constants/calendar'
import {
toDateKey,
toTimeLabel,
getDurationHours,
} from '@/features/home/common/schedule/lib/date'
Comment on lines +17 to 22
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

아키텍처 위반: features 간 의존성 (세 번째 발생)

Line 17의 @/shared/constants/calendar import는 올바르지만, lines 18-22의 @/features/home/common/schedule/lib/date import는 동일한 아키텍처 위반입니다.

여러 파일에서 반복되는 패턴으로 보아, toDateKey, toTimeLabel, getDurationHourssrc/shared/lib로 이동하는 것이 이 PR의 리팩토링 범위에 포함되어야 합니다.

As per coding guidelines: features 레이어는 entities, shared 레이어만 import해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/user/home/schedule/lib/date.ts` around lines 17 - 22, This file
imports toDateKey, toTimeLabel, and getDurationHours from another feature
(violating architecture); move those utility functions into the shared layer
(e.g., src/shared/lib or equivalent) and update imports in this file to import
from the shared lib (use '@/shared/lib/<module>' or your project's shared path);
ensure you relocate the implementations for toDateKey, toTimeLabel,
getDurationHours, update any other files that import them to the new shared
location, and run tests/TS build to fix any path/type issues.


// 순수 날짜 유틸은 common으로 이동 — 하위 호환 re-export
export { toDateKey, toTimeLabel, getDurationHours }

export function getMonthlyDateCells(baseDate: Date) {
const monthStart = startOfMonth(baseDate)
const monthEnd = endOfMonth(baseDate)
Expand Down
6 changes: 3 additions & 3 deletions src/features/user/home/workspace/api/workspaceSchedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import type {
CalendarViewData,
} from '@/features/user/home/schedule/types/schedule'
import {
getDurationHours,
toDateKey,
toTimeLabel,
getDurationHours,
formatScheduleTimeRange,
} from '@/features/user/home/schedule/lib/date'
} from '@/features/home/common/schedule/lib/date'
import { formatScheduleTimeRange } from '@/features/user/home/schedule/lib/date'
Comment on lines 6 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

아키텍처 위반: features 간 의존성 (동일 이슈)

@/features/home/common/schedule/lib/date에서 import - 앞서 schedule/api/schedule.ts와 동일한 아키텍처 위반입니다.

해당 유틸리티들을 src/shared/lib로 이동하고 모든 features에서 shared 레이어를 참조하도록 수정해주세요.

As per coding guidelines: features 레이어는 entities, shared 레이어만 import해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/user/home/workspace/api/workspaceSchedule.ts` around lines 6 -
11, The imports getDurationHours, toDateKey, toTimeLabel and
formatScheduleTimeRange are coming from another feature layer which violates the
architecture; move the shared scheduling utilities into the shared layer (e.g.,
src/shared/lib scheduling/date helpers) and update all feature imports
(including references in workspaceSchedule.ts and schedule/api/schedule.ts) to
import getDurationHours, toDateKey, toTimeLabel and formatScheduleTimeRange from
the new shared module so features only depend on shared/entities.

import type {
WorkspaceScheduleApiResponse,
WorkspaceScheduleQueryParams,
Expand Down
Loading
Loading