Skip to content
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react'
import { useInfiniteQuery } from '@tanstack/react-query'
import { fetchManagedPostings } from '@/features/manager/home/api/posting'
import { fetchManagedPostings } from '@/features/manager/api/posting'
import { adaptPostingDto } from '@/features/manager/home/types/posting'
import { queryKeys } from '@/shared/lib/queryKeys'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { fetchManagedWorkspaces } from '@/features/manager/home/api/workspace'
import { fetchManagedWorkspaces } from '@/features/manager/api/workspace'
import { useWorkspaceStore } from '@/shared/stores/useWorkspaceStore'
import { queryKeys } from '@/shared/lib/queryKeys'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useMemo, useState } from 'react'
import { addMonths, format } from 'date-fns'
import { useQuery } from '@tanstack/react-query'
import { fetchMonthlySchedules } from '@/features/manager/home/api/schedule'
import { fetchMonthlySchedules } from '@/features/manager/api/schedule'
import type {
ManagerScheduleApiResponse,
ManagerScheduleShiftDto,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react'
import { useInfiniteQuery } from '@tanstack/react-query'
import { fetchSubstituteRequests } from '@/features/manager/home/api/substitute'
import { fetchSubstituteRequests } from '@/features/manager/api/substitute'
import { adaptSubstituteRequestDto } from '@/features/manager/home/types/substitute'
import { queryKeys } from '@/shared/lib/queryKeys'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { fetchTodaySchedules } from '@/features/manager/home/api/schedule'
import { fetchTodaySchedules } from '@/features/manager/api/schedule'
import { queryKeys } from '@/shared/lib/queryKeys'
import { formatIsoTimeRangeLabel } from '@/features/home/common/schedule/lib/date'
import type { TodayWorkerItem } from '@/features/manager/home/ui/TodayWorkerList'
Expand Down
2 changes: 1 addition & 1 deletion src/features/manager/home/hooks/useWorkspaceDetailQuery.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { fetchWorkspaceDetail } from '@/features/manager/home/api/workspace'
import { fetchWorkspaceDetail } from '@/features/manager/api/workspace'
import { queryKeys } from '@/shared/lib/queryKeys'

export function useWorkspaceDetailQuery(workspaceId: number | null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useMemo } from 'react'
import { useInfiniteQuery } from '@tanstack/react-query'
import { fetchWorkspaceWorkers } from '@/features/manager/home/api/worker'
import { fetchWorkspaceWorkers } from '@/features/manager/api/worker'
import { adaptWorkerDto } from '@/features/manager/home/lib/worker'
import { queryKeys } from '@/shared/lib/queryKeys'

const PAGE_SIZE = 20
const PAGE_SIZE = 50

export function useWorkspaceWorkersViewModel(
workspaceId: number | null,
Expand Down
1 change: 1 addition & 0 deletions src/features/manager/home/types/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface WorkerDto {
user: WorkerUserDto
status: WorkerStatusDto
position: WorkerPositionDto
colorCode: string
employedAt: string
resignedAt: string | null
nextShiftDateTime: string | null
Expand Down
15 changes: 15 additions & 0 deletions src/features/manager/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
export {
getFixedWorkerSchdules,
postFixedWorkerSchdules,
deleteFixedWorkerSchdule,
patchFixedWorkerSchdule,
} from '@/features/manager/worker-schedule/api/fixedWorkerSchdule'
export type {
ResponseGetFixedWorkerSchdules,
RequestPostFixedWorkerSchdules,
ResponsePostFixedWorkerSchdules,
ResponseDeleteFixedWorkerSchdules,
RequestPatchFixedWorkerSchdules,
} from '@/features/manager/worker-schedule/types/fixedWorkerSchdules'
export { StoreWorkerListItem } from '@/features/manager/home/ui/StoreWorkerListItem'
export { WorkspaceChangeList } from '@/features/manager/home/ui/WorkspaceChangeList'
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 { useWorkerScheduleManageViewModel } from '@/features/manager/worker-schedule/hooks/useWorkerScheduleManageViewModel'
export { ScheduleColor } from '@/features/manager/worker-schedule/types/scheduleColor'
export type { ScheduleTab } from '@/features/manager/schedule/types/workerSchedule'
export { SCHEDULE_TABS } from '@/features/manager/schedule/constants/workerSchedule'
50 changes: 50 additions & 0 deletions src/features/manager/worker-schedule/api/fixedWorkerSchdule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import axiosInstance from '@/shared/lib/axiosInstance'
import type {
ResponseGetFixedWorkerSchdules,
RequestPostFixedWorkerSchdules,
ResponsePostFixedWorkerSchdules,
ResponseDeleteFixedWorkerSchdules,
RequestPatchFixedWorkerSchdules,
} from '@/features/manager'

export async function getFixedWorkerSchdules(
workspaceId: number
): Promise<ResponseGetFixedWorkerSchdules> {
const response = await axiosInstance.get<ResponseGetFixedWorkerSchdules>(
`/manager/workspaces/${workspaceId}/fixed-worker-schedules`
)
return response.data
}

export async function postFixedWorkerSchdules(
workspaceId: number,
body: RequestPostFixedWorkerSchdules
): Promise<ResponsePostFixedWorkerSchdules> {
const response = await axiosInstance.post<ResponsePostFixedWorkerSchdules>(
`/manager/workspaces/${workspaceId}/fixed-worker-schedules`,
body
)
return response.data
}

export async function deleteFixedWorkerSchdule(
workspaceId: number,
workerScheduleId: number
): Promise<ResponseDeleteFixedWorkerSchdules> {
const response =
await axiosInstance.delete<ResponseDeleteFixedWorkerSchdules>(
`/manager/workspaces/${workspaceId}/fixed-worker-schedules/${workerScheduleId}`
)
return response.data
}

export async function patchFixedWorkerSchdule(
workspaceId: number,
workerScheduleId: number,
body: RequestPatchFixedWorkerSchdules
): Promise<void> {
await axiosInstance.patch(
`/manager/workspaces/${workspaceId}/fixed-worker-schedules/${workerScheduleId}`,
body
)
}
3 changes: 3 additions & 0 deletions src/features/manager/worker-schedule/hooks/mutation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { useCreateFixedWorkerSchedule } from './useCreateFixedWorkerSchedule'
export { useUpdateFixedWorkerSchedule } from './useUpdateFixedWorkerSchedule'
export { useDeleteFixedWorkerSchedule } from './useDeleteFixedWorkerSchedule'
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { postFixedWorkerSchdules } from '@/features/manager/worker-schedule/api/fixedWorkerSchdule'
import { queryKeys } from '@/shared/lib/queryKeys'
import type { RequestPostFixedWorkerSchdules } from '@/features/manager/worker-schedule/types/fixedWorkerSchdules'

export function useCreateFixedWorkerSchedule(workspaceId: number) {
const queryClient = useQueryClient()

return useMutation({
mutationFn: (body: RequestPostFixedWorkerSchdules) =>
postFixedWorkerSchdules(workspaceId, body),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: queryKeys.fixedWorkerSchedule.list(workspaceId),
})
},
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { deleteFixedWorkerSchdule } from '@/features/manager/worker-schedule/api/fixedWorkerSchdule'
import { queryKeys } from '@/shared/lib/queryKeys'

export function useDeleteFixedWorkerSchedule(workspaceId: number) {
const queryClient = useQueryClient()

return useMutation({
mutationFn: (workerScheduleId: number) =>
deleteFixedWorkerSchdule(workspaceId, workerScheduleId),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: queryKeys.fixedWorkerSchedule.list(workspaceId),
})
},
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { patchFixedWorkerSchdule } from '@/features/manager/worker-schedule/api/fixedWorkerSchdule'
import { queryKeys } from '@/shared/lib/queryKeys'
import type { RequestPatchFixedWorkerSchdules } from '@/features/manager/worker-schedule/types/fixedWorkerSchdules'

interface UpdateFixedWorkerScheduleParams {
workerScheduleId: number
body: RequestPatchFixedWorkerSchdules
}

export function useUpdateFixedWorkerSchedule(workspaceId: number) {
const queryClient = useQueryClient()

return useMutation({
mutationFn: ({ workerScheduleId, body }: UpdateFixedWorkerScheduleParams) =>
patchFixedWorkerSchdule(workspaceId, workerScheduleId, body),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: queryKeys.fixedWorkerSchedule.list(workspaceId),
})
},
})
}
2 changes: 2 additions & 0 deletions src/features/manager/worker-schedule/hooks/query/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { useWorkspaceWorkers } from './useWorkspaceWorkers'
export { useFixedWorkerSchedules } from './useFixedWorkerSchedules'
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useQuery } from '@tanstack/react-query'
import { getFixedWorkerSchdules } from '@/features/manager/worker-schedule/api/fixedWorkerSchdule'
import { queryKeys } from '@/shared/lib/queryKeys'

export function useFixedWorkerSchedules(workspaceId: number) {
return useQuery({
queryKey: queryKeys.fixedWorkerSchedule.list(workspaceId),
queryFn: () => getFixedWorkerSchdules(workspaceId),
enabled: !!workspaceId,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useQuery } from '@tanstack/react-query'
import { fetchWorkspaceWorkers } from '@/features/manager/api/worker'
import { queryKeys } from '@/shared/lib/queryKeys'
import type { WorkersApiResponse } from '@/features/manager/home/types/worker'

const PAGE_SIZE = 50

interface UseWorkspaceWorkersParams {
workspaceId?: number
status?: string
name?: string
}

export function useWorkspaceWorkers({
workspaceId,
status,
name,
}: UseWorkspaceWorkersParams) {
return useQuery<WorkersApiResponse>({
queryKey: queryKeys.managerWorkspace.workers(workspaceId ?? 0, {
status,
name,
pageSize: PAGE_SIZE,
}),
queryFn: () =>
fetchWorkspaceWorkers({
workspaceId: workspaceId ?? 0,
pageSize: PAGE_SIZE,
status,
name,
}),
enabled: !!workspaceId,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import { splitClockToParts } from '@/features/home/common/schedule/lib/date'
import { fetchWorkerFixedSchedules } from '@/features/manager/home/api/workerFixedSchedule'
import { fetchWorkerFixedSchedules } from '@/features/manager/worker-schedule/api/workerFixedSchedule'
import { MANAGER_WEEKDAY_KO_ORDER } from '@/features/manager/home/constants/managerWeekdayKo'
import type { ManagerWeekdayKo } from '@/features/manager/home/constants/managerWeekdayKo'
import { mapFixedScheduleSlotsToByWeekdayKo } from '@/features/manager/home/lib/mapWorkerFixedScheduleSlots'
Expand Down Expand Up @@ -138,23 +138,25 @@ export function useWorkerScheduleManageViewModel(args: {
}

return {
workersLoading,
worker,
workers,
workersLoading,
fixedScheduleLoading,
fixedScheduleError,
goToWorker,
workdayOptions: MANAGER_WEEKDAY_KO_ORDER,
selectedDays,
workTimeRangeLabel,
startHour,
startMinute,
endHour,
endMinute,
setStartHour,
setStartMinute,
setEndHour,
setEndMinute,
toggleDay,
workTime: {
rangeLabel: workTimeRangeLabel,
startHour,
startMinute,
endHour,
endMinute,
setStartHour,
setStartMinute,
setEndHour,
setEndMinute,
},
}
}
40 changes: 40 additions & 0 deletions src/features/manager/worker-schedule/types/fixedWorkerSchdules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { CommonApiResponse } from '@/shared/types/common'

export type ResponseGetFixedWorkerSchdules = CommonApiResponse<{
id: number
workspaceWorkerId: number
startDayofWeek: string
startTime: string
endDayOfWeek: string
endTime: string
status: string
}>

export type RequestPostFixedWorkerSchdules = {
workspaceId: number
schedules: {
startDayOfWeek: string
startTime: string
endDayOfWeek: string
endTime: string
}
}

export type ResponsePostFixedWorkerSchdules = {
timestamp?: string
data?: object
code?: string
}

export type ResponseDeleteFixedWorkerSchdules = {
timestamp?: string
data?: object
code?: string
}

export type RequestPatchFixedWorkerSchdules = {
startDayOfWeek: string
startTime: string
endDayOfWeek: string
endTime: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { ReactNode } from 'react'
import chevronDownIcon from '@/assets/icons/home/chevron-down.svg'
import { cn } from '@/shared/lib/utils'

interface CollapsibleScheduleSectionProps {
title: string
icon?: ReactNode
isOpen: boolean
onToggle: () => void
children: ReactNode
className?: string
}

export function CollapsibleScheduleSection({
title,
icon,
isOpen,
onToggle,
children,
className,
}: CollapsibleScheduleSectionProps) {
return (
<section className={cn('flex flex-col gap-2.5', className)}>
<button
type="button"
onClick={onToggle}
className="flex h-12 w-full items-center rounded-2xl bg-white px-4"
aria-expanded={isOpen}
>
<div className="flex min-w-0 flex-1 items-center gap-1.5">
<span className="typography-headline03 text-text-100">{title}</span>
{icon}
</div>
<img
src={chevronDownIcon}
alt=""
aria-hidden="true"
className={cn('size-6 transition-transform', isOpen && 'rotate-180')}
/>
</button>
{isOpen ? children : null}
</section>
)
}
Loading
Loading