Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
ff15ef7
페이지 구조 설계
seongihun Dec 30, 2025
ac447a4
컴포넌트 설계
seongihun Dec 30, 2025
a41f4ba
폴더구조 구성에따른 컴포넌트 이동
seongihun Dec 30, 2025
4c95017
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
9a7bd94
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
bbc5398
데이터의 title 값에 맞는 드롭다운 리스트 구현
seongihun Jan 2, 2026
6575722
css 수정 텍스트 토큰 사용
seongihun Jan 2, 2026
12e3819
시안에 맞게 스타일수정
seongihun Jan 2, 2026
932e6ab
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
d93561a
디버그 콘솔 제거
seongihun Jan 2, 2026
8470c21
mock데이터 2026으로 최신화
seongihun Jan 2, 2026
0bf5375
날짜 로직 수정
seongihun Jan 2, 2026
1291a44
모바일 ,태블릿 반응형 모달
seongihun Jan 2, 2026
ec54e42
반응형 적용
seongihun Jan 2, 2026
d393e6d
파일명 오타수정
seongihun Jan 2, 2026
3c826b3
모바일 태블릿 반응형 모달 커스텀훅
seongihun Jan 2, 2026
7ec0379
modal 공통 요소 분기
seongihun Jan 2, 2026
77f3be3
페이지 구조 설계
seongihun Dec 30, 2025
ecbf92c
컴포넌트 설계
seongihun Dec 30, 2025
9220836
폴더구조 구성에따른 컴포넌트 이동
seongihun Dec 30, 2025
57641ac
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
2429775
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
f58d5e8
데이터의 title 값에 맞는 드롭다운 리스트 구현
seongihun Jan 2, 2026
af9dba8
css 수정 텍스트 토큰 사용
seongihun Jan 2, 2026
6895297
시안에 맞게 스타일수정
seongihun Jan 2, 2026
a4da135
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
a96396e
디버그 콘솔 제거
seongihun Jan 2, 2026
effc375
mock데이터 2026으로 최신화
seongihun Jan 2, 2026
a8a9682
날짜 로직 수정
seongihun Jan 2, 2026
cadc201
모바일 ,태블릿 반응형 모달
seongihun Jan 2, 2026
0f3ef46
반응형 적용
seongihun Jan 2, 2026
e1857ff
파일명 오타수정
seongihun Jan 2, 2026
fefa27d
모바일 태블릿 반응형 모달 커스텀훅
seongihun Jan 2, 2026
3bf488e
modal 공통 요소 분기
seongihun Jan 2, 2026
1007410
Merge branch 'feat/ReserVationStatusPage' of https://github.com/5team…
seongihun Jan 3, 2026
65c6b4d
페이지 구조 설계
seongihun Dec 30, 2025
6bcad50
컴포넌트 설계
seongihun Dec 30, 2025
f15eceb
폴더구조 구성에따른 컴포넌트 이동
seongihun Dec 30, 2025
c0417cb
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
7a0e91d
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
55efbec
데이터의 title 값에 맞는 드롭다운 리스트 구현
seongihun Jan 2, 2026
d084eb6
css 수정 텍스트 토큰 사용
seongihun Jan 2, 2026
2eaa36b
시안에 맞게 스타일수정
seongihun Jan 2, 2026
d9d9cad
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
b079471
디버그 콘솔 제거
seongihun Jan 2, 2026
6b61d59
mock데이터 2026으로 최신화
seongihun Jan 2, 2026
f348144
날짜 로직 수정
seongihun Jan 2, 2026
12d4077
모바일 ,태블릿 반응형 모달
seongihun Jan 2, 2026
c240d7b
반응형 적용
seongihun Jan 2, 2026
8fe296a
파일명 오타수정
seongihun Jan 2, 2026
ba7f0e7
모바일 태블릿 반응형 모달 커스텀훅
seongihun Jan 2, 2026
bf8d3ed
modal 공통 요소 분기
seongihun Jan 2, 2026
b7847c6
페이지 구조 설계
seongihun Dec 30, 2025
c9489a8
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
9b0363c
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
1557f22
시안에 맞게 스타일수정
seongihun Jan 2, 2026
b01066e
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
f087256
파일명 오타수정
seongihun Jan 2, 2026
3638737
Merge branch 'feat/ReserVationStatusPage' of https://github.com/5team…
seongihun Jan 3, 2026
d0585c3
Dayjs 라이브러리 설치 및 기본설정 파일 생성
seongihun Jan 6, 2026
0b8959a
dayjs 적용
seongihun Jan 6, 2026
7038df4
return 문 적용
seongihun Jan 6, 2026
8dc42e3
mockdata id string 형식으로 전환
seongihun Jan 6, 2026
3dadd7a
dayjs적용
seongihun Jan 6, 2026
5190fbd
타입 확장 및 수정
seongihun Jan 6, 2026
34612c5
예약 상태 코드 및 스타일 맵 수정
seongihun Jan 6, 2026
de49db8
CalendarGrid 컴포넌트와의 간격 조정
seongihun Jan 6, 2026
09739af
onSelectDate 함수의 매개변수 수정 및 코드 정리
seongihun Jan 6, 2026
1fb2174
onClick 매개변수를 onSelectDate로 변경하고 클릭 핸들러 수정
seongihun Jan 6, 2026
440561b
예약 상태 UI 구성 및 스타일 수정
seongihun Jan 6, 2026
d4ee584
예약 상태 페이지 구성 요소 추가 및 코드 정리
seongihun Jan 6, 2026
02298c4
페이지 구조 설계
seongihun Dec 30, 2025
3a0f045
컴포넌트 설계
seongihun Dec 30, 2025
e0d8b03
폴더구조 구성에따른 컴포넌트 이동
seongihun Dec 30, 2025
6258eb7
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
c09b796
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
610eb09
데이터의 title 값에 맞는 드롭다운 리스트 구현
seongihun Jan 2, 2026
46db8ae
css 수정 텍스트 토큰 사용
seongihun Jan 2, 2026
f3a0e61
시안에 맞게 스타일수정
seongihun Jan 2, 2026
659181e
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
b901841
디버그 콘솔 제거
seongihun Jan 2, 2026
d768c9f
mock데이터 2026으로 최신화
seongihun Jan 2, 2026
9ac65f1
날짜 로직 수정
seongihun Jan 2, 2026
8311753
모바일 ,태블릿 반응형 모달
seongihun Jan 2, 2026
beec938
반응형 적용
seongihun Jan 2, 2026
67823c6
파일명 오타수정
seongihun Jan 2, 2026
e34c5b3
모바일 태블릿 반응형 모달 커스텀훅
seongihun Jan 2, 2026
b76f8fa
modal 공통 요소 분기
seongihun Jan 2, 2026
5a52344
페이지 구조 설계
seongihun Dec 30, 2025
1c87520
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
c05d91a
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
89074d7
시안에 맞게 스타일수정
seongihun Jan 2, 2026
7d9a6ee
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
01fceb5
파일명 오타수정
seongihun Jan 2, 2026
0f12404
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
d98cde7
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
0159aa5
시안에 맞게 스타일수정
seongihun Jan 2, 2026
099e220
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
58f42cf
파일명 오타수정
seongihun Jan 2, 2026
f8f4f3d
feat-기훈 -예약내역 페이지 구현중
seongihun Dec 30, 2025
b756e72
컴포넌트 및 파일이름변경
seongihun Jan 2, 2026
ba9c2e0
시안에 맞게 스타일수정
seongihun Jan 2, 2026
1a2246c
props css 수정및 페이지 요소 삽입
seongihun Jan 2, 2026
83e53f5
파일명 오타수정
seongihun Jan 2, 2026
199e51d
Dayjs 라이브러리 설치 및 기본설정 파일 생성
seongihun Jan 6, 2026
074f8d9
dayjs 적용
seongihun Jan 6, 2026
eab931e
return 문 적용
seongihun Jan 6, 2026
1e46bb3
mockdata id string 형식으로 전환
seongihun Jan 6, 2026
96ac1a0
dayjs적용
seongihun Jan 6, 2026
4c5f1eb
타입 확장 및 수정
seongihun Jan 6, 2026
c2d921a
예약 상태 코드 및 스타일 맵 수정
seongihun Jan 6, 2026
266bbc9
CalendarGrid 컴포넌트와의 간격 조정
seongihun Jan 6, 2026
a783572
onSelectDate 함수의 매개변수 수정 및 코드 정리
seongihun Jan 6, 2026
06f1924
onClick 매개변수를 onSelectDate로 변경하고 클릭 핸들러 수정
seongihun Jan 6, 2026
a648f26
예약 상태 UI 구성 및 스타일 수정
seongihun Jan 6, 2026
bc003f3
예약 상태 페이지 구성 요소 추가 및 코드 정리
seongihun Jan 6, 2026
19566e3
Merge branch 'feat/ReserVationStatusPage' of https://github.com/5team…
seongihun Jan 7, 2026
b908b37
date-fns-jalali 패키지 추가
seongihun Jan 7, 2026
f95a781
Merge branch 'develop' into feat/ReserVationStatusPage
seongihun Jan 7, 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
44 changes: 44 additions & 0 deletions Mocks/reservationStatus.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Reservation } from "@/feature/reservationStatus/types/reservation";

export const mockReservations: Reservation[] = [
{
id: "선기훈",
title: "함께 배우는 플로잉 댄스",
date: "2025-12-01T11:00:00",
price: 10000,
people: 1,
status: "pending",
},
{
id: "정만철",
title: "함께 배우는 플로잉 댄스",
date: "2025-02-01T18:00:00",
price: 10000,
people: 1,
status: "pending",
},
{
id: "오승환",
title: "내 강아지 인생 사진 찍어주기",
date: "2026-02-11T13:00:00",
price: 35000,
people: 1,
status: "canceled",
},
{
id: "이대호",
title: "이색 액티비티 체험",
date: "2026-01-10T10:00:00",
price: 60000,
people: 3,
status: "declined",
},
{
id: "양의지",
title: "별과 함께하는 북촌 체험",
date: "2026-01-14T15:00:00",
price: 40000,
people: 2,
status: "completed",
},
];
2 changes: 1 addition & 1 deletion feature/Experience/schedule/DateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useState, useRef } from "react";
import CalendarIcon from "@/public/icon_calendar.svg";
import DatePicker from "./Datepicker";
import { Input } from "@/components/common/input";
import { Input } from "@/components/input/Input";
import { useClickOutside } from "@/hooks/useClickOutside";

interface Props {
Expand Down
9 changes: 3 additions & 6 deletions feature/MyInfo/MyInfoClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Sidebar from "@/feature/MyInfo/Sidebar";
import MyInfoView from "@/feature/MyInfo/MyInfoView";
import ReservationView from "@/feature/MyInfo/ReservationView";
import MyExperinenceView from "@/feature/MyInfo/MyExperinenceView";
import ReservaionStatusView from "@/feature/MyInfo/ReservaionStatusView";
import ReservationStatusPage from "@/feature/reservationStatus/ReservationStatusPage";
import type { SidebarMenu } from "@/types/SidebarTypes";

const DEFAULT_MENU: SidebarMenu = "MY_INFO";
Expand All @@ -15,8 +15,7 @@ export default function MyInfoClient() {
const searchParams = useSearchParams();
const router = useRouter();

const activeMenu =
(searchParams.get("menu") as SidebarMenu) ?? DEFAULT_MENU;
const activeMenu = (searchParams.get("menu") as SidebarMenu) ?? DEFAULT_MENU;

const handleMenuChange = (menu: SidebarMenu) => {
router.push(`/myinfo?menu=${menu}`);
Expand All @@ -32,9 +31,7 @@ export default function MyInfoClient() {
{activeMenu === "MY_INFO" && <MyInfoView />}
{activeMenu === "RESERVATIONS" && <ReservationView />}
{activeMenu === "MY_EXPERIENCE" && <MyExperinenceView />}
{activeMenu === "RESERVATION_STATUS" && (
<ReservaionStatusView />
)}
{activeMenu === "RESERVATION_STATUS" && <ReservationStatusPage />}
</main>
</div>
</div>
Expand Down
29 changes: 0 additions & 29 deletions feature/MyInfo/ReservaionStatusView.tsx

This file was deleted.

103 changes: 103 additions & 0 deletions feature/reservationStatus/Calendar/CalendarCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"use client";

import { CalendarDate } from "../types/calendar";
import { ReservationBadge } from "@/feature/reservationStatus/types/reservationStatus";
import { cn } from "@/lib/utils/twmerge";
import { StatusBadge } from "./StatusBadge";
import { toDateKey } from "@/lib/utils/date";

interface Props {
date: CalendarDate;
badges: ReservationBadge[];
isSelected: boolean;
onSelectDate: (
key: string,
position: { top: number; left: number; width: number; height: number }
) => void;
containerRef: React.RefObject<HTMLDivElement | null>;
}

export default function CalendarCell({
date,
badges,
isSelected,
onSelectDate,
containerRef,
}: Props) {
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
if (!date.isCurrentMonth) return;
if (!containerRef.current) return;

const rect = e.currentTarget.getBoundingClientRect();
const containerRect = containerRef.current.getBoundingClientRect();

const dateKey = toDateKey(date.date);
const MODAL_VERTICAL_OFFSET = 70;

const position = {
top:
rect.top -
containerRect.top +
rect.height / 2 +
MODAL_VERTICAL_OFFSET,
left:
rect.left -
containerRect.left +
rect.width +
12,
width: rect.width,
height: rect.height,
};



onSelectDate(dateKey, position);
};

return (
<div
onClick={handleClick}
className={cn(
"relative min-h-25 cursor-pointer transition-colors px-3 pt-4.5 pb-2.5",
"hover:text-black",
!date.isCurrentMonth && "text-gray-300",
isSelected && "bg-gray-50 text-gray-950 hover:bg-gray-100"
)}
>
{/* 날짜 숫자 */}
<div className="flex justify-center items-center mb-1.5">
<span
className={cn(
"text-sm",
date.isToday &&
"flex h-6 w-6 items-center justify-center rounded-full bg-gray-100",
isSelected && date.isToday && "bg-white text-black"
)}
>
{date.day}
</span>

{/* 예약 있음 표시 (점) */}
{badges.length > 0 && (
<span
className={cn(
"ml-1 h-1.5 w-1.5 rounded-full",
isSelected ? "bg-primary-500" : "bg-red-500"
)}
/>
)}
</div>

{/* 상태 배지 */}
<div className="flex flex-col gap-1">
{badges.map((badge) => (
<StatusBadge
key={badge.status}
status={badge.status}
count={badge.count}
/>
))}
</div>
</div>
);
}
66 changes: 66 additions & 0 deletions feature/reservationStatus/Calendar/CalendarGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { CalendarDate } from "@/feature/reservationStatus/types/calendar";
import { ReservationMap } from "../utils/mapReservationsToCalendar";
import { toDateKey } from "@/lib/utils/date";
import CalendarCell from "./CalendarCell";
import { useRef } from "react";

const DAYS = [
{ id: 0, label: "S" },
{ id: 1, label: "M" },
{ id: 2, label: "T" },
{ id: 3, label: "W" },
{ id: 4, label: "T" },
{ id: 5, label: "F" },
{ id: 6, label: "S" },
];

interface Props {
dates: CalendarDate[];
badgesMap: ReservationMap;
selectedDateKey: string | null;
onSelectDate: (
key: string,
position: { top: number; left: number; width: number; height: number }
) => void;
}


export default function CalendarGrid({
dates,
badgesMap,
selectedDateKey,
onSelectDate,
}: Props) {
const gridRef = useRef<HTMLDivElement>(null);

return (
<div>
{/* 요일 */}
<div className="grid grid-cols-7 mb-4">
{DAYS.map((day) => (
<div key={day.id} className="p-3 text-16-b items-center">
{day.label}
</div>
))}
</div>

{/* 날짜 */}
<div ref={gridRef} className="relative grid grid-cols-7">
{dates.map((date) => {
const dateKey = toDateKey(date.date);

return (
<CalendarCell
key={dateKey}
date={date}
badges={badgesMap[dateKey] ?? []}
isSelected={selectedDateKey === dateKey}
onSelectDate={onSelectDate}
containerRef={gridRef}
/>
);
})}
</div>
</div>
);
}
33 changes: 33 additions & 0 deletions feature/reservationStatus/Calendar/CalendarHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// CalendarHeader.tsx
import ArrowLeft from "@/public/icon_arrow_left.svg"
import ArrowRight from "@/public/icon_arrow_right.svg"

interface Props {
year: number;
month: number;
onPrev: () => void;
onNext: () => void;
}

export default function CalendarHeader({
year,
month,
onPrev,
onNext,
}: Props) {
return (
<div className="flex justify-center items-center gap-8 mb-8 cursor-pointer">
<button onClick={onPrev} className="cursor-pointer">
<ArrowLeft className="text-gray-600" />
</button>

<h2 className="text-20-b">
{year}년 {month + 1}월
</h2>

<button onClick={onNext} className="cursor-pointer">
<ArrowRight className="text-gray-600" />
</button>
</div>
);
}
48 changes: 48 additions & 0 deletions feature/reservationStatus/Calendar/ReservationCalendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"use client";

import { getMonthCalendar } from "@/feature/reservationStatus/types/calendar";
import { mapReservationsToCalendar } from "../utils/mapReservationsToCalendar";
import { Reservation } from "../types/reservation";
import CalendarHeader from "./CalendarHeader";
import CalendarGrid from "./CalendarGrid";
import { useCalendar } from "@/hooks/useCalendar";

interface Props {
reservations: Reservation[];
selectedDateKey: string | null;
onSelectDate: (key: string, position: { top: number; left: number }) => void;
}

export default function ReservationCalendar({
reservations,
selectedDateKey,
onSelectDate,
}: Props) {
const today = new Date();

const { year, month, prevMonth, nextMonth } = useCalendar(
today.getFullYear(),
today.getMonth(),
);

const calendarDates = getMonthCalendar(year, month);
const reservationMap = mapReservationsToCalendar(reservations);

return (
<div className="relative border border-white rounded-2xl pt-5 pb-2.5 shadow-xl">
<CalendarHeader
year={year}
month={month}
onPrev={prevMonth}
onNext={nextMonth}
/>
<CalendarGrid
dates={calendarDates}
badgesMap={reservationMap}
selectedDateKey={selectedDateKey}
onSelectDate={onSelectDate}
/>

</div>
);
}
27 changes: 27 additions & 0 deletions feature/reservationStatus/Calendar/StatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {
ReservationStatusCode,
RESERVATION_STATUS_LABEL,
} from "@/feature/reservationStatus/types/reservationStatus";

interface StatusBadgeProps {
status: ReservationStatusCode;
count: number;
}

const STYLE_MAP: Record<ReservationStatusCode, string> = {
pending: "bg-blue-50 text-blue-500",
confirmed: "bg-orange-50 text-orange-500",
declined: "bg-red-50 text-red-500",
canceled: "bg-gray-100 text-gray-400",
completed: "bg-gray-100 text-gray-500",
};

export function StatusBadge({ status, count }: StatusBadgeProps) {
return (
<div
className={`rounded-md px-2.5 py-0.5 text-14-m ${STYLE_MAP[status]}`}
>
{RESERVATION_STATUS_LABEL[status]} {count}
</div>
);
}
Loading