Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b2f89b2
fix: 사용자 메인 컴포넌트 너비 및 Navbar 배경색 수정
limtjdghks Apr 12, 2026
b811282
feat: 알바생 메인 페이지 구현
limtjdghks Apr 12, 2026
0c56e81
fix: Navbar 타이포그래피 스타일 설정 수정
limtjdghks Apr 12, 2026
ffebc9e
feat: 근무중인 가게 상세페이지 구현
limtjdghks Apr 12, 2026
55a6931
feat: 내가 지원한 가게 페이지 구현
limtjdghks Apr 12, 2026
5453eaa
feat: 공고 지원 조회 모달 구현
limtjdghks Apr 12, 2026
17f58f2
feat: 나의 근무 스케줄 조회 api 연동
limtjdghks Apr 12, 2026
b5845bd
refactor: 코드 포맷팅
limtjdghks Apr 12, 2026
87bdc04
feat: 현재 근무중인 업장 목록 api 연동
limtjdghks Apr 15, 2026
3cebd76
refactor: 페이지 경로 수정
limtjdghks Apr 15, 2026
cde8265
refactor: 파일 구조 변경
limtjdghks Apr 15, 2026
292ccb5
feat: 업장별 근무 스케줄 조회 API 연동
limtjdghks Apr 15, 2026
e1de542
feat: 근무중인 업장 근무자 조회 API 연동
limtjdghks Apr 15, 2026
826da24
fix: storybook import 수정
limtjdghks Apr 15, 2026
bc33002
feat: 업장 상세페이지 컴포넌트 사용하도록 수정 및 관리자 조회 API 추가
limtjdghks Apr 15, 2026
88ff969
feat: 사용자 공고 지원 목록 조회 API 연동
limtjdghks Apr 15, 2026
0f8c3d1
feat: 공고 지원 취소 API 연동
limtjdghks Apr 16, 2026
e732adc
feat: 사장님 메인 페이지 디자인 수정 및 추가 컴포넌트 구현
limtjdghks Apr 16, 2026
a069cb8
feat: 사장님 스케줄 관리 페이지 구현중
limtjdghks Apr 16, 2026
9fa7621
feat: 사장님 관리하는 업장 목록 및 상세 조회 API 연동
limtjdghks Apr 16, 2026
70afa3d
feat: 사장님 업장 근무자 목록 조회 API 연동
limtjdghks Apr 16, 2026
cb9657b
feat: 내가 등록한 공고 조회 API 연동
limtjdghks Apr 16, 2026
aa4c5e0
feat: 사장님 대타 요청 조회 API 연동
limtjdghks Apr 16, 2026
9a76e0c
feat: 사장님 업장 스케줄 조회 API 연동
limtjdghks Apr 16, 2026
e4910e6
refactor: 캘린더 공통 컴포넌트로 리팩토링
limtjdghks Apr 16, 2026
7bac714
fix: date 유틸 re-export 누락 및 useWorkspaceMembers 타입 오류 수정
limtjdghks Apr 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import {
Outlet,
} from 'react-router-dom'
import { ManagerHomePage } from '@/pages/manager/home'
import { ManagerWorkerSchedulePage } from '@/pages/manager/worker-schedule'
import { SocialPage } from '@/pages/manager/social'
import { SocialChatPage } from '@/pages/manager/social-chat'
import { LoginPage } from '@/pages/login'
import { JobLookupMapPage } from '@/pages/user/job-lookup-map'
import { SchedulePage } from '@/pages/user/schedule'
import { UserHomePage } from '@/pages/user/home'
import { WorkspaceMembersPage } from '@/pages/user/workspace-members'
import { WorkspacePage } from '@/pages/user/workspace'
import { WorkspaceDetailPage } from '@/pages/user/workspace-detail'
import { AppliedStoresPage } from '@/pages/user/applied-stores'
import { MobileLayout } from '@/shared/ui/MobileLayout'
import { MobileLayoutWithDocbar } from '@/shared/ui/MobileLayoutWithDocbar'

Expand Down Expand Up @@ -58,16 +62,26 @@ export function App() {
</Suspense>
}
/>
<Route path="/schedule" element={<SchedulePage />} />
<Route path="/user/schedule" element={<SchedulePage />} />
<Route
path="/workspaces/:workspaceId/members"
path="/user/workspaces/:workspaceId/members"
element={<WorkspaceMembersPage />}
/>
<Route path="/user/workspace" element={<WorkspacePage />} />
<Route
path="/user/workspace/:workspaceId"
element={<WorkspaceDetailPage />}
/>
<Route path="/user/applied-stores" element={<AppliedStoresPage />} />
<Route
path="/manager/worker-schedule"
element={<ManagerWorkerSchedulePage />}
/>
</Route>

<Route element={<MobileRouteLayoutWithDocbar />}>
<Route path="/job-lookup-map" element={<JobLookupMapPage />} />
<Route path="/home" element={<UserHomePage />} />
<Route path="/user/job-lookup-map" element={<JobLookupMapPage />} />
<Route path="/user/home" element={<UserHomePage />} />
<Route path="/manager/home" element={<ManagerHomePage />} />
<Route path="/manager/social" element={<SocialPage />} />
<Route path="/manager/social/chat" element={<SocialChatPage />} />
Expand Down
5 changes: 5 additions & 0 deletions src/assets/icons/home/crown-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/assets/icons/home/manager-home-banner-plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/assets/icons/home/manager-workspace-modal-plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/assets/icons/home/users.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/manager-home-banner.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import {
DATE_KEY_FORMAT,
MONTH_LABEL_FORMAT,
WEEKDAY_LABELS_MONDAY_FIRST,
} from '@/features/home/user/constants/calendar'
import { useMonthlyDateCellsState } from '@/features/home/user/hooks/useMonthlyDateCellsState'
} from '@/features/home/common/schedule/constants/calendar'
import { useMonthlyDateCellsState } from '@/features/home/common/schedule/hooks/useMonthlyDateCellsState'
import type {
MonthlyCalendarViewModel,
MonthlyCellInput,
MonthlyDayMetrics,
MonthlyCalendarPropsBase,
} from '@/features/home/user/types/monthlyCalendar'
import type { CalendarViewData } from '@/features/home/user/types/schedule'
} 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)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useMemo } from 'react'
import type { UseMonthlyDateCellsStateParams } from '@/features/home/user/types/monthlyCalendar'
import type { UseMonthlyDateCellsStateParams } from '@/features/home/common/schedule/types/monthlyCalendar'

export function useMonthlyDateCellsState({
cells,
Expand Down
18 changes: 18 additions & 0 deletions src/features/home/common/schedule/lib/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const ISO_DATE_LENGTH = 10
const ISO_TIME_START = 11
const ISO_TIME_END = 16

export function toDateKey(iso: string) {
return iso.slice(0, ISO_DATE_LENGTH)
}

export function toTimeLabel(iso: string) {
return iso.slice(ISO_TIME_START, ISO_TIME_END)
}

export function getDurationHours(startIso: string, endIso: string) {
const start = new Date(startIso).getTime()
const end = new Date(endIso).getTime()
const diffHours = Math.max((end - start) / (1000 * 60 * 60), 0)
return Number(diffHours.toFixed(1))
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CalendarViewData } from '@/features/home/user/types/schedule'
import type { CalendarViewData } from '@/features/home/common/schedule/types/calendarView'

export interface BaseCalendarProps {
baseDate: Date
Expand Down
24 changes: 24 additions & 0 deletions src/features/home/common/schedule/types/calendarView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { StatusEnum } from '@/shared/types/enums'

export interface CalendarEvent {
shiftId: number
workspaceName: string
position: string
status: StatusEnum
startDateTime: string
endDateTime: string
dateKey: string
startTimeLabel: string
endTimeLabel: string
durationHours: number
}

export interface CalendarSummary {
totalWorkHours: number
eventCount: number
}

export interface CalendarViewData {
summary: CalendarSummary
events: CalendarEvent[]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { WEEKDAY_LABELS_MONDAY_FIRST } from '@/features/home/user/constants/calendar'
import type { BaseCalendarProps } from '@/features/home/user/types/calendar'
import type { WEEKDAY_LABELS_MONDAY_FIRST } from '@/features/home/common/schedule/constants/calendar'
import type { BaseCalendarProps } from '@/features/home/common/schedule/types/calendarBase'

export interface MonthlyCellInput {
dateKey: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import type { ReactNode } from 'react'
import DownIcon from '@/assets/icons/home/chevron-down.svg?react'
import { useMonthlyCalendarViewModel } from '@/features/home/user/hooks/useMonthlyCalendarViewModel'
import type { MonthlyCalendarPropsBase } from '@/features/home/user/types/monthlyCalendar'
import { MonthlyDateCell } from '@/features/home/user/ui/MonthlyDateCell'
import { useMonthlyCalendarViewModel } from '@/features/home/common/schedule/hooks/useMonthlyCalendarViewModel'
import type { MonthlyCalendarPropsBase } from '@/features/home/common/schedule/types/monthlyCalendar'
import { MonthlyDateCell } from '@/features/home/common/schedule/ui/MonthlyDateCell'

interface MonthlyCalendarProps extends MonthlyCalendarPropsBase {
isLoading?: boolean
hideTitle?: boolean
rightAction?: ReactNode
estimatedEarningsText?: string
layout?: 'default' | 'manager'
}

export function MonthlyCalendar({
Expand All @@ -13,6 +18,10 @@ export function MonthlyCalendar({
workspaceName,
isLoading = false,
selectedDateKey,
hideTitle = false,
rightAction,
estimatedEarningsText,
layout = 'default',
}: MonthlyCalendarProps) {
const {
title,
Expand All @@ -37,22 +46,36 @@ export function MonthlyCalendar({

return (
<section className="rounded-2xl bg-white">
<div className="px-[13px] gap-2">
<h3 className="typography-headline01 mb-4">{title}</h3>
<button
type="button"
className="flex items-center gap-1 typography-body01-regular text-text-90"
>
{monthLabel}
<DownIcon className="w-4 h-4" />
</button>
<div className="flex items-center gap-2 py-1">
<span className="typography-display">{totalWorkHoursText}</span>
<span className="typography-body02-semibold">시간 근무해요</span>
<div className={layout === 'manager' ? 'px-6 pt-5' : 'px-[13px]'}>
{!hideTitle && <h3 className="typography-headline01 mb-4">{title}</h3>}

<div className="flex items-center justify-between">
<button
type="button"
className="flex items-center gap-1 typography-body01-regular text-text-90"
>
{monthLabel}
<DownIcon className="w-4 h-4" />
</button>
{rightAction}
</div>

<div className="flex items-center justify-between py-1">
<div className="flex items-center gap-2">
<span className="typography-display">{totalWorkHoursText}</span>
<span className="typography-body02-semibold">시간 근무해요</span>
</div>
{estimatedEarningsText ? (
<span className="typography-body01-semibold text-sub">
{estimatedEarningsText}
</span>
) : null}
</div>
</div>

<section className="mt-4">
<section
className={layout === 'manager' ? 'mt-5 px-[11px] pb-4' : 'mt-4'}
>
<div className="grid grid-cols-7 text-center">
{weekdayLabels.map((label, index) => (
<span
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MonthlyDateGauge } from '@/features/home/user/ui/MonthlyDateGauge'
import { MonthlyDateGauge } from '@/features/home/common/schedule/ui/MonthlyDateGauge'

interface MonthlyDateCellProps {
dayText: string
Expand Down
24 changes: 11 additions & 13 deletions src/features/home/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
export { HomeScheduleCalendar } from '@/features/home/user/ui/HomeScheduleCalendar'
export { HomeScheduleCalendar } from '@/features/home/user/schedule/ui/HomeScheduleCalendar'
export { TodayWorkerList } from '@/features/home/manager/ui/TodayWorkerList'
export { StoreWorkerListItem } from '@/features/home/manager/ui/StoreWorkerListItem'
export { WorkspaceChangeCard } from '@/features/home/manager/ui/WorkspaceChangeCard'
export { WorkspaceChangeList } from '@/features/home/manager/ui/WorkspaceChangeList'
export { AppliedStoreCard } from '@/features/home/user/ui/AppliedStoreCard'
export { AppliedStoreList } from '@/features/home/user/ui/AppliedStoreList'
export { WorkingStoresList } from '@/features/home/user/ui/WorkingStoresList'
export { WorkingStoreCard } from '@/features/home/user/ui/WorkingStoreCard'
export type {
HomeCalendarMode,
CalendarViewData,
} from '@/features/home/user/types/schedule'
export { AppliedStoreCard } from '@/features/home/user/applied-stores/ui/AppliedStoreCard'
export { AppliedStoreList } from '@/features/home/user/applied-stores/ui/AppliedStoreList'
export { AppliedStoreDetailModal } from '@/features/home/user/applied-stores/ui/AppliedStoreDetailModal'
export { WorkingStoresList } from '@/features/home/user/workspace/ui/WorkingStoresList'
export { WorkingStoreCard } from '@/features/home/user/workspace/ui/WorkingStoreCard'
export type { HomeCalendarMode } from '@/features/home/user/schedule/types/schedule'
export type { CalendarViewData } from '@/features/home/common/schedule/types/calendarView'
export {
getMonthlySchedules,
getWeeklySchedules,
getDailySchedules,
} from '@/features/home/user/api/schedule'
getSelfSchedule,
adaptScheduleResponse,
} from '@/features/home/user/schedule/api/schedule'
24 changes: 24 additions & 0 deletions src/features/home/manager/api/posting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import axiosInstance from '@/shared/lib/axiosInstance'
import type {
PostingListApiResponse,
ManagedPostingsQueryParams,
} from '@/features/home/manager/types/posting'

export async function fetchManagedPostings(
params: ManagedPostingsQueryParams
): Promise<PostingListApiResponse> {
const response = await axiosInstance.get<PostingListApiResponse>(
'/manager/postings',
{
params: {
pageSize: params.pageSize,
...(params.workspaceId !== undefined && {
workspaceId: params.workspaceId,
}),
...(params.status && { status: params.status }),
...(params.cursor !== undefined && { cursor: params.cursor }),
},
}
)
return response.data
}
21 changes: 21 additions & 0 deletions src/features/home/manager/api/schedule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import axiosInstance from '@/shared/lib/axiosInstance'
import type {
ManagerScheduleApiResponse,
ManagerScheduleQueryParams,
} from '@/features/home/manager/types/schedule'

export async function fetchMonthlySchedules(
params: ManagerScheduleQueryParams
): Promise<ManagerScheduleApiResponse> {
const response = await axiosInstance.get<ManagerScheduleApiResponse>(
'/manager/schedules',
{
params: {
workspaceId: params.workspaceId,
year: params.year,
month: params.month,
},
}
)
return response.data
}
24 changes: 24 additions & 0 deletions src/features/home/manager/api/substitute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import axiosInstance from '@/shared/lib/axiosInstance'
import type {
SubstituteListApiResponse,
SubstituteRequestsQueryParams,
} from '@/features/home/manager/types/substitute'

export async function fetchSubstituteRequests(
params: SubstituteRequestsQueryParams
): Promise<SubstituteListApiResponse> {
const response = await axiosInstance.get<SubstituteListApiResponse>(
'/manager/substitute-requests',
{
params: {
pageSize: params.pageSize,
...(params.workspaceId !== undefined && {
workspaceId: params.workspaceId,
}),
...(params.status && { status: params.status }),
...(params.cursor !== undefined && { cursor: params.cursor }),
},
}
)
return response.data
}
23 changes: 23 additions & 0 deletions src/features/home/manager/api/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import axiosInstance from '@/shared/lib/axiosInstance'
import type {
WorkersApiResponse,
WorkspaceWorkersQueryParams,
} from '@/features/home/manager/types/worker'

export async function fetchWorkspaceWorkers(
params: WorkspaceWorkersQueryParams
): Promise<WorkersApiResponse> {
const { workspaceId, cursor, pageSize, status, name } = params
const response = await axiosInstance.get<WorkersApiResponse>(
`/manager/workspaces/${workspaceId}/workers`,
{
params: {
pageSize,
...(cursor !== undefined && { cursor }),
...(status && { status }),
...(name && { name }),
},
}
)
return response.data
}
Loading
Loading