From 040122290671fccfd0e355962e8e224738d499d0 Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 27 May 2026 18:11:12 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=EC=82=AC=EC=9E=A5=EB=8B=98=20?= =?UTF-8?q?=EC=83=81=EB=8B=A8=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/types/managerHomeLocationState.ts | 3 -- .../hooks/useWorkerScheduleManageViewModel.ts | 8 +---- src/pages/manager/home/index.tsx | 31 +------------------ 3 files changed, 2 insertions(+), 40 deletions(-) delete mode 100644 src/features/manager/home/types/managerHomeLocationState.ts diff --git a/src/features/manager/home/types/managerHomeLocationState.ts b/src/features/manager/home/types/managerHomeLocationState.ts deleted file mode 100644 index e4aba25..0000000 --- a/src/features/manager/home/types/managerHomeLocationState.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type ManagerHomeLocationState = { - workerScheduleSaveSuccess?: boolean -} diff --git a/src/features/manager/worker-schedule/hooks/useWorkerScheduleManageViewModel.ts b/src/features/manager/worker-schedule/hooks/useWorkerScheduleManageViewModel.ts index e56dded..d26549f 100644 --- a/src/features/manager/worker-schedule/hooks/useWorkerScheduleManageViewModel.ts +++ b/src/features/manager/worker-schedule/hooks/useWorkerScheduleManageViewModel.ts @@ -19,7 +19,6 @@ import { invalidateManagerScheduleQueries } from '@/features/manager/worker-sche import { saveFixedWorkerSchedules } from '@/features/manager/worker-schedule/lib/saveFixedWorkerSchedules' import { saveGeneralWorkerSchedule } from '@/features/manager/worker-schedule/lib/saveGeneralWorkerSchedule' import { dateTimeToHourMinute } from '@/features/manager/worker-schedule/lib/scheduleDateTime' -import type { ManagerHomeLocationState } from '@/features/manager/home/types/managerHomeLocationState' import { ROUTES, managerWorkerSchedulePath } from '@/shared/constants/routes' import { queryKeys } from '@/shared/lib/queryKeys' import { getAxiosErrorMessage } from '@/shared/lib/getAxiosErrorMessage' @@ -417,12 +416,7 @@ export function useWorkerScheduleManageViewModel(args: { if (onSaveSuccess) { onSaveSuccess() } else { - navigate(ROUTES.MANAGER.HOME, { - replace: true, - state: { - workerScheduleSaveSuccess: true, - } satisfies ManagerHomeLocationState, - }) + navigate(ROUTES.MANAGER.HOME, { replace: true }) } }, onError: async (error: unknown) => { diff --git a/src/pages/manager/home/index.tsx b/src/pages/manager/home/index.tsx index e196830..3cc56b3 100644 --- a/src/pages/manager/home/index.tsx +++ b/src/pages/manager/home/index.tsx @@ -1,9 +1,7 @@ -import { useEffect, useRef } from 'react' import { format } from 'date-fns' import { ko } from 'date-fns/locale' import { Navbar } from '@/shared/ui/common/Navbar' -import { useLocation, useNavigate } from 'react-router-dom' -import type { ManagerHomeLocationState } from '@/features/manager/home/types/managerHomeLocationState' +import { useNavigate } from 'react-router-dom' import { TodayWorkerList, StoreWorkerListItem, @@ -23,16 +21,9 @@ import { shouldShowInfiniteListLoadMore } from '@/shared/lib/listLoadMoreVisibil import { ROUTES, managerWorkerSchedulePath } from '@/shared/constants/routes' const STORE_WORKERS_SECTION_ID = 'manager-store-workers' -const SCHEDULE_SAVE_SUCCESS_MESSAGE = '스케줄이 성공적으로 저장되었습니다.' export function ManagerHomePage() { const navigate = useNavigate() - const location = useLocation() - const scheduleSaveScrollHandled = useRef(false) - - const navigationState = location.state as ManagerHomeLocationState | null - const showScheduleSaveSuccess = - navigationState?.workerScheduleSaveSuccess === true const { todayWorkers, storeWorkers, @@ -57,30 +48,10 @@ export function ManagerHomePage() { selectWorkspace, } = useManagerHomeViewModel() - useEffect(() => { - if (!showScheduleSaveSuccess || scheduleSaveScrollHandled.current) return - - scheduleSaveScrollHandled.current = true - requestAnimationFrame(() => { - document - .getElementById(STORE_WORKERS_SECTION_ID) - ?.scrollIntoView({ behavior: 'smooth', block: 'start' }) - }) - }, [showScheduleSaveSuccess]) - return (
- {showScheduleSaveSuccess ? ( -

- {SCHEDULE_SAVE_SUCCESS_MESSAGE} -

- ) : null} -
Date: Wed, 27 May 2026 18:21:39 +0900 Subject: [PATCH 02/11] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9E=A5=EB=8B=98?= =?UTF-8?q?=20=EB=A9=94=EC=9D=B8=20=EB=8D=94=EB=B3=B4=EA=B8=B0=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20UX=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/home/hooks/useManagedPostingsViewModel.ts | 9 ++++----- .../manager/home/hooks/useManagerHomeViewModel.ts | 6 +++--- .../manager/home/hooks/useSubstituteRequestsViewModel.ts | 9 ++++----- .../manager/home/hooks/useWorkspaceWorkersViewModel.ts | 9 ++++----- src/shared/ui/manager/OngoingPostingCard.tsx | 8 +++++--- src/shared/ui/manager/SubstituteApprovalCard.tsx | 8 +++++--- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/features/manager/home/hooks/useManagedPostingsViewModel.ts b/src/features/manager/home/hooks/useManagedPostingsViewModel.ts index f9514ef..dec10da 100644 --- a/src/features/manager/home/hooks/useManagedPostingsViewModel.ts +++ b/src/features/manager/home/hooks/useManagedPostingsViewModel.ts @@ -4,11 +4,10 @@ import { fetchManagedPostings } from '@/features/manager/api/posting' import { adaptPostingDto } from '@/features/manager/home/types/posting' import { queryKeys } from '@/shared/lib/queryKeys' -const PAGE_SIZE = 10 - export function useManagedPostingsViewModel( workspaceId: number | null, - params?: { status?: string } + params?: { status?: string }, + pageSize = 10 ) { const { data, @@ -21,11 +20,11 @@ export function useManagedPostingsViewModel( queryKey: queryKeys.posting.list({ workspaceId: workspaceId ?? undefined, status: params?.status, - pageSize: PAGE_SIZE, + pageSize, }), queryFn: ({ pageParam }) => fetchManagedPostings({ - pageSize: PAGE_SIZE, + pageSize, workspaceId: workspaceId ?? undefined, status: params?.status, cursor: pageParam as string | undefined, diff --git a/src/features/manager/home/hooks/useManagerHomeViewModel.ts b/src/features/manager/home/hooks/useManagerHomeViewModel.ts index 98e640c..0bf8796 100644 --- a/src/features/manager/home/hooks/useManagerHomeViewModel.ts +++ b/src/features/manager/home/hooks/useManagerHomeViewModel.ts @@ -22,21 +22,21 @@ export function useManagerHomeViewModel() { fetchNextPage: fetchMoreWorkers, hasNextPage: hasMoreWorkers, isFetchingNextPage: isFetchingMoreWorkers, - } = useWorkspaceWorkersViewModel(activeWorkspaceId) + } = useWorkspaceWorkersViewModel(activeWorkspaceId, undefined, 3) const { postings: ongoingPostings, totalCount: postingsTotalCount, fetchNextPage: fetchMorePostings, hasNextPage: hasMorePostings, - } = useManagedPostingsViewModel(activeWorkspaceId, { status: 'OPEN' }) + } = useManagedPostingsViewModel(activeWorkspaceId, { status: 'OPEN' }, 3) const { requests: substituteRequests, totalCount: substituteTotalCount, fetchNextPage: fetchMoreSubstitutes, hasNextPage: hasMoreSubstitutes, - } = useSubstituteRequestsViewModel(activeWorkspaceId) + } = useSubstituteRequestsViewModel(activeWorkspaceId, undefined, 3) const { baseDate: scheduleBaseDate, diff --git a/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts b/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts index 196ca3f..c65bb09 100644 --- a/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts +++ b/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts @@ -4,11 +4,10 @@ import { fetchSubstituteRequests } from '@/features/manager/api/substitute' import { adaptSubstituteRequestDto } from '@/features/manager/home/types/substitute' import { queryKeys } from '@/shared/lib/queryKeys' -const PAGE_SIZE = 10 - export function useSubstituteRequestsViewModel( workspaceId: number | null, - params?: { status?: string } + params?: { status?: string }, + pageSize = 10 ) { const { data, @@ -21,11 +20,11 @@ export function useSubstituteRequestsViewModel( queryKey: queryKeys.substitute.list({ workspaceId: workspaceId ?? undefined, status: params?.status, - pageSize: PAGE_SIZE, + pageSize, }), queryFn: ({ pageParam }) => fetchSubstituteRequests({ - pageSize: PAGE_SIZE, + pageSize, workspaceId: workspaceId ?? undefined, status: params?.status, cursor: pageParam as string | undefined, diff --git a/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts b/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts index 8606924..a907cde 100644 --- a/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts +++ b/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts @@ -4,11 +4,10 @@ import { fetchWorkspaceWorkers } from '@/features/manager/api/worker' import { adaptWorkerDto } from '@/features/manager/home/lib/worker' import { queryKeys } from '@/shared/lib/queryKeys' -const PAGE_SIZE = 50 - export function useWorkspaceWorkersViewModel( workspaceId: number | null, - params?: { status?: string; name?: string } + params?: { status?: string; name?: string }, + pageSize = 50 ) { const { data, @@ -21,12 +20,12 @@ export function useWorkspaceWorkersViewModel( queryKey: queryKeys.managerWorkspace.workers(workspaceId ?? 0, { status: params?.status, name: params?.name, - pageSize: PAGE_SIZE, + pageSize, }), queryFn: ({ pageParam }) => fetchWorkspaceWorkers({ workspaceId: workspaceId!, - pageSize: PAGE_SIZE, + pageSize, cursor: pageParam as string | undefined, status: params?.status, name: params?.name, diff --git a/src/shared/ui/manager/OngoingPostingCard.tsx b/src/shared/ui/manager/OngoingPostingCard.tsx index bdd1a61..8c96f09 100644 --- a/src/shared/ui/manager/OngoingPostingCard.tsx +++ b/src/shared/ui/manager/OngoingPostingCard.tsx @@ -119,9 +119,11 @@ export function OngoingPostingCard({ /> ))}
-
- -
+ {onViewMore && ( +
+ +
+ )}
) } diff --git a/src/shared/ui/manager/SubstituteApprovalCard.tsx b/src/shared/ui/manager/SubstituteApprovalCard.tsx index 1dcc644..4427cdf 100644 --- a/src/shared/ui/manager/SubstituteApprovalCard.tsx +++ b/src/shared/ui/manager/SubstituteApprovalCard.tsx @@ -98,9 +98,11 @@ export function SubstituteApprovalCard({ /> ))} -
- -
+ {onViewMore && ( +
+ +
+ )} ) } From 0c7f1741be300de27987d29469516566be60e6bc Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 27 May 2026 18:22:41 +0900 Subject: [PATCH 03/11] =?UTF-8?q?refactor:=20=EA=B0=81=20=EC=84=B9?= =?UTF-8?q?=EC=85=98=EC=97=90=20=EC=95=84=EC=9D=B4=ED=85=9C=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20UI=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/manager/home/index.tsx | 48 +++++++++++-------- src/shared/ui/manager/OngoingPostingCard.tsx | 36 ++++++++------ .../ui/manager/SubstituteApprovalCard.tsx | 36 ++++++++------ 3 files changed, 71 insertions(+), 49 deletions(-) diff --git a/src/pages/manager/home/index.tsx b/src/pages/manager/home/index.tsx index 3cc56b3..ee17af6 100644 --- a/src/pages/manager/home/index.tsx +++ b/src/pages/manager/home/index.tsx @@ -216,27 +216,33 @@ export function ManagerHomePage() {
-
- {storeWorkers.map(worker => ( - {}} - /> - ))} - {shouldShowInfiniteListLoadMore( - hasMoreWorkers, - storeWorkersTotalCount - ) && ( - fetchMoreWorkers()} - disabled={isFetchingMoreWorkers} - /> - )} -
+ {storeWorkers.length === 0 ? ( +

+ 근무자가 없습니다 +

+ ) : ( +
+ {storeWorkers.map(worker => ( + {}} + /> + ))} + {shouldShowInfiniteListLoadMore( + hasMoreWorkers, + storeWorkersTotalCount + ) && ( + fetchMoreWorkers()} + disabled={isFetchingMoreWorkers} + /> + )} +
+ )}
diff --git a/src/shared/ui/manager/OngoingPostingCard.tsx b/src/shared/ui/manager/OngoingPostingCard.tsx index 8c96f09..1d72af0 100644 --- a/src/shared/ui/manager/OngoingPostingCard.tsx +++ b/src/shared/ui/manager/OngoingPostingCard.tsx @@ -109,20 +109,28 @@ export function OngoingPostingCard({ }: OngoingPostingCardProps) { return (
-
- {postings.map((posting, index) => ( - onPostingClick?.(posting)} - isLast={index === postings.length - 1} - /> - ))} -
- {onViewMore && ( -
- -
+ {postings.length === 0 ? ( +

+ 진행 중인 공고가 없습니다 +

+ ) : ( + <> +
+ {postings.map((posting, index) => ( + onPostingClick?.(posting)} + isLast={index === postings.length - 1} + /> + ))} +
+ {onViewMore && ( +
+ +
+ )} + )}
) diff --git a/src/shared/ui/manager/SubstituteApprovalCard.tsx b/src/shared/ui/manager/SubstituteApprovalCard.tsx index 4427cdf..9d2d389 100644 --- a/src/shared/ui/manager/SubstituteApprovalCard.tsx +++ b/src/shared/ui/manager/SubstituteApprovalCard.tsx @@ -88,20 +88,28 @@ export function SubstituteApprovalCard({ }: SubstituteApprovalCardProps) { return (
-
- {requests.map((item, index) => ( - onRequestClick?.(item)} - isLast={index === requests.length - 1} - /> - ))} -
- {onViewMore && ( -
- -
+ {requests.length === 0 ? ( +

+ 대타 승인 요청이 없습니다 +

+ ) : ( + <> +
+ {requests.map((item, index) => ( + onRequestClick?.(item)} + isLast={index === requests.length - 1} + /> + ))} +
+ {onViewMore && ( +
+ +
+ )} + )}
) From 61ebab19b6e5ae68eaaa16011862eb679ffa103e Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 27 May 2026 18:27:00 +0900 Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20=EB=8D=94=EB=B3=B4=EA=B8=B0?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/manager/home/index.tsx | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/pages/manager/home/index.tsx b/src/pages/manager/home/index.tsx index ee17af6..69c7b7b 100644 --- a/src/pages/manager/home/index.tsx +++ b/src/pages/manager/home/index.tsx @@ -17,7 +17,6 @@ import managerHomeBannerImage from '@/assets/manager-home-banner.jpg' import managerHomeBannerPlusIcon from '@/assets/icons/home/manager-home-banner-plus.svg' import managerWorkspaceModalPlusIcon from '@/assets/icons/home/manager-workspace-modal-plus.svg' import managerScheduleEditIcon from '@/assets/icons/home/edit.svg' -import { shouldShowInfiniteListLoadMore } from '@/shared/lib/listLoadMoreVisibility' import { ROUTES, managerWorkerSchedulePath } from '@/shared/constants/routes' const STORE_WORKERS_SECTION_ID = 'manager-store-workers' @@ -29,16 +28,13 @@ export function ManagerHomePage() { storeWorkers, storeWorkersTotalCount, fetchMoreWorkers, - hasMoreWorkers, isFetchingMoreWorkers, ongoingPostings, postingsTotalCount, fetchMorePostings, - hasMorePostings, substituteRequests, substituteTotalCount, fetchMoreSubstitutes, - hasMoreSubstitutes, schedule, activeWorkspaceId, workspaceDetail, @@ -232,10 +228,7 @@ export function ManagerHomePage() { onOptions={() => {}} /> ))} - {shouldShowInfiniteListLoadMore( - hasMoreWorkers, - storeWorkersTotalCount - ) && ( + {storeWorkers.length < storeWorkersTotalCount && ( fetchMoreWorkers()} disabled={isFetchingMoreWorkers} @@ -254,10 +247,7 @@ export function ManagerHomePage() { fetchMorePostings() : undefined } @@ -274,10 +264,7 @@ export function ManagerHomePage() { fetchMoreSubstitutes() : undefined } From 9a01a03d12577dfbecdac3b81c01c3dbeaa20c4e Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 27 May 2026 18:32:17 +0900 Subject: [PATCH 05/11] =?UTF-8?q?refactor:=20=EC=98=A4=EB=8A=98=20?= =?UTF-8?q?=EA=B7=BC=EB=AC=B4=EC=9E=90=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B5=9C=EC=86=8C=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=EC=A7=80=EC=A0=95=20=EB=B0=8F=200?= =?UTF-8?q?=EB=AA=85=EC=9D=BC=20=EB=95=8C=20=EB=AC=B8=EA=B5=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/home/ui/TodayWorkerList.tsx | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/features/manager/home/ui/TodayWorkerList.tsx b/src/features/manager/home/ui/TodayWorkerList.tsx index 97acd74..dde39b7 100644 --- a/src/features/manager/home/ui/TodayWorkerList.tsx +++ b/src/features/manager/home/ui/TodayWorkerList.tsx @@ -42,12 +42,20 @@ export function TodayWorkerList({ 오늘 근무자는 {workers.length}명이에요 -
-
- {workers.map(worker => ( - - ))} -
+
+ {workers.length === 0 ? ( +
+

+ 오늘 등록된 스케줄이 없어요 +

+
+ ) : ( +
+ {workers.map(worker => ( + + ))} +
+ )}
) From e0df8d6c5e793a51cec97af0c1ed2c927f113c9f Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 27 May 2026 18:42:22 +0900 Subject: [PATCH 06/11] =?UTF-8?q?fix:=20key=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/hooks/useManagedPostingsViewModel.ts | 10 +++---- .../hooks/useSubstituteRequestsViewModel.ts | 10 +++---- .../home/hooks/useTodaySchedulesViewModel.ts | 29 ++++++++++++------- .../hooks/useWorkspaceWorkersViewModel.ts | 9 +++--- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/features/manager/home/hooks/useManagedPostingsViewModel.ts b/src/features/manager/home/hooks/useManagedPostingsViewModel.ts index dec10da..3b1a587 100644 --- a/src/features/manager/home/hooks/useManagedPostingsViewModel.ts +++ b/src/features/manager/home/hooks/useManagedPostingsViewModel.ts @@ -34,13 +34,13 @@ export function useManagedPostingsViewModel( enabled: workspaceId !== null, }) - const postings = useMemo( - () => + const postings = useMemo(() => { + const all = data?.pages.flatMap( page => page.data?.data?.map(adaptPostingDto) ?? [] - ) ?? [], - [data] - ) + ) ?? [] + return [...new Map(all.map(p => [p.id, p])).values()] + }, [data]) const totalCount = data?.pages[0]?.data?.page?.totalCount ?? 0 diff --git a/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts b/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts index c65bb09..14ad521 100644 --- a/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts +++ b/src/features/manager/home/hooks/useSubstituteRequestsViewModel.ts @@ -34,13 +34,13 @@ export function useSubstituteRequestsViewModel( enabled: workspaceId !== null, }) - const requests = useMemo( - () => + const requests = useMemo(() => { + const all = data?.pages.flatMap( page => page?.data?.data?.map(adaptSubstituteRequestDto) ?? [] - ) ?? [], - [data] - ) + ) ?? [] + return [...new Map(all.map(r => [r.id, r])).values()] + }, [data]) const totalCount = data?.pages?.[0]?.data?.page?.totalCount ?? 0 diff --git a/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts b/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts index 212ac84..0d4b289 100644 --- a/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts +++ b/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts @@ -14,17 +14,24 @@ export function useTodaySchedulesViewModel(workspaceId: number | null) { const todayWorkers = useMemo(() => { if (!data) return [] - return data.data.map(worker => ({ - id: worker.workerId, - name: worker.workerName, - profileImageUrl: worker.profileImageUrl, - workTime: worker.shifts[0] - ? formatIsoTimeRangeLabel( - worker.shifts[0].startDateTime, - worker.shifts[0].endDateTime - ) - : '', - })) + const seen = new Set() + return data.data + .filter(worker => { + if (seen.has(worker.workerId)) return false + seen.add(worker.workerId) + return true + }) + .map(worker => ({ + id: worker.workerId, + name: worker.workerName, + profileImageUrl: worker.profileImageUrl, + workTime: worker.shifts[0] + ? formatIsoTimeRangeLabel( + worker.shifts[0].startDateTime, + worker.shifts[0].endDateTime + ) + : '', + })) }, [data]) return { diff --git a/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts b/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts index a907cde..a018194 100644 --- a/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts +++ b/src/features/manager/home/hooks/useWorkspaceWorkersViewModel.ts @@ -35,10 +35,11 @@ export function useWorkspaceWorkersViewModel( enabled: workspaceId !== null, }) - const workers = useMemo( - () => data?.pages.flatMap(page => page.data.data.map(adaptWorkerDto)) ?? [], - [data] - ) + const workers = useMemo(() => { + const all = + data?.pages.flatMap(page => page.data.data.map(adaptWorkerDto)) ?? [] + return [...new Map(all.map(w => [w.id, w])).values()] + }, [data]) const totalCount = data?.pages[0]?.data.page.totalCount ?? 0 From 1434c8922d14013d077e15f50cfa4a7cf321026c Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 27 May 2026 18:54:18 +0900 Subject: [PATCH 07/11] =?UTF-8?q?refactor:=20=EB=8D=94=EB=B3=B4=EA=B8=B0?= =?UTF-8?q?=20=EB=85=B8=EC=B6=9C=20=EC=A1=B0=EA=B1=B4=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/manager/home/index.tsx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/pages/manager/home/index.tsx b/src/pages/manager/home/index.tsx index 69c7b7b..78cd16f 100644 --- a/src/pages/manager/home/index.tsx +++ b/src/pages/manager/home/index.tsx @@ -28,13 +28,16 @@ export function ManagerHomePage() { storeWorkers, storeWorkersTotalCount, fetchMoreWorkers, + hasMoreWorkers, isFetchingMoreWorkers, ongoingPostings, postingsTotalCount, fetchMorePostings, + hasMorePostings, substituteRequests, substituteTotalCount, fetchMoreSubstitutes, + hasMoreSubstitutes, schedule, activeWorkspaceId, workspaceDetail, @@ -228,12 +231,13 @@ export function ManagerHomePage() { onOptions={() => {}} /> ))} - {storeWorkers.length < storeWorkersTotalCount && ( - fetchMoreWorkers()} - disabled={isFetchingMoreWorkers} - /> - )} + {storeWorkers.length < storeWorkersTotalCount && + hasMoreWorkers && ( + fetchMoreWorkers()} + disabled={isFetchingMoreWorkers} + /> + )}
)}
@@ -247,7 +251,7 @@ export function ManagerHomePage() { fetchMorePostings() : undefined } @@ -264,7 +268,8 @@ export function ManagerHomePage() { fetchMoreSubstitutes() : undefined } From cc8c70ac85d2ff9ca980a2bac88b2db79a5c6c71 Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 3 Jun 2026 17:35:40 +0900 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20=EA=B7=BC=EB=AC=B4=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EB=B3=B5=EC=88=98=20=EC=89=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=B0=A9=EC=8B=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/hooks/useTodaySchedulesViewModel.ts | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts b/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts index 0d4b289..5788c47 100644 --- a/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts +++ b/src/features/manager/home/hooks/useTodaySchedulesViewModel.ts @@ -14,24 +14,17 @@ export function useTodaySchedulesViewModel(workspaceId: number | null) { const todayWorkers = useMemo(() => { if (!data) return [] - const seen = new Set() - return data.data - .filter(worker => { - if (seen.has(worker.workerId)) return false - seen.add(worker.workerId) - return true - }) - .map(worker => ({ - id: worker.workerId, + return data.data.flatMap(worker => + worker.shifts.map(shift => ({ + id: shift.shiftId, name: worker.workerName, profileImageUrl: worker.profileImageUrl, - workTime: worker.shifts[0] - ? formatIsoTimeRangeLabel( - worker.shifts[0].startDateTime, - worker.shifts[0].endDateTime - ) - : '', + workTime: formatIsoTimeRangeLabel( + shift.startDateTime, + shift.endDateTime + ), })) + ) }, [data]) return { From f326a544ecb5701600333d6fc0164bf42be89ddc Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 3 Jun 2026 17:49:10 +0900 Subject: [PATCH 09/11] =?UTF-8?q?fix:=20pagesize=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/hooks/useManagerHomeViewModel.ts | 75 +++++++++++++++---- src/pages/manager/home/index.tsx | 12 +-- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/features/manager/home/hooks/useManagerHomeViewModel.ts b/src/features/manager/home/hooks/useManagerHomeViewModel.ts index 0bf8796..b8a769a 100644 --- a/src/features/manager/home/hooks/useManagerHomeViewModel.ts +++ b/src/features/manager/home/hooks/useManagerHomeViewModel.ts @@ -17,26 +17,71 @@ export function useManagerHomeViewModel() { const { detail: workspaceDetail } = useWorkspaceDetailQuery(activeWorkspaceId) const { - workers: storeWorkers, + workers: allStoreWorkers, totalCount: storeWorkersTotalCount, - fetchNextPage: fetchMoreWorkers, - hasNextPage: hasMoreWorkers, + fetchNextPage: fetchNextWorkersPage, + hasNextPage: hasNextWorkersPage, isFetchingNextPage: isFetchingMoreWorkers, - } = useWorkspaceWorkersViewModel(activeWorkspaceId, undefined, 3) + } = useWorkspaceWorkersViewModel(activeWorkspaceId) const { - postings: ongoingPostings, + postings: allOngoingPostings, totalCount: postingsTotalCount, - fetchNextPage: fetchMorePostings, - hasNextPage: hasMorePostings, - } = useManagedPostingsViewModel(activeWorkspaceId, { status: 'OPEN' }, 3) + fetchNextPage: fetchNextPostingsPage, + hasNextPage: hasNextPostingsPage, + } = useManagedPostingsViewModel(activeWorkspaceId, { status: 'OPEN' }) const { - requests: substituteRequests, + requests: allSubstituteRequests, totalCount: substituteTotalCount, - fetchNextPage: fetchMoreSubstitutes, - hasNextPage: hasMoreSubstitutes, - } = useSubstituteRequestsViewModel(activeWorkspaceId, undefined, 3) + fetchNextPage: fetchNextSubstitutesPage, + hasNextPage: hasNextSubstitutesPage, + } = useSubstituteRequestsViewModel(activeWorkspaceId) + + const [visibleWorkersCount, setVisibleWorkersCount] = useState(3) + const [visiblePostingsCount, setVisiblePostingsCount] = useState(3) + const [visibleSubstitutesCount, setVisibleSubstitutesCount] = useState(3) + + const storeWorkers = allStoreWorkers.slice(0, visibleWorkersCount) + const ongoingPostings = allOngoingPostings.slice(0, visiblePostingsCount) + const substituteRequests = allSubstituteRequests.slice( + 0, + visibleSubstitutesCount + ) + + const hasMoreWorkers = + visibleWorkersCount < allStoreWorkers.length || hasNextWorkersPage + const hasMorePostings = + visiblePostingsCount < allOngoingPostings.length || hasNextPostingsPage + const hasMoreSubstitutes = + visibleSubstitutesCount < allSubstituteRequests.length || + hasNextSubstitutesPage + + const showMoreWorkers = () => { + if (visibleWorkersCount < allStoreWorkers.length) { + setVisibleWorkersCount(c => c + 3) + } else { + fetchNextWorkersPage().then(() => setVisibleWorkersCount(c => c + 3)) + } + } + + const showMorePostings = () => { + if (visiblePostingsCount < allOngoingPostings.length) { + setVisiblePostingsCount(c => c + 3) + } else { + fetchNextPostingsPage().then(() => setVisiblePostingsCount(c => c + 3)) + } + } + + const showMoreSubstitutes = () => { + if (visibleSubstitutesCount < allSubstituteRequests.length) { + setVisibleSubstitutesCount(c => c + 3) + } else { + fetchNextSubstitutesPage().then(() => + setVisibleSubstitutesCount(c => c + 3) + ) + } + } const { baseDate: scheduleBaseDate, @@ -82,16 +127,16 @@ export function useManagerHomeViewModel() { todayWorkers, storeWorkers, storeWorkersTotalCount, - fetchMoreWorkers, + showMoreWorkers, hasMoreWorkers, isFetchingMoreWorkers, ongoingPostings, postingsTotalCount, - fetchMorePostings, + showMorePostings, hasMorePostings, substituteRequests, substituteTotalCount, - fetchMoreSubstitutes, + showMoreSubstitutes, hasMoreSubstitutes, schedule: { baseDate: scheduleBaseDate, diff --git a/src/pages/manager/home/index.tsx b/src/pages/manager/home/index.tsx index 78cd16f..bffd594 100644 --- a/src/pages/manager/home/index.tsx +++ b/src/pages/manager/home/index.tsx @@ -27,16 +27,16 @@ export function ManagerHomePage() { todayWorkers, storeWorkers, storeWorkersTotalCount, - fetchMoreWorkers, + showMoreWorkers, hasMoreWorkers, isFetchingMoreWorkers, ongoingPostings, postingsTotalCount, - fetchMorePostings, + showMorePostings, hasMorePostings, substituteRequests, substituteTotalCount, - fetchMoreSubstitutes, + showMoreSubstitutes, hasMoreSubstitutes, schedule, activeWorkspaceId, @@ -234,7 +234,7 @@ export function ManagerHomePage() { {storeWorkers.length < storeWorkersTotalCount && hasMoreWorkers && ( fetchMoreWorkers()} + onClick={() => showMoreWorkers()} disabled={isFetchingMoreWorkers} /> )} @@ -252,7 +252,7 @@ export function ManagerHomePage() { postings={ongoingPostings} onViewMore={ ongoingPostings.length < postingsTotalCount && hasMorePostings - ? () => fetchMorePostings() + ? () => showMorePostings() : undefined } onPostingClick={() => {}} @@ -270,7 +270,7 @@ export function ManagerHomePage() { onViewMore={ substituteRequests.length < substituteTotalCount && hasMoreSubstitutes - ? () => fetchMoreSubstitutes() + ? () => showMoreSubstitutes() : undefined } onRequestClick={() => {}} From 8a62ad9787a0436b97dbd758ff3109b502de5c91 Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 3 Jun 2026 17:51:35 +0900 Subject: [PATCH 10/11] =?UTF-8?q?fix:=20STORE=5FWORKERS=5FSECTION=5FID=20?= =?UTF-8?q?=EB=AF=B8=EC=82=AC=EC=9A=A9=20=EC=83=81=EC=88=98=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/manager/home/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/manager/home/index.tsx b/src/pages/manager/home/index.tsx index bffd594..73ed077 100644 --- a/src/pages/manager/home/index.tsx +++ b/src/pages/manager/home/index.tsx @@ -19,8 +19,6 @@ import managerWorkspaceModalPlusIcon from '@/assets/icons/home/manager-workspace import managerScheduleEditIcon from '@/assets/icons/home/edit.svg' import { ROUTES, managerWorkerSchedulePath } from '@/shared/constants/routes' -const STORE_WORKERS_SECTION_ID = 'manager-store-workers' - export function ManagerHomePage() { const navigate = useNavigate() const { @@ -200,7 +198,7 @@ export function ManagerHomePage() { /> -
+

우리 매장 근무자 From f2e81930e2d86c6f4a969de750f66fbd97ede2fa Mon Sep 17 00:00:00 2001 From: SeongHwan Date: Wed, 3 Jun 2026 18:12:39 +0900 Subject: [PATCH 11/11] =?UTF-8?q?feat:=20=EC=97=85=EC=9E=A5=20=EC=A0=84?= =?UTF-8?q?=ED=99=98=20=EC=8B=9C=20=EB=8D=94=EB=B3=B4=EA=B8=B0=20=EC=B9=B4?= =?UTF-8?q?=EC=9A=B4=ED=8A=B8=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/hooks/useManagerHomeViewModel.ts | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/src/features/manager/home/hooks/useManagerHomeViewModel.ts b/src/features/manager/home/hooks/useManagerHomeViewModel.ts index b8a769a..12a30b0 100644 --- a/src/features/manager/home/hooks/useManagerHomeViewModel.ts +++ b/src/features/manager/home/hooks/useManagerHomeViewModel.ts @@ -38,9 +38,19 @@ export function useManagerHomeViewModel() { hasNextPage: hasNextSubstitutesPage, } = useSubstituteRequestsViewModel(activeWorkspaceId) - const [visibleWorkersCount, setVisibleWorkersCount] = useState(3) - const [visiblePostingsCount, setVisiblePostingsCount] = useState(3) - const [visibleSubstitutesCount, setVisibleSubstitutesCount] = useState(3) + const [visibleCounts, setVisibleCounts] = useState({ + forWorkspaceId: activeWorkspaceId, + workers: 3, + postings: 3, + substitutes: 3, + }) + + const isSameWorkspace = visibleCounts.forWorkspaceId === activeWorkspaceId + const visibleWorkersCount = isSameWorkspace ? visibleCounts.workers : 3 + const visiblePostingsCount = isSameWorkspace ? visibleCounts.postings : 3 + const visibleSubstitutesCount = isSameWorkspace + ? visibleCounts.substitutes + : 3 const storeWorkers = allStoreWorkers.slice(0, visibleWorkersCount) const ongoingPostings = allOngoingPostings.slice(0, visiblePostingsCount) @@ -58,27 +68,58 @@ export function useManagerHomeViewModel() { hasNextSubstitutesPage const showMoreWorkers = () => { + const nextCount = visibleWorkersCount + 3 if (visibleWorkersCount < allStoreWorkers.length) { - setVisibleWorkersCount(c => c + 3) + setVisibleCounts(prev => ({ + ...prev, + forWorkspaceId: activeWorkspaceId, + workers: nextCount, + })) } else { - fetchNextWorkersPage().then(() => setVisibleWorkersCount(c => c + 3)) + fetchNextWorkersPage().then(() => + setVisibleCounts(prev => ({ + ...prev, + forWorkspaceId: activeWorkspaceId, + workers: nextCount, + })) + ) } } const showMorePostings = () => { + const nextCount = visiblePostingsCount + 3 if (visiblePostingsCount < allOngoingPostings.length) { - setVisiblePostingsCount(c => c + 3) + setVisibleCounts(prev => ({ + ...prev, + forWorkspaceId: activeWorkspaceId, + postings: nextCount, + })) } else { - fetchNextPostingsPage().then(() => setVisiblePostingsCount(c => c + 3)) + fetchNextPostingsPage().then(() => + setVisibleCounts(prev => ({ + ...prev, + forWorkspaceId: activeWorkspaceId, + postings: nextCount, + })) + ) } } const showMoreSubstitutes = () => { + const nextCount = visibleSubstitutesCount + 3 if (visibleSubstitutesCount < allSubstituteRequests.length) { - setVisibleSubstitutesCount(c => c + 3) + setVisibleCounts(prev => ({ + ...prev, + forWorkspaceId: activeWorkspaceId, + substitutes: nextCount, + })) } else { fetchNextSubstitutesPage().then(() => - setVisibleSubstitutesCount(c => c + 3) + setVisibleCounts(prev => ({ + ...prev, + forWorkspaceId: activeWorkspaceId, + substitutes: nextCount, + })) ) } }