From 268b5da4dc142f5fb10577bd20a59cf5a0341ec7 Mon Sep 17 00:00:00 2001 From: Dew Date: Wed, 6 May 2026 20:27:56 +0900 Subject: [PATCH 1/6] =?UTF-8?q?refactor:=20=EA=B3=B5=EC=9A=A9=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B0=8F=20DTO=EB=A5=BC=20types=20=ED=8F=B4?= =?UTF-8?q?=EB=8D=94=EB=A1=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/adapters/store.adapter.ts | 3 +- src/api/axios.ts | 9 +- src/api/bookings.ts | 31 +----- src/api/dto/store.dto.ts | 37 ------- src/api/endpoints/bookings.ts | 40 +------ src/api/endpoints/member.ts | 47 ++------ src/api/endpoints/menus.ts | 27 +---- src/api/endpoints/payments.ts | 34 +----- src/api/endpoints/reservations.ts | 82 +++----------- src/api/inquiry.ts | 6 +- src/api/owner/menus.ts | 66 ++--------- src/api/owner/reservation.ts | 43 ++------ src/api/owner/storeLayout.ts | 41 +------ src/api/owner/stores.ts | 60 ++-------- src/api/owner/table.ts | 30 +---- .../customer-support/support.schema.ts | 5 - src/components/owner/AddTableModal.tsx | 2 +- src/components/owner/BreakTimeModal.tsx | 5 +- src/components/owner/MenuManagement.tsx | 6 +- src/components/owner/StoreSettings.tsx | 3 +- src/components/owner/menuFormModal.tsx | 10 +- src/components/owner/tableDashboard.tsx | 25 +++-- src/components/owner/tableDetailModal.tsx | 13 +-- .../reservation/modals/PaymentModal.tsx | 2 +- .../modals/ReservationConfirmModal.tsx | 2 +- src/hooks/reservation/useAvailableTables.ts | 3 +- src/hooks/store/useRestaurantDetail.ts | 2 +- src/hooks/store/useSearchStores.ts | 58 ++-------- src/pages/SearchPage.tsx | 2 +- src/pages/myPage/storePage.tsx | 3 +- src/types/api.ts | 7 ++ src/types/booking.ts | 58 +++++++++- src/types/inquiry.ts | 4 + src/types/layout.ts | 40 +++++++ src/types/member.ts | 24 ++++ src/types/menus.ts | 72 ++++++++++++ src/types/payment.ts | 19 ++++ src/types/reservation.ts | 94 ++++++++++++++++ src/types/store.ts | 104 ++++++++++++++++++ src/types/table.ts | 24 ++++ 40 files changed, 559 insertions(+), 584 deletions(-) delete mode 100644 src/api/dto/store.dto.ts create mode 100644 src/types/inquiry.ts create mode 100644 src/types/layout.ts create mode 100644 src/types/member.ts create mode 100644 src/types/reservation.ts diff --git a/src/api/adapters/store.adapter.ts b/src/api/adapters/store.adapter.ts index 888b174..2102676 100644 --- a/src/api/adapters/store.adapter.ts +++ b/src/api/adapters/store.adapter.ts @@ -1,5 +1,4 @@ -import type { StoreDetailDataDTO } from "@/api/dto/store.dto"; -import type { BreakTime, RestaurantDetail } from "@/types/store"; +import type { BreakTime, RestaurantDetail, StoreDetailDataDTO } from "@/types/store"; export function toRestaurantDetail(dto: StoreDetailDataDTO): RestaurantDetail { const breakTime = toBreakTime(dto.breakStartTime, dto.breakEndTime); diff --git a/src/api/axios.ts b/src/api/axios.ts index 2cfabb6..5606ff9 100644 --- a/src/api/axios.ts +++ b/src/api/axios.ts @@ -1,7 +1,7 @@ import axios, { type AxiosError, type InternalAxiosRequestConfig } from "axios"; import { useAuthStore } from "@/stores/useAuthStore"; -import type { ApiError } from "@/types/api"; +import type { ApiError, ApiResponseWithFlags } from "@/types/api"; import { isApiResponse, normalizeApiError } from "./api.error"; import { clearAuth, postRefresh } from "./auth"; @@ -38,13 +38,6 @@ api.interceptors.request.use((config: InternalAxiosRequestConfig) => { let refreshPromise: ReturnType | null = null; -type ApiResponseWithFlags = { - code?: string; - message?: string; - success?: boolean; - isSuccess?: boolean; -}; - api.interceptors.response.use( (res) => { const data = res.data; diff --git a/src/api/bookings.ts b/src/api/bookings.ts index 024635c..2e5feb7 100644 --- a/src/api/bookings.ts +++ b/src/api/bookings.ts @@ -1,33 +1,6 @@ -import { api } from "./axios"; - -type ApiBookingStatus = "PENDING" | "CONFIRMED" | "COMPLETED" | "CANCELED"; - -interface Booking { - bookingId: number; - storeName: string; - storeAddress: string; - bookingDate: string; - bookingTime: string; - partySize: number; - tableNumbers: string; - amount: number | null; - paymentMethod: string; - status: ApiBookingStatus; -} +import type { ApiBookingStatus, BookingResponse, GetBookingParams } from "@/types/booking"; -interface BookingResponse { - bookingList: Booking[]; - listSize: number; - totalPage: number; - totalElements: number; - isFirst: boolean; - isLast: boolean; -} - -type GetBookingParams = { - page: number; - status?: ApiBookingStatus; -}; +import { api } from "./axios"; export const getBookings = async ( status?: ApiBookingStatus, diff --git a/src/api/dto/store.dto.ts b/src/api/dto/store.dto.ts deleted file mode 100644 index ce40038..0000000 --- a/src/api/dto/store.dto.ts +++ /dev/null @@ -1,37 +0,0 @@ -export type CategoryDTO = "KOREAN" | "CHINESE" | "JAPANESE" | "WESTERN" | "CAFE"; - -export type DayDTO = - | "MONDAY" - | "TUESDAY" - | "WEDNESDAY" - | "THURSDAY" - | "FRIDAY" - | "SATURDAY" - | "SUNDAY"; - -export type BusinessHourDTO = { - day: DayDTO; - openTime: string | null; - closeTime: string | null; - isClosed: boolean; -}; - -export type StoreDetailDataDTO = { - storeId: number | string; - storeName: string; - description: string; - address: string; - phone: string; - category: CategoryDTO; - rating: number; - reviewCount: number | null; - mainImageUrl?: string | null; - tableImageUrls: string[] | null; - businessHours: BusinessHourDTO[] | null; - breakStartTime?: string | null; - breakEndTime?: string | null; - isOpenNow?: boolean; - - depositAmount: number; - depositRate?: number | null; -}; diff --git a/src/api/endpoints/bookings.ts b/src/api/endpoints/bookings.ts index 9619b5b..10f993b 100644 --- a/src/api/endpoints/bookings.ts +++ b/src/api/endpoints/bookings.ts @@ -1,41 +1,9 @@ -import { api } from "../axios"; - -type APiResult = { - isSucceess?: boolean; - success?: boolean; - code?: string; - message?: string; - result: T; -}; +import type { ApiResponse } from "@/types/api"; +import type { UserBookingsResult } from "@/types/booking"; -type BookingListItem = { - bookingId: number; - storeName: string; - storeAddress: string; - bookingDate: string; - bookingTime: { - hour: number; - minute: number; - second: number; - nano: number; - }; - partySize: number; - tableNumbers: string; - amount: number; - paymentMethod: string; - status: string; -}; - -type UserBookingsResult = { - bookingList: BookingListItem[]; - listSize: number; - totalPage: number; - totalElements: number; - isFirst: boolean; - isLast: boolean; -}; +import { api } from "../axios"; export async function getUserBookings(page = 1) { - const res = await api.get>(`/api/v1/users/bookings?page=${page}`); + const res = await api.get>(`/api/v1/users/bookings?page=${page}`); return res.data.result; } diff --git a/src/api/endpoints/member.ts b/src/api/endpoints/member.ts index 07cb053..8be0605 100644 --- a/src/api/endpoints/member.ts +++ b/src/api/endpoints/member.ts @@ -1,61 +1,38 @@ -import { api } from "../axios"; +import type { ApiResponse } from "@/types/api"; +import type { + ChangePasswordRequest, + ChangePasswordResponse, + MemberInfo, + PatchMemberInfo, +} from "@/types/member"; -type ApiEnvelope = { - isSuccess?: boolean; - success?: boolean; - code?: string; - message?: string; - result: T; -}; +import { api } from "../axios"; -type MemberInfo = { - id: number; - profileImage: string | null; - email: string; - name: string; - phoneNumber: string; -}; export async function getMemberInfo() { - const res = await api.get>("/api/v1/member/info"); + const res = await api.get>("/api/v1/member/info"); if (!res.data.isSuccess || !res.data.result) { throw new Error(res.data.message ?? "회원정보 조회 실패"); } return res.data.result; } -type PatchMemberInfo = { - name: string; - phoneNumber: string; -}; - export async function patchMemberInfo(body: PatchMemberInfo) { - const res = await api.patch>("/api/v1/member/info", body); + const res = await api.patch>("/api/v1/member/info", body); return res.data.result; } export async function putProfileImage(file: File) { const formData = new FormData(); formData.append("profileImage", file); - const res = await api.put>("/api/v1/member/profile-image", formData); + const res = await api.put>("/api/v1/member/profile-image", formData); if (!res.data.isSuccess) { throw new Error(res.data.message ?? "프로필 업로드 실패"); } return res.data.result; } -type ChangePasswordRequest = { - currentPassword: string; - newPassword: string; - newPasswordConfirm: string; -}; - -type ChangePasswordResponse = { - change: boolean; - changeAt: string; - message: string; -}; export async function putChangePassword(body: ChangePasswordRequest) { - const res = await api.put>("/api/v1/member/password", body); + const res = await api.put>("/api/v1/member/password", body); if (!res.data?.isSuccess) { throw new Error(res.data.message ?? "비밀번호 변경에 실패했습니다"); } diff --git a/src/api/endpoints/menus.ts b/src/api/endpoints/menus.ts index 39a0184..5d58373 100644 --- a/src/api/endpoints/menus.ts +++ b/src/api/endpoints/menus.ts @@ -1,31 +1,10 @@ -import type { MenuCategory, MenuItem } from "@/types/menus"; +import type { ApiResponse } from "@/types/api"; +import type { MenuCategory, MenuItem, MenuListResult } from "@/types/menus"; import { api } from "../axios"; -type ApiResult = { - isSuccess?: boolean; - success?: boolean; - code?: string; - message?: string; - result: T; -}; - -type MenuDto = { - menuId: number; - name: string; - description?: string; - price: number; - category: MenuCategory | string; - imageUrl?: string; - isSoldOut: boolean; -}; - -type MenuListResult = { - menus: MenuDto[]; -}; - export async function getMenus(storeId: string): Promise { - const { data } = await api.get>(`/api/v1/stores/${storeId}/menus`); + const { data } = await api.get>(`/api/v1/stores/${storeId}/menus`); if (!data?.isSuccess) { throw { status: 0, diff --git a/src/api/endpoints/payments.ts b/src/api/endpoints/payments.ts index 5cb528e..827b32a 100644 --- a/src/api/endpoints/payments.ts +++ b/src/api/endpoints/payments.ts @@ -1,23 +1,10 @@ -import { api } from "../axios"; - -type ApiEnvelope = { - isSuccess?: boolean; - success?: boolean; - code?: string; - message?: string; - result: T; -}; +import type { ApiResponse } from "@/types/api"; +import type { PaymentConfirmResult, PaymentRequestResult } from "@/types/payment"; -type PaymentRequestResult = { - paymentId: number; - bookingId: number; - orderId: string; - amount: number; - requestedAt: string; -}; +import { api } from "../axios"; export async function requestPayment(body: { bookingId: number }) { - const res = await api.post>(`/api/v1/payments/request`, body); + const res = await api.post>(`/api/v1/payments/request`, body); if (!res.data?.isSuccess) { throw { status: 0, @@ -28,23 +15,12 @@ export async function requestPayment(body: { bookingId: number }) { return res.data.result; } -type PaymentConfirmResult = { - paymentId: number; - status: string; - approvedAt: string; - orderId: string; - amount: number; - paymentMethod: string; - paymentProvider: string; - receiptUrl: string; -}; - export async function confirmPayment(body: { paymentKey: string; orderId: string; amount: number; }) { - const res = await api.post>("/api/v1/payments/confirm", body); + const res = await api.post>("/api/v1/payments/confirm", body); if (!res.data?.isSuccess) { throw new Error(res.data?.message ?? "결제 승인에 실패했습니다."); } diff --git a/src/api/endpoints/reservations.ts b/src/api/endpoints/reservations.ts index 9ce56c4..23a6b53 100644 --- a/src/api/endpoints/reservations.ts +++ b/src/api/endpoints/reservations.ts @@ -1,27 +1,19 @@ -import { api } from "../axios"; - -type ApiResult = { - isSuccess: boolean; - code: string; - message: string; - result: T; -}; - -type GetAvailableTimesParams = { - storeId: string | number; - date: string; - partySize: number; - isSplitAccepted: boolean; -}; +import type { ApiResponse } from "@/types/api"; +import type { + AvailableTablesResult, + AvailableTimesResult, + CreateBookingBody, + CreateBookingResult, + GetAvailableTablesParams, + GetAvailableTimesParams, +} from "@/types/reservation"; -type AvailableTimesResult = { - availableTimes: string[]; -}; +import { api } from "../axios"; export async function getAvailableTimes(params: GetAvailableTimesParams): Promise { const { storeId, ...query } = params; - const { data } = await api.get>( + const { data } = await api.get>( `/api/v1/stores/${storeId}/bookings/available-times`, { params: query }, ); @@ -36,36 +28,9 @@ export async function getAvailableTimes(params: GetAvailableTimesParams): Promis return data.result?.availableTimes ?? []; } -type SeatsTypes = "WINDOW" | "GENERAL" | string; - -type AvailableTable = { - tableId: number; - tableNumber: string; - tableSeats: number; - seatsType: SeatsTypes; - gridX: number; - gridY: number; - widthSpan: number; - heightSpan: number; -}; -export type GetAvailableTablesParams = { - storeId: string | number; - date: string; - time: string; - partySize: number; - isSplitAccepted: boolean; - seatsType?: string; -}; - -type AvailableTablesResult = { - rows: number; - cols: number; - tables: AvailableTable[]; -}; - export async function getAvailableTables(params: GetAvailableTablesParams) { const { storeId, ...query } = params; - const { data } = await api.get>( + const { data } = await api.get>( `/api/v1/stores/${storeId}/bookings/available-tables`, { params: query }, ); @@ -80,33 +45,12 @@ export async function getAvailableTables(params: GetAvailableTablesParams) { return data.result; } -type CreateBookingBody = { - date: string; - time: string; - partySize: number; - tableIds: number[]; - menuItems: { menuId: number; quantity: number }[]; - isSplitAccepted: boolean; -}; - -export type CreateBookingResult = { - bookingId: number; - status: "PENDING" | "CONFIRMED" | string; - storeName: string; - date: string; - time: string; - partySize: number; - totalDeposit: number; - paymentId?: number; - orderId: string; -}; - export async function createBooking(params: { storeId: string | number; body: CreateBookingBody; }): Promise { const { storeId, body } = params; - const { data } = await api.post>( + const { data } = await api.post>( `/api/v1/stores/${storeId}/bookings`, body, ); diff --git a/src/api/inquiry.ts b/src/api/inquiry.ts index 36c2a08..a09db77 100644 --- a/src/api/inquiry.ts +++ b/src/api/inquiry.ts @@ -1,8 +1,6 @@ -import type { - ResponseInquiryDTO, - SupportFormValues, -} from "@/components/customer-support/support.schema"; +import type { SupportFormValues } from "@/components/customer-support/support.schema"; import type { ApiResponse } from "@/types/api"; +import type { ResponseInquiryDTO } from "@/types/inquiry"; import { api } from "./axios"; diff --git a/src/api/owner/menus.ts b/src/api/owner/menus.ts index c00637e..f89661b 100644 --- a/src/api/owner/menus.ts +++ b/src/api/owner/menus.ts @@ -1,67 +1,17 @@ import axios from "axios"; import type { ApiResponse } from "@/types/api"; +import type { + DeleteMenusResponse, + GetMenusResult, + MenuCreateItem, + MenuCreateResult, + MenuUpdateItem, + MenuUpdateResult, +} from "@/types/menus"; import { api } from "../axios"; -interface ServerMenu { - menuId: number; - name: string; - description?: string | null; - price: number; - category?: string | null; - imageUrl?: string | null; - isSoldOut?: boolean; -} - -interface GetMenusResult { - menus: ServerMenu[]; -} - -export interface MenuUpdateItem { - name: string; - description?: string; - price: number; - category: string; - imageKey?: string; -} - -interface MenuUpdateResult { - menuId: number; - name: string; - description?: string; - price: number; - category?: string; - imageUrl?: string; -} - -interface MenuCreateItem { - name: string; - description?: string; - price: number; - category: string; - imageKey?: string; -} - -interface MenuCreateResult { - menus: { - menuId: number; - name: string; - description?: string; - price: number; - category?: string; - imageUrl?: string; - imageKey?: string; - }[]; -} - -interface DeleteMenusResponse { - isSuccess: boolean; - code: string; - result: { deletedMenuIds: number[] }; - message: string; -} - export async function getMenus(storeId: string | number) { const res = await api.get>(`/api/v1/stores/${storeId}/menus`); return res.data; diff --git a/src/api/owner/reservation.ts b/src/api/owner/reservation.ts index f050b7d..459378f 100644 --- a/src/api/owner/reservation.ts +++ b/src/api/owner/reservation.ts @@ -1,43 +1,14 @@ import type { ApiResponse } from "@/types/api"; +import type { + BookingDetailResult, + GetSlotsResult, + PatchBreakTimeRequest, + UpdateSlotRequest, + UpdateSlotResult, +} from "@/types/reservation"; import { api } from "../axios"; -export interface Slot { - time: string; - status: "AVAILABLE" | "BOOKED" | "BLOCKED"; - isAvailable: boolean; - bookingId: number | null; -} - -interface GetSlotsResult { - slots: Slot[]; -} - -export type SlotStatus = "AVAILABLE" | "BLOCKED"; - -export interface UpdateSlotRequest { - targetDate: string; - startTime: string; - status: SlotStatus; -} - -interface UpdateSlotResult { - targetDate: string; - startTime: string; - status: SlotStatus; -} - -interface PatchBreakTimeRequest { - breakStartTime: string; - breakEndTime: string; -} - -interface BookingDetailResult { - bookerName: string; - partySize: number; - amount: number; -} - export const getTableSlots = (storeId: number, tableId: number, date: string) => api.get>(`/api/v1/stores/${storeId}/tables/${tableId}/slots`, { params: { date }, diff --git a/src/api/owner/storeLayout.ts b/src/api/owner/storeLayout.ts index cae1d9e..ee1c760 100644 --- a/src/api/owner/storeLayout.ts +++ b/src/api/owner/storeLayout.ts @@ -1,49 +1,10 @@ import axios from "axios"; import type { ApiResponse } from "@/types/api"; -import type { SeatsType } from "@/types/table"; +import type { CreateTableRequest, CreateTableResponse, LayoutResponse } from "@/types/layout"; import { api } from "../axios"; -export interface LayoutTable { - tableId: number; - tableNumber: string; - minSeatCount: number; - maxSeatCount: number; - gridX: number; - gridY: number; - widthSpan: number; - heightSpan: number; - tableImageUrl: string | null; - seatsType: SeatsType; -} - -interface LayoutResponse { - layoutId: number; - totalTableCount: number; - gridInfo: { gridCol: number; gridRow: number }; - tables: LayoutTable[]; -} - -export interface CreateTableRequest { - gridX: number; - gridY: number; - minSeatCount: number; - maxSeatCount: number; - seatsType: SeatsType; -} - -interface CreateTableResponse { - tableId: number; - tableNumber: string; - minSeatCount: number; - maxSeatCount: number; - seatsType: string; - gridX: number; - gridY: number; - tableImageUrl: string | null; -} - export const getActiveLayout = async (storeId: number): Promise => { try { const res = await api.get(`/api/v1/stores/${storeId}/layouts`); diff --git a/src/api/owner/stores.ts b/src/api/owner/stores.ts index 4d8c6df..68f0cef 100644 --- a/src/api/owner/stores.ts +++ b/src/api/owner/stores.ts @@ -1,56 +1,14 @@ import { api } from "@/api/axios"; import type { ApiResponse } from "@/types/api"; -import type { UpdateStoreResponse } from "@/types/store"; - -interface StoreDetail { - storeId: number; - storeName: string; - description: string; - address: string; - phone: string; - businessHours?: BusinessHour[]; - isApproved: boolean; - rating?: number; - reviewCount?: number; -} - -interface BusinessHour { - day: "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY"; - openTime: string | null; - closeTime: string | null; - isClosed: boolean; -} - -export interface MyStore { - storeId: number; - storeName: string; - address: string; - category: string; - rating: number; - totalBookingCount: number; - reviewCount: number; - mainImageUrl: string; - isOpenNow: boolean; -} - -interface MyStoreResponse { - isSuccess: boolean; - code: string; - message: string; - result: { - stores: MyStore[]; - }; -} - -export interface TableImage { - tableImageId: number; - tableImageUrl: string; -} - -interface TableImagesResponse { - storeId: number; - tableImages: TableImage[]; -} +import type { + BusinessHour, + MyStore, + MyStoreResponse, + StoreDetail, + TableImage, + TableImagesResponse, + UpdateStoreResponse, +} from "@/types/store"; export function getStore(storeId: number | string) { return api.get>(`/api/v1/stores/${storeId}`); diff --git a/src/api/owner/table.ts b/src/api/owner/table.ts index 2cec825..602f2b0 100644 --- a/src/api/owner/table.ts +++ b/src/api/owner/table.ts @@ -1,33 +1,15 @@ import type { AxiosProgressEvent } from "axios"; import type { ApiResponse } from "@/types/api"; +import type { + DeleteTableImageResult, + PatchTableRequest, + UpdatedTable, + UploadTableImageResult, +} from "@/types/table"; import { api } from "../axios"; -interface UploadTableImageResult { - tableId: number; - tableImageUrl: string; -} - -interface DeleteTableImageResult { - tableId: number; -} - -export interface PatchTableRequest { - tableNumber?: string; - minSeatCount?: number; - maxSeatCount?: number; - seatsType?: "GENERAL" | "WINDOW" | "ROOM" | "BAR" | "OUTDOOR"; -} - -export interface UpdatedTable { - tableId: number; - tableNumber: string; - minSeatCount: number; - maxSeatCount: number; - seatsType: string; -} - export const uploadTableImage = ( storeId: number, tableId: number, diff --git a/src/components/customer-support/support.schema.ts b/src/components/customer-support/support.schema.ts index 51f8155..e17ccfa 100644 --- a/src/components/customer-support/support.schema.ts +++ b/src/components/customer-support/support.schema.ts @@ -25,8 +25,3 @@ export const supportSchema = z.object({ }); export type SupportFormValues = z.infer; - -export interface ResponseInquiryDTO { - id: number; - createdAt: string; -} diff --git a/src/components/owner/AddTableModal.tsx b/src/components/owner/AddTableModal.tsx index da1ac8e..69453e4 100644 --- a/src/components/owner/AddTableModal.tsx +++ b/src/components/owner/AddTableModal.tsx @@ -1,7 +1,7 @@ import { Check, X } from "lucide-react"; import React, { useEffect, useRef, useState } from "react"; -import type { CreateTableRequest } from "@/api/owner/storeLayout"; +import type { CreateTableRequest } from "@/types/layout"; import type { SeatsType } from "@/types/table"; interface AddTableModalProps { diff --git a/src/components/owner/BreakTimeModal.tsx b/src/components/owner/BreakTimeModal.tsx index 8ddf6fa..504c5b2 100644 --- a/src/components/owner/BreakTimeModal.tsx +++ b/src/components/owner/BreakTimeModal.tsx @@ -1,10 +1,7 @@ import { Clock, X } from "lucide-react"; import React, { useState } from "react"; -export interface BreakTime { - start: string; - end: string; -} +import type { BreakTime } from "@/types/store"; interface Props { openTime: string; diff --git a/src/components/owner/MenuManagement.tsx b/src/components/owner/MenuManagement.tsx index b33810f..36fb722 100644 --- a/src/components/owner/MenuManagement.tsx +++ b/src/components/owner/MenuManagement.tsx @@ -15,7 +15,7 @@ interface Category { label: string; } -type ServerMenu = { +type MenuDraft = { menuId?: number | string; name?: string; description?: string; @@ -48,7 +48,7 @@ const MenuManagement: React.FC = ({ storeId }) => { const [isModalOpen, setIsModalOpen] = useState(false); const [editingMenu, setEditingMenu] = useState(null); - const mapServerToLocal = (s: ServerMenu, restaurantId?: string): MenuItem => ({ + const mapServerToLocal = (s: MenuDraft, restaurantId?: string): MenuItem => ({ id: String(s.menuId ?? `MENU_${crypto.randomUUID()}`), restaurantId: restaurantId ?? "", name: s.name ?? "", @@ -86,7 +86,7 @@ const MenuManagement: React.FC = ({ storeId }) => { try { const res = await getMenus(restaurantId); if (res.isSuccess && res.result && Array.isArray(res.result.menus)) { - const serverMenus = (res.result.menus as ServerMenu[]).map((menu) => + const serverMenus = (res.result.menus as MenuDraft[]).map((menu) => mapServerToLocal(menu, restaurantId), ); diff --git a/src/components/owner/StoreSettings.tsx b/src/components/owner/StoreSettings.tsx index 274b8dc..908ea76 100644 --- a/src/components/owner/StoreSettings.tsx +++ b/src/components/owner/StoreSettings.tsx @@ -5,12 +5,11 @@ import { deleteTableImages, getStore, getTableImages, - type TableImage, updateBusinessHours, updateStore, uploadTableImages, } from "@/api/owner/stores"; -import type { Day } from "@/types/store"; +import type { Day, TableImage } from "@/types/store"; interface StoreSettingsProps { storeId?: string; diff --git a/src/components/owner/menuFormModal.tsx b/src/components/owner/menuFormModal.tsx index 9982c7d..dd4b5bb 100644 --- a/src/components/owner/menuFormModal.tsx +++ b/src/components/owner/menuFormModal.tsx @@ -1,14 +1,8 @@ import { X } from "lucide-react"; import React, { useEffect, useState } from "react"; -import { - createMenus, - deleteMenuImage, - type MenuUpdateItem, - updateMenu, - uploadMenuImage, -} from "@/api/owner/menus"; -import type { MenuCategory, MenuItem } from "@/types/menus"; +import { createMenus, deleteMenuImage, updateMenu, uploadMenuImage } from "@/api/owner/menus"; +import type { MenuCategory, MenuItem, MenuUpdateItem } from "@/types/menus"; interface MenuFormModalProps { isOpen: boolean; diff --git a/src/components/owner/tableDashboard.tsx b/src/components/owner/tableDashboard.tsx index dce9772..c14ff97 100644 --- a/src/components/owner/tableDashboard.tsx +++ b/src/components/owner/tableDashboard.tsx @@ -3,20 +3,20 @@ import { Check, Clock, Lightbulb, Pencil, Plus, Store, X } from "lucide-react"; import React, { useEffect, useState } from "react"; import { patchBreakTime } from "@/api/owner/reservation"; +import { createLayout, createTable, deleteTable, getActiveLayout } from "@/api/owner/storeLayout"; +import { patchTableInfo } from "@/api/owner/table"; +import type { CreateTableRequest, LayoutTable } from "@/types/layout"; +import type { BreakTime } from "@/types/store"; import { - createLayout, - createTable, - type CreateTableRequest, - deleteTable, - getActiveLayout, - type LayoutTable, -} from "@/api/owner/storeLayout"; -import { patchTableInfo, type PatchTableRequest, type UpdatedTable } from "@/api/owner/table"; -import { SEATS_TYPE_LABEL, type SeatsType } from "@/types/table"; + type PatchTableRequest, + SEATS_TYPE_LABEL, + type SeatsType, + type UpdatedTable, +} from "@/types/table"; import { getErrorMessage } from "@/utils/error"; import AddTableModal from "./AddTableModal"; -import BreakTimeModal, { type BreakTime } from "./BreakTimeModal"; +import BreakTimeModal from "./BreakTimeModal"; import TableCreateModal from "./TableCreateModal"; import TableDetailModal from "./tableDetailModal"; @@ -241,7 +241,7 @@ const TableDashboard: React.FC = ({ storeId, storeName }) = })), ); - setTableData(mapTablesFromApi(layout.tables, layout.gridInfo.gridCol, tableData)); + setTableData((prev) => mapTablesFromApi(layout.tables, layout.gridInfo.gridCol, prev)); setCreateModalOpen(false); } else { setCreateModalOpen(true); @@ -253,7 +253,8 @@ const TableDashboard: React.FC = ({ storeId, storeName }) = }; fetchLayout(); - }, [storeId, tableData]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [storeId]); const handleCreateLayout = async (columns: number, rows: number) => { if (!storeId) return; diff --git a/src/components/owner/tableDetailModal.tsx b/src/components/owner/tableDetailModal.tsx index 80ba7b5..c49ec0b 100644 --- a/src/components/owner/tableDetailModal.tsx +++ b/src/components/owner/tableDetailModal.tsx @@ -15,7 +15,6 @@ import { } from "lucide-react"; import React, { useEffect, useState } from "react"; -import type { Slot, SlotStatus, UpdateSlotRequest } from "@/api/owner/reservation"; import { cancelBookingByOwner, getBookingDetail, @@ -23,11 +22,11 @@ import { updateTableSlotStatus, } from "@/api/owner/reservation"; import { deleteTableImage, patchTableInfo, uploadTableImage } from "@/api/owner/table"; +import type { BookingDetailResult, Slot, SlotStatus, UpdateSlotRequest } from "@/types/reservation"; +import type { BreakTime } from "@/types/store"; import { SEATS_TYPE_LABEL, type SeatsType } from "@/types/table"; import { getErrorMessage } from "@/utils/error"; -import type { BreakTime } from "./BreakTimeModal"; - interface TableInfo { minCapacity: number; maxCapacity: number; @@ -52,12 +51,6 @@ interface Props { type Step = "DETAIL" | "CALENDAR" | "SLOTS"; -type BookingDetail = { - bookerName: string; - partySize: number; - amount: number; -}; - const TableDetailModal: React.FC = ({ storeId, tableNumber, @@ -82,7 +75,7 @@ const TableDetailModal: React.FC = ({ const [loading, setLoading] = useState(false); const [error, setError] = useState(null); - const [bookingDetail, setBookingDetail] = useState(null); + const [bookingDetail, setBookingDetail] = useState(null); const [detailLoading, setDetailLoading] = useState(false); const [showBookingDetail, setShowBookingDetail] = useState(false); const [detailError, setDetailError] = useState(null); diff --git a/src/components/reservation/modals/PaymentModal.tsx b/src/components/reservation/modals/PaymentModal.tsx index 821a7a2..c2374e2 100644 --- a/src/components/reservation/modals/PaymentModal.tsx +++ b/src/components/reservation/modals/PaymentModal.tsx @@ -4,13 +4,13 @@ import { useEffect, useMemo, useRef, useState } from "react"; import { useNavigate } from "react-router-dom"; import { requestPayment } from "@/api/endpoints/payments"; -import type { CreateBookingResult } from "@/api/endpoints/reservations"; import { useConfirmClose } from "@/hooks/common/useConfirmClose"; import { useModalPresence } from "@/hooks/common/useModalPresence"; import { useDepositRate } from "@/hooks/reservation/useDepositRate"; import { useMenus } from "@/hooks/reservation/useMenus"; import { cn } from "@/lib/utils"; import { useUserId } from "@/stores/useAuthStore"; +import type { CreateBookingResult } from "@/types/reservation"; import type { ReservationDraft } from "@/types/restaurant"; import type { RestaurantDetail } from "@/types/store"; import { calcMenuTotal } from "@/utils/menu"; diff --git a/src/components/reservation/modals/ReservationConfirmModal.tsx b/src/components/reservation/modals/ReservationConfirmModal.tsx index 14610cc..1350b33 100644 --- a/src/components/reservation/modals/ReservationConfirmModal.tsx +++ b/src/components/reservation/modals/ReservationConfirmModal.tsx @@ -1,12 +1,12 @@ import { X } from "lucide-react"; -import type { CreateBookingResult } from "@/api/endpoints/reservations.ts"; import { useConfirmClose } from "@/hooks/common/useConfirmClose"; import { useModalPresence } from "@/hooks/common/useModalPresence"; import { useCreateBooking } from "@/hooks/reservation/useCreateBooking"; import { useDepositRate } from "@/hooks/reservation/useDepositRate"; import { useMenus } from "@/hooks/reservation/useMenus"; import { cn } from "@/lib/utils"; +import type { CreateBookingResult } from "@/types/reservation"; import type { ReservationDraft } from "@/types/restaurant"; import type { RestaurantDetail } from "@/types/store"; import { toYmd } from "@/utils/date"; diff --git a/src/hooks/reservation/useAvailableTables.ts b/src/hooks/reservation/useAvailableTables.ts index 36d263a..8853fc7 100644 --- a/src/hooks/reservation/useAvailableTables.ts +++ b/src/hooks/reservation/useAvailableTables.ts @@ -1,7 +1,8 @@ import { useQuery } from "@tanstack/react-query"; -import { getAvailableTables, type GetAvailableTablesParams } from "@/api/endpoints/reservations"; +import { getAvailableTables } from "@/api/endpoints/reservations"; import { queryKeys } from "@/query/keys"; +import type { GetAvailableTablesParams } from "@/types/reservation"; export function useAvailableTables(params: GetAvailableTablesParams | null) { return useQuery({ diff --git a/src/hooks/store/useRestaurantDetail.ts b/src/hooks/store/useRestaurantDetail.ts index 22dda3b..acc14f4 100644 --- a/src/hooks/store/useRestaurantDetail.ts +++ b/src/hooks/store/useRestaurantDetail.ts @@ -2,8 +2,8 @@ import { useQuery } from "@tanstack/react-query"; import { toRestaurantDetail } from "@/api/adapters/store.adapter"; import { api } from "@/api/axios"; -import type { StoreDetailDataDTO } from "@/api/dto/store.dto"; import { queryKeys } from "@/query/keys"; +import type { StoreDetailDataDTO } from "@/types/store"; export function useRestaurantDetail(storeId: number | null) { return useQuery({ diff --git a/src/hooks/store/useSearchStores.ts b/src/hooks/store/useSearchStores.ts index 47431c3..be680da 100644 --- a/src/hooks/store/useSearchStores.ts +++ b/src/hooks/store/useSearchStores.ts @@ -1,53 +1,13 @@ import { useQuery } from "@tanstack/react-query"; import { api } from "@/api/axios"; -import type { Category, RestaurantSummary } from "@/types/store"; - -type Params = { - keyword: string; - lat: number; - lng: number; - radius?: number; - category?: "KOREAN" | "CHINESE" | "JAPANESE" | "WESTERN" | "CAFE"; - sort?: "DISTANCE" | "RATING"; - page?: number; - limit?: number; - sido?: string; - sigungu?: string; - bname?: string; -}; - -type ApiStoreSummary = { - storeId: number; - name: string; - address: string; - category: Category; - rating: number | null; - reviewCount: number | null; - distance?: number | null; - mainImageUrl?: string | null; - isOpenNow?: boolean | null; - latitude?: number | string | null; - longitude?: number | string | null; - lat?: number | string | null; - lng?: number | string | null; -}; - -type ApiResponse = { - isSuccess: boolean; - code: string; - message: string; - result: { - stores: ApiStoreSummary[]; - pagination: { - page: number; - limit: number; - totalCount: number; - totalPages: number; - hasNext: boolean; - }; - }; -}; +import type { ApiResponse } from "@/types/api"; +import type { + ApiStoreSummary, + RestaurantSummary, + SearchStoreParams, + SearchStoresResult, +} from "@/types/store"; const toNum = (v: unknown): number | undefined => { if (v == null) return undefined; @@ -72,7 +32,7 @@ function toSummary(s: ApiStoreSummary): RestaurantSummary { }; } -export function useSearchStores(params: Params | null) { +export function useSearchStores(params: SearchStoreParams | null) { return useQuery({ queryKey: ["searchStores", params], enabled: !!params && !!params.keyword, @@ -92,7 +52,7 @@ export function useSearchStores(params: Params | null) { if (params.sigungu) cleanParams.sigungu = params.sigungu; if (params.bname) cleanParams.bname = params.bname; - const res = await api.get("/api/v1/stores/search", { + const res = await api.get>("/api/v1/stores/search", { params: cleanParams, }); diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index d7d0f3d..3a551dd 100644 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -1,7 +1,6 @@ import { Search } from "lucide-react"; import { useEffect, useMemo, useState } from "react"; -import type { CreateBookingResult } from "@/api/endpoints/reservations"; import KakaoMap from "@/components/map/KakaoMap"; import PaymentModal from "@/components/reservation/modals/PaymentModal"; import ReservationConfirmMoodal from "@/components/reservation/modals/ReservationConfirmModal"; @@ -14,6 +13,7 @@ import { useRestaurantDetail } from "@/hooks/store/useRestaurantDetail"; import { useSearchStores } from "@/hooks/store/useSearchStores"; import type { KakaoAddressSearchResult, KakaoAddressSearchStatus } from "@/types/kakao"; import type { LatLng } from "@/types/map"; +import type { CreateBookingResult } from "@/types/reservation"; import type { ReservationDraft } from "@/types/restaurant"; import type { RestaurantSummary } from "@/types/store"; import { toHHmm } from "@/utils/time"; diff --git a/src/pages/myPage/storePage.tsx b/src/pages/myPage/storePage.tsx index eecab15..d09c4d7 100644 --- a/src/pages/myPage/storePage.tsx +++ b/src/pages/myPage/storePage.tsx @@ -2,8 +2,9 @@ import { BarChart3, Calendar, Plus, Star, Store } from "lucide-react"; import { useEffect, useState } from "react"; import { Link, useNavigate } from "react-router-dom"; -import { getMyStores, type MyStore } from "@/api/owner/stores"; +import { getMyStores } from "@/api/owner/stores"; import { cn } from "@/lib/utils"; +import type { MyStore } from "@/types/store"; export default function StorePage() { const [shops, setShops] = useState([]); diff --git a/src/types/api.ts b/src/types/api.ts index ae9c4a9..5774bd2 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -10,3 +10,10 @@ export interface ApiError { code?: string; message: string; } + +export interface ApiResponseWithFlags { + code?: string; + message?: string; + success?: boolean; + isSuccess?: boolean; +} diff --git a/src/types/booking.ts b/src/types/booking.ts index 79956fb..27971d6 100644 --- a/src/types/booking.ts +++ b/src/types/booking.ts @@ -1,3 +1,57 @@ -import type { getUserBookings } from "@/api/endpoints/bookings"; +export type ApiBookingStatus = "PENDING" | "CONFIRMED" | "COMPLETED" | "CANCELED"; -export type UserBookingItem = Awaited>["bookingList"][number]; +export interface Booking { + bookingId: number; + storeName: string; + storeAddress: string; + bookingDate: string; + bookingTime: string; + partySize: number; + tableNumbers: string; + amount: number | null; + paymentMethod: string; + status: ApiBookingStatus; +} + +export interface BookingResponse { + bookingList: Booking[]; + listSize: number; + totalPage: number; + totalElements: number; + isFirst: boolean; + isLast: boolean; +} + +export type GetBookingParams = { + page: number; + status?: ApiBookingStatus; +}; + +export type BookingListItem = { + bookingId: number; + storeName: string; + storeAddress: string; + bookingDate: string; + bookingTime: { + hour: number; + minute: number; + second: number; + nano: number; + }; + partySize: number; + tableNumbers: string; + amount: number; + paymentMethod: string; + status: ApiBookingStatus; +}; + +export type UserBookingsResult = { + bookingList: BookingListItem[]; + listSize: number; + totalPage: number; + totalElements: number; + isFirst: boolean; + isLast: boolean; +}; + +export type UserBookingItem = BookingListItem; diff --git a/src/types/inquiry.ts b/src/types/inquiry.ts new file mode 100644 index 0000000..e416757 --- /dev/null +++ b/src/types/inquiry.ts @@ -0,0 +1,4 @@ +export interface ResponseInquiryDTO { + id: number; + createdAt: string; +} diff --git a/src/types/layout.ts b/src/types/layout.ts new file mode 100644 index 0000000..3e555c8 --- /dev/null +++ b/src/types/layout.ts @@ -0,0 +1,40 @@ +import type { SeatsType } from "./table"; + +export interface LayoutTable { + tableId: number; + tableNumber: string; + minSeatCount: number; + maxSeatCount: number; + gridX: number; + gridY: number; + widthSpan: number; + heightSpan: number; + tableImageUrl: string | null; + seatsType: SeatsType; +} + +export interface LayoutResponse { + layoutId: number; + totalTableCount: number; + gridInfo: { gridCol: number; gridRow: number }; + tables: LayoutTable[]; +} + +export interface CreateTableRequest { + gridX: number; + gridY: number; + minSeatCount: number; + maxSeatCount: number; + seatsType: SeatsType; +} + +export interface CreateTableResponse { + tableId: number; + tableNumber: string; + minSeatCount: number; + maxSeatCount: number; + seatsType: string; + gridX: number; + gridY: number; + tableImageUrl: string | null; +} diff --git a/src/types/member.ts b/src/types/member.ts new file mode 100644 index 0000000..f281037 --- /dev/null +++ b/src/types/member.ts @@ -0,0 +1,24 @@ +export type MemberInfo = { + id: number; + profileImage: string | null; + email: string; + name: string; + phoneNumber: string; +}; + +export type PatchMemberInfo = { + name: string; + phoneNumber: string; +}; + +export type ChangePasswordRequest = { + currentPassword: string; + newPassword: string; + newPasswordConfirm: string; +}; + +export type ChangePasswordResponse = { + change: boolean; + changeAt: string; + message: string; +}; diff --git a/src/types/menus.ts b/src/types/menus.ts index 0050881..e7ad8a0 100644 --- a/src/types/menus.ts +++ b/src/types/menus.ts @@ -57,3 +57,75 @@ export type ResponseMenuImageDto = { imageKey: string; imageUrl: string; }; + +export interface ServerMenu { + menuId: number; + name: string; + description?: string | null; + price: number; + category?: string | null; + imageUrl?: string | null; + isSoldOut?: boolean; +} + +export interface GetMenusResult { + menus: ServerMenu[]; +} + +export interface MenuUpdateItem { + name: string; + description?: string; + price: number; + category: string; + imageKey?: string; +} + +export interface MenuUpdateResult { + menuId: number; + name: string; + description?: string; + price: number; + category?: string; + imageUrl?: string; +} + +export interface MenuCreateItem { + name: string; + description?: string; + price: number; + category: string; + imageKey?: string; +} + +export interface MenuCreateResult { + menus: { + menuId: number; + name: string; + description?: string; + price: number; + category?: string; + imageUrl?: string; + imageKey?: string; + }[]; +} + +export interface DeleteMenusResponse { + isSuccess: boolean; + code: string; + result: { deletedMenuIds: number[] }; + message: string; +} + +export type MenuDto = { + menuId: number; + name: string; + description?: string; + price: number; + category: MenuCategory | string; + imageUrl?: string; + isSoldOut: boolean; +}; + +export type MenuListResult = { + menus: MenuDto[]; +}; diff --git a/src/types/payment.ts b/src/types/payment.ts index 859d3c0..aa90d84 100644 --- a/src/types/payment.ts +++ b/src/types/payment.ts @@ -1 +1,20 @@ export type { DepositRate } from "@/types/store"; + +export type PaymentRequestResult = { + paymentId: number; + bookingId: number; + orderId: string; + amount: number; + requestedAt: string; +}; + +export type PaymentConfirmResult = { + paymentId: number; + status: string; + approvedAt: string; + orderId: string; + amount: number; + paymentMethod: string; + paymentProvider: string; + receiptUrl: string; +}; diff --git a/src/types/reservation.ts b/src/types/reservation.ts new file mode 100644 index 0000000..3d418ea --- /dev/null +++ b/src/types/reservation.ts @@ -0,0 +1,94 @@ +export interface Slot { + time: string; + status: "AVAILABLE" | "BOOKED" | "BLOCKED"; + isAvailable: boolean; + bookingId: number | null; +} + +export interface GetSlotsResult { + slots: Slot[]; +} + +export type SlotStatus = "AVAILABLE" | "BLOCKED"; + +export interface UpdateSlotRequest { + targetDate: string; + startTime: string; + status: SlotStatus; +} + +export interface UpdateSlotResult { + targetDate: string; + startTime: string; + status: SlotStatus; +} + +export interface PatchBreakTimeRequest { + breakStartTime: string; + breakEndTime: string; +} + +export interface BookingDetailResult { + bookerName: string; + partySize: number; + amount: number; +} + +export type GetAvailableTimesParams = { + storeId: string | number; + date: string; + partySize: number; + isSplitAccepted: boolean; +}; + +export type AvailableTimesResult = { + availableTimes: string[]; +}; + +export type SeatsTypes = "WINDOW" | "GENERAL" | string; + +export type AvailableTable = { + tableId: number; + tableNumber: string; + tableSeats: number; + seatsType: SeatsTypes; + gridX: number; + gridY: number; + widthSpan: number; + heightSpan: number; +}; +export type GetAvailableTablesParams = { + storeId: string | number; + date: string; + time: string; + partySize: number; + isSplitAccepted: boolean; + seatsType?: string; +}; + +export type AvailableTablesResult = { + rows: number; + cols: number; + tables: AvailableTable[]; +}; + +export type CreateBookingBody = { + date: string; + time: string; + partySize: number; + tableIds: number[]; + menuItems: { menuId: number; quantity: number }[]; + isSplitAccepted: boolean; +}; + +export type CreateBookingResult = { + bookingId: number; + status: "PENDING" | "CONFIRMED" | string; + storeName: string; + date: string; + time: string; + partySize: number; + totalDeposit: number; + paymentId?: number; + orderId: string; +}; diff --git a/src/types/store.ts b/src/types/store.ts index c9d0d82..56f20b8 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -117,3 +117,107 @@ export type AddressSearchResult = { sido: string; sigungu: string; }; + +export interface StoreDetail { + storeId: number; + storeName: string; + description: string; + address: string; + phone: string; + businessHours?: BusinessHour[]; + isApproved: boolean; + rating?: number; + reviewCount?: number; +} + +export interface MyStore { + storeId: number; + storeName: string; + address: string; + category: string; + rating: number; + totalBookingCount: number; + reviewCount: number; + mainImageUrl: string; + isOpenNow: boolean; +} + +export interface MyStoreResponse { + isSuccess: boolean; + code: string; + message: string; + result: { + stores: MyStore[]; + }; +} + +export interface TableImage { + tableImageId: number; + tableImageUrl: string; +} + +export interface TableImagesResponse { + storeId: number; + tableImages: TableImage[]; +} + +export type StoreDetailDataDTO = { + storeId: number | string; + storeName: string; + description: string; + address: string; + phone: string; + category: Category; + rating: number; + reviewCount: number | null; + mainImageUrl?: string | null; + tableImageUrls: string[] | null; + businessHours: BusinessHour[] | null; + breakStartTime?: string | null; + breakEndTime?: string | null; + isOpenNow?: boolean; + + depositAmount: number; + depositRate?: number | null; +}; + +export type SearchStoreParams = { + keyword: string; + lat: number; + lng: number; + radius?: number; + category?: Category; + sort?: "DISTANCE" | "RATING"; + page?: number; + limit?: number; + sido?: string; + sigungu?: string; + bname?: string; +}; + +export type ApiStoreSummary = { + storeId: number; + name: string; + address: string; + category: Category; + rating: number | null; + reviewCount: number | null; + distance?: number | null; + mainImageUrl?: string | null; + isOpenNow?: boolean | null; + latitude?: number | string | null; + longitude?: number | string | null; + lat?: number | string | null; + lng?: number | string | null; +}; + +export interface SearchStoresResult { + stores: ApiStoreSummary[]; + pagination: { + page: number; + limit: number; + totalCount: number; + totalPages: number; + hasNext: boolean; + }; +} diff --git a/src/types/table.ts b/src/types/table.ts index 54aefd3..09d1bb7 100644 --- a/src/types/table.ts +++ b/src/types/table.ts @@ -7,3 +7,27 @@ export const SEATS_TYPE_LABEL: Record = { BAR: "바 좌석", OUTDOOR: "야외석", }; + +export interface UploadTableImageResult { + tableId: number; + tableImageUrl: string; +} + +export interface DeleteTableImageResult { + tableId: number; +} + +export interface PatchTableRequest { + tableNumber?: string; + minSeatCount?: number; + maxSeatCount?: number; + seatsType?: SeatsType; +} + +export interface UpdatedTable { + tableId: number; + tableNumber: string; + minSeatCount: number; + maxSeatCount: number; + seatsType: string; +} From dda79f71d3ebecde9e14fefdc738233b6a409f8a Mon Sep 17 00:00:00 2001 From: Dew Date: Wed, 6 May 2026 23:52:15 +0900 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=20=EA=B0=9D=EC=B2=B4=EB=8A=94=20i?= =?UTF-8?q?nterface,=20=EC=A1=B0=ED=95=A9=EC=9D=80=20type=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/main/FeatureCard.tsx | 4 +- src/components/main/Header.tsx | 4 +- src/components/map/KakaoMap.tsx | 4 +- src/components/owner/MenuManagement.tsx | 4 +- .../reservation/modals/PaymentModal.tsx | 4 +- .../modals/ReservationCompleteModal.tsx | 4 +- .../modals/ReservationConfirmModal.tsx | 4 +- .../modals/ReservationMenuModal.tsx | 4 +- .../reservation/modals/ReservationModal.tsx | 4 +- src/components/reservation/parts/TableMap.tsx | 4 +- src/components/restaurant/RestaurantCard.tsx | 4 +- .../restaurant/RestaurantDetailModal.tsx | 4 +- src/components/restaurant/RestaurantList.tsx | 4 +- src/hooks/common/useInView.ts | 4 +- src/hooks/reservation/useAvailableTimes.ts | 4 +- src/pages/myPage/MyInfoPage.tsx | 4 +- src/pages/myPage/StoreRegistrationPage.tsx | 4 +- src/pages/myPage/reservationPage.tsx | 4 +- src/types/auth.ts | 28 ++++----- src/types/booking.ts | 12 ++-- src/types/kakao.d.ts | 6 +- src/types/map.ts | 9 ++- src/types/member.ts | 16 ++--- src/types/menus.ts | 36 +++++------ src/types/payment.ts | 8 +-- src/types/reservation.ts | 28 ++++----- src/types/restaurant.ts | 12 ++-- src/types/store.ts | 60 ++++++++++--------- 28 files changed, 146 insertions(+), 141 deletions(-) diff --git a/src/components/main/FeatureCard.tsx b/src/components/main/FeatureCard.tsx index ec4e7f3..415a8fd 100644 --- a/src/components/main/FeatureCard.tsx +++ b/src/components/main/FeatureCard.tsx @@ -1,13 +1,13 @@ import type { ReactNode } from "react"; -type Props = { +interface Props { title: string; desc: string; icon: ReactNode; iconBg: string; className?: string; style?: React.CSSProperties; -}; +} export default function FeatureCard({ title, desc, icon, iconBg, className, style }: Props) { return ( diff --git a/src/components/main/Header.tsx b/src/components/main/Header.tsx index b1cc564..0184f5d 100644 --- a/src/components/main/Header.tsx +++ b/src/components/main/Header.tsx @@ -10,10 +10,10 @@ import { LoginDialog } from "../auth/LoginDialog"; import { SignupDialog } from "../auth/SignupDialog"; import { Button } from "../ui/button"; -type NavItem = { +interface NavItem { label: string; href: string; -}; +} export default function Header() { const [scrolled, setScrolled] = useState(false); diff --git a/src/components/map/KakaoMap.tsx b/src/components/map/KakaoMap.tsx index 88df73e..6690476 100644 --- a/src/components/map/KakaoMap.tsx +++ b/src/components/map/KakaoMap.tsx @@ -10,7 +10,7 @@ import type { } from "@/types/map"; import type { RestaurantSummary } from "@/types/store"; -type Props = { +interface Props { center: LatLng; markers: RestaurantSummary[]; selectedId?: number | null; @@ -18,7 +18,7 @@ type Props = { className?: string; defaultLevel?: number; selectedLevel?: number; -}; +} const toNum = (v: unknown) => { const n = typeof v === "string" ? parseFloat(v) : Number(v); return Number.isFinite(n) ? n : null; diff --git a/src/components/owner/MenuManagement.tsx b/src/components/owner/MenuManagement.tsx index 36fb722..fd6ec94 100644 --- a/src/components/owner/MenuManagement.tsx +++ b/src/components/owner/MenuManagement.tsx @@ -15,7 +15,7 @@ interface Category { label: string; } -type MenuDraft = { +interface MenuDraft { menuId?: number | string; name?: string; description?: string; @@ -25,7 +25,7 @@ type MenuDraft = { imageKey?: string; isSoldOut?: boolean; isActive?: boolean; -}; +} type CategoryType = "ALL" | MenuCategory; diff --git a/src/components/reservation/modals/PaymentModal.tsx b/src/components/reservation/modals/PaymentModal.tsx index c2374e2..8ee2224 100644 --- a/src/components/reservation/modals/PaymentModal.tsx +++ b/src/components/reservation/modals/PaymentModal.tsx @@ -19,7 +19,7 @@ import { formatKrw } from "@/utils/money"; import { Button } from "../../ui/button"; -type Props = { +interface Props { open: boolean; onClose: () => void; onOpenChange: (open: boolean) => void; @@ -27,7 +27,7 @@ type Props = { restaurant: RestaurantDetail; draft: ReservationDraft; booking: CreateBookingResult | null; -}; +} type TossPaymentsInstance = Awaited>; type TossWidgetsInstance = ReturnType; diff --git a/src/components/reservation/modals/ReservationCompleteModal.tsx b/src/components/reservation/modals/ReservationCompleteModal.tsx index f62522a..dc1c613 100644 --- a/src/components/reservation/modals/ReservationCompleteModal.tsx +++ b/src/components/reservation/modals/ReservationCompleteModal.tsx @@ -9,13 +9,13 @@ import { toYmd } from "@/utils/date"; import { backdropMotionClass, panelMotionClass } from "@/utils/modalMotion"; import { toHHmm } from "@/utils/time"; -type Props = { +interface Props { open: boolean; restaurant: Pick; draft: Pick; onClose: () => void; autoCloseMs?: number; -}; +} export default function ReservationCompleteModal({ open, diff --git a/src/components/reservation/modals/ReservationConfirmModal.tsx b/src/components/reservation/modals/ReservationConfirmModal.tsx index 1350b33..51cdb8e 100644 --- a/src/components/reservation/modals/ReservationConfirmModal.tsx +++ b/src/components/reservation/modals/ReservationConfirmModal.tsx @@ -18,7 +18,7 @@ import { formatKrw } from "@/utils/money"; import { calcDeposit } from "@/utils/payment"; import { tablePrefLabel } from "@/utils/reservation"; -type Props = { +interface Props { open: boolean; onClose: () => void; onBack: () => void; @@ -26,7 +26,7 @@ type Props = { restaurant: RestaurantDetail; draft: ReservationDraft; booking: CreateBookingResult | null; -}; +} export default function ReservationConfirmModal({ open, diff --git a/src/components/reservation/modals/ReservationMenuModal.tsx b/src/components/reservation/modals/ReservationMenuModal.tsx index b3bb0df..730c2f6 100644 --- a/src/components/reservation/modals/ReservationMenuModal.tsx +++ b/src/components/reservation/modals/ReservationMenuModal.tsx @@ -22,14 +22,14 @@ import { calcDeposit } from "@/utils/payment"; import { Button } from "../../ui/button"; -type Props = { +interface Props { open: boolean; restaurant: RestaurantDetail; onConfirm: (draft: ReservationDraft) => void; onBack: () => void; onClose: () => void; draft: ReservationDraft; -}; +} export default function ReservationMenuModal({ open, diff --git a/src/components/reservation/modals/ReservationModal.tsx b/src/components/reservation/modals/ReservationModal.tsx index 8387850..d2865a7 100644 --- a/src/components/reservation/modals/ReservationModal.tsx +++ b/src/components/reservation/modals/ReservationModal.tsx @@ -24,13 +24,13 @@ import { Calendar } from "../../ui/calendar"; import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover"; import TableMap from "../parts/TableMap"; -type Props = { +interface Props { open: boolean; restaurant: RestaurantDetail; initialDraft?: ReservationDraft; onClickConfirm: (draft: ReservationDraft) => void; onClose: () => void; -}; +} const PEOPLE = [1, 2, 3, 4, 5, 6, 7, 8]; diff --git a/src/components/reservation/parts/TableMap.tsx b/src/components/reservation/parts/TableMap.tsx index a339625..3d46287 100644 --- a/src/components/reservation/parts/TableMap.tsx +++ b/src/components/reservation/parts/TableMap.tsx @@ -1,14 +1,14 @@ import { cn } from "@/lib/utils"; import type { SeatLayout, SeatTable, SeatType } from "@/types/restaurant"; -type Props = { +interface Props { layout: SeatLayout; availableIds: Set; selectedTableId: number | null; seatType: SeatType | null; onSelectTable: (tableId: number) => void; onSelectSeatType: (seatType: SeatType) => void; -}; +} export default function TableMap({ layout, diff --git a/src/components/restaurant/RestaurantCard.tsx b/src/components/restaurant/RestaurantCard.tsx index bb3d4ba..e5bd7e5 100644 --- a/src/components/restaurant/RestaurantCard.tsx +++ b/src/components/restaurant/RestaurantCard.tsx @@ -1,9 +1,9 @@ import { type RestaurantSummary, storeCategoryLabel } from "@/types/store"; -type Props = { +interface Props { restaurant: RestaurantSummary; onClick: () => void; -}; +} export default function RestaurantCard({ restaurant, onClick }: Props) { return ( diff --git a/src/components/restaurant/RestaurantDetailModal.tsx b/src/components/restaurant/RestaurantDetailModal.tsx index b84a90d..b79b9c3 100644 --- a/src/components/restaurant/RestaurantDetailModal.tsx +++ b/src/components/restaurant/RestaurantDetailModal.tsx @@ -9,7 +9,7 @@ import { backdropMotionClass, panelMotionClass } from "@/utils/modalMotion"; import { Button } from "../ui/button"; -type Props = { +interface Props { open: boolean; onOpenChange: (open: boolean) => void; status: "idle" | "loading" | "success" | "error"; @@ -17,7 +17,7 @@ type Props = { errorMessage?: string; onRetry?: () => void; onClickReserve: () => void; -}; +} const DAY_LABEL: Record = { MONDAY: "월", diff --git a/src/components/restaurant/RestaurantList.tsx b/src/components/restaurant/RestaurantList.tsx index 09d93d1..473cce5 100644 --- a/src/components/restaurant/RestaurantList.tsx +++ b/src/components/restaurant/RestaurantList.tsx @@ -2,10 +2,10 @@ import type { RestaurantSummary } from "@/types/store"; import RestaurantCard from "./RestaurantCard"; -type Props = { +interface Props { restaurants: RestaurantSummary[]; onSelect: (restaurant: RestaurantSummary) => void; -}; +} export default function RestaurantList({ restaurants, onSelect }: Props) { return ( diff --git a/src/hooks/common/useInView.ts b/src/hooks/common/useInView.ts index e2a971d..8923b24 100644 --- a/src/hooks/common/useInView.ts +++ b/src/hooks/common/useInView.ts @@ -1,10 +1,10 @@ import { useEffect, useRef, useState } from "react"; -type Options = { +interface Options { threshold?: number | number[]; rootMargin?: string; once?: boolean; -}; +} export function useInView({ threshold = 0.3, diff --git a/src/hooks/reservation/useAvailableTimes.ts b/src/hooks/reservation/useAvailableTimes.ts index f0f18da..0e023dd 100644 --- a/src/hooks/reservation/useAvailableTimes.ts +++ b/src/hooks/reservation/useAvailableTimes.ts @@ -3,12 +3,12 @@ import { useQuery } from "@tanstack/react-query"; import { getAvailableTimes } from "@/api/endpoints/reservations"; import { queryKeys } from "@/query/keys"; -type AvailableTimesInput = { +interface AvailableTimesInput { storeId?: string | number; date?: string; partySize?: number; isSplitAccepted?: boolean; -}; +} export function useAvailableTimes(input: AvailableTimesInput) { const { storeId, date, partySize, isSplitAccepted } = input; diff --git a/src/pages/myPage/MyInfoPage.tsx b/src/pages/myPage/MyInfoPage.tsx index 0f1e166..2351030 100644 --- a/src/pages/myPage/MyInfoPage.tsx +++ b/src/pages/myPage/MyInfoPage.tsx @@ -7,11 +7,11 @@ import ProfileAvatar from "@/components/profile/profileAvatar"; import { Button } from "@/components/ui/button"; import { phoneNumber } from "@/utils/phoneNumber"; -type Form = { +interface Form { email: string; nickname: string; phone: string; -}; +} export default function MyInfoPage() { const qc = useQueryClient(); diff --git a/src/pages/myPage/StoreRegistrationPage.tsx b/src/pages/myPage/StoreRegistrationPage.tsx index 319c624..d986515 100644 --- a/src/pages/myPage/StoreRegistrationPage.tsx +++ b/src/pages/myPage/StoreRegistrationPage.tsx @@ -17,12 +17,12 @@ import { useMenuCreate, useMenuImage } from "@/hooks/queries/useMenu"; import { useMainImage, useRegisterStore } from "@/hooks/queries/useStore"; import { getErrorMessage } from "@/utils/error"; -type Step1Data = { +interface Step1Data { name: string; businessNumber: string; startDate: string; isVerified: boolean; -}; +} export default function StoreRegistrationPage() { const { mutateAsync: registerStore } = useRegisterStore(); diff --git a/src/pages/myPage/reservationPage.tsx b/src/pages/myPage/reservationPage.tsx index 0cdfdea..bb2a38a 100644 --- a/src/pages/myPage/reservationPage.tsx +++ b/src/pages/myPage/reservationPage.tsx @@ -6,7 +6,7 @@ import { cn } from "@/lib/utils"; type ReservationStatus = "전체" | "예정된 예약" | "방문 완료" | "취소된 예약"; -type Reservation = { +interface Reservation { id: number; shopName: string; status: "예약 확정" | "방문 완료" | "취소됨"; @@ -17,7 +17,7 @@ type Reservation = { payment: string; method: string; step: string; -}; +} export default function ReservationPage() { const [activeTab, setActiveTab] = useState("전체"); diff --git a/src/types/auth.ts b/src/types/auth.ts index a0f1e66..070af3f 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -1,4 +1,4 @@ -export type RequestSignupDto = { +export interface RequestSignupDto { name: string; email: string; password: string; @@ -7,36 +7,36 @@ export type RequestSignupDto = { tosConsent: boolean; privacyConsent: boolean; marketingConsent: boolean; -}; +} -export type ResponseSignupDto = { +export interface ResponseSignupDto { id: number; createdAt: string; -}; +} -export type RequestLoginDto = { +export interface RequestLoginDto { email: string; password: string; -}; +} -export type ResponseLoginDto = { +export interface ResponseLoginDto { id: number; accessToken: string; refreshToken: string | null; -}; +} export type ResponseLogoutDto = string; -export type ResponseRefreshDto = { +export interface ResponseRefreshDto { accessToken: string; -}; +} -export type RequestVerifyOwnerDto = { +export interface RequestVerifyOwnerDto { businessNumber: string; startDate: string; -}; +} -export type ResponseVerifyOwnerDto = { +export interface ResponseVerifyOwnerDto { businessNumber: string; startDate: string; -}; +} diff --git a/src/types/booking.ts b/src/types/booking.ts index 27971d6..e5a982b 100644 --- a/src/types/booking.ts +++ b/src/types/booking.ts @@ -22,12 +22,12 @@ export interface BookingResponse { isLast: boolean; } -export type GetBookingParams = { +export interface GetBookingParams { page: number; status?: ApiBookingStatus; -}; +} -export type BookingListItem = { +export interface BookingListItem { bookingId: number; storeName: string; storeAddress: string; @@ -43,15 +43,15 @@ export type BookingListItem = { amount: number; paymentMethod: string; status: ApiBookingStatus; -}; +} -export type UserBookingsResult = { +export interface UserBookingsResult { bookingList: BookingListItem[]; listSize: number; totalPage: number; totalElements: number; isFirst: boolean; isLast: boolean; -}; +} export type UserBookingItem = BookingListItem; diff --git a/src/types/kakao.d.ts b/src/types/kakao.d.ts index 26b7eec..f348c9b 100644 --- a/src/types/kakao.d.ts +++ b/src/types/kakao.d.ts @@ -53,11 +53,9 @@ declare global { } } -export {}; - export type KakaoAddressSearchStatus = "OK" | "ZERO_RESULT" | "ERROR"; -export type KakaoAddressSearchResult = { +export interface KakaoAddressSearchResult { x: string; y: string; -}; +} diff --git a/src/types/map.ts b/src/types/map.ts index 9252878..9b36474 100644 --- a/src/types/map.ts +++ b/src/types/map.ts @@ -1,7 +1,12 @@ import type { RestaurantSummary } from "./store"; -export type LatLng = { lat: number; lng: number }; -export type MarkerWithLocation = RestaurantSummary & { location: LatLng }; +export interface LatLng { + lat: number; + lng: number; +} +export interface MarkerWithLocation extends RestaurantSummary { + location: LatLng; +} type KakaoMaps = NonNullable["maps"]>; export type KaKaoMapInstance = InstanceType; diff --git a/src/types/member.ts b/src/types/member.ts index f281037..9c80e0f 100644 --- a/src/types/member.ts +++ b/src/types/member.ts @@ -1,24 +1,24 @@ -export type MemberInfo = { +export interface MemberInfo { id: number; profileImage: string | null; email: string; name: string; phoneNumber: string; -}; +} -export type PatchMemberInfo = { +export interface PatchMemberInfo { name: string; phoneNumber: string; -}; +} -export type ChangePasswordRequest = { +export interface ChangePasswordRequest { currentPassword: string; newPassword: string; newPasswordConfirm: string; -}; +} -export type ChangePasswordResponse = { +export interface ChangePasswordResponse { change: boolean; changeAt: string; message: string; -}; +} diff --git a/src/types/menus.ts b/src/types/menus.ts index e7ad8a0..e105b10 100644 --- a/src/types/menus.ts +++ b/src/types/menus.ts @@ -1,4 +1,4 @@ -export type MenuItem = { +export interface MenuItem { id: string; restaurantId: string; name: string; @@ -11,12 +11,12 @@ export type MenuItem = { isActive: boolean; createdAt?: string; updatedAt?: string; -}; +} -export type SelectedMenu = { +export interface SelectedMenu { menuId: string; quantity: number; -}; +} export type MenuCategory = "MAIN" | "SIDE" | "BEVERAGE" | "ALCOHOL"; @@ -33,30 +33,30 @@ export const UiMenuCategoryLabel: Record = { OTHER: "기타", }; -export type MenuCreateItemDto = { +export interface MenuCreateItemDto { name: string; description?: string; price: number; category: MenuCategory; imageKey?: string; -}; +} -export type RequestMenuCreateDto = { +export interface RequestMenuCreateDto { menus: MenuCreateItemDto[]; -}; +} -export type ResponseMenuCreateDto = { +export interface ResponseMenuCreateDto { menus: MenuCreateItemDto[]; -}; +} -export type RequestMenuImageDto = { +export interface RequestMenuImageDto { image: File; -}; +} -export type ResponseMenuImageDto = { +export interface ResponseMenuImageDto { imageKey: string; imageUrl: string; -}; +} export interface ServerMenu { menuId: number; @@ -116,7 +116,7 @@ export interface DeleteMenusResponse { message: string; } -export type MenuDto = { +export interface MenuDto { menuId: number; name: string; description?: string; @@ -124,8 +124,8 @@ export type MenuDto = { category: MenuCategory | string; imageUrl?: string; isSoldOut: boolean; -}; +} -export type MenuListResult = { +export interface MenuListResult { menus: MenuDto[]; -}; +} diff --git a/src/types/payment.ts b/src/types/payment.ts index aa90d84..bbec91e 100644 --- a/src/types/payment.ts +++ b/src/types/payment.ts @@ -1,14 +1,14 @@ export type { DepositRate } from "@/types/store"; -export type PaymentRequestResult = { +export interface PaymentRequestResult { paymentId: number; bookingId: number; orderId: string; amount: number; requestedAt: string; -}; +} -export type PaymentConfirmResult = { +export interface PaymentConfirmResult { paymentId: number; status: string; approvedAt: string; @@ -17,4 +17,4 @@ export type PaymentConfirmResult = { paymentMethod: string; paymentProvider: string; receiptUrl: string; -}; +} diff --git a/src/types/reservation.ts b/src/types/reservation.ts index 3d418ea..004631a 100644 --- a/src/types/reservation.ts +++ b/src/types/reservation.ts @@ -34,20 +34,20 @@ export interface BookingDetailResult { amount: number; } -export type GetAvailableTimesParams = { +export interface GetAvailableTimesParams { storeId: string | number; date: string; partySize: number; isSplitAccepted: boolean; -}; +} -export type AvailableTimesResult = { +export interface AvailableTimesResult { availableTimes: string[]; -}; +} export type SeatsTypes = "WINDOW" | "GENERAL" | string; -export type AvailableTable = { +export interface AvailableTable { tableId: number; tableNumber: string; tableSeats: number; @@ -56,32 +56,32 @@ export type AvailableTable = { gridY: number; widthSpan: number; heightSpan: number; -}; -export type GetAvailableTablesParams = { +} +export interface GetAvailableTablesParams { storeId: string | number; date: string; time: string; partySize: number; isSplitAccepted: boolean; seatsType?: string; -}; +} -export type AvailableTablesResult = { +export interface AvailableTablesResult { rows: number; cols: number; tables: AvailableTable[]; -}; +} -export type CreateBookingBody = { +export interface CreateBookingBody { date: string; time: string; partySize: number; tableIds: number[]; menuItems: { menuId: number; quantity: number }[]; isSplitAccepted: boolean; -}; +} -export type CreateBookingResult = { +export interface CreateBookingResult { bookingId: number; status: "PENDING" | "CONFIRMED" | string; storeName: string; @@ -91,4 +91,4 @@ export type CreateBookingResult = { totalDeposit: number; paymentId?: number; orderId: string; -}; +} diff --git a/src/types/restaurant.ts b/src/types/restaurant.ts index 516fa30..a6ad897 100644 --- a/src/types/restaurant.ts +++ b/src/types/restaurant.ts @@ -4,7 +4,7 @@ export const SEATS = ["일반석", "창가석", "룸/프라이빗", "바(Bar)석 export type SeatType = (typeof SEATS)[number]; export type TablePref = "split_ok" | "one_table"; -export type ReservationDraft = { +export interface ReservationDraft { people: number; date: Date; time?: string; @@ -13,9 +13,9 @@ export type ReservationDraft = { tableId: number; tableNo: number | null; selectedMenus: SelectedMenu[]; -}; +} -export type SeatTable = { +export interface SeatTable { id: number; tableNo: number; minPeople: number; @@ -24,10 +24,10 @@ export type SeatTable = { gridX: number; gridY: number; imageUrl?: string; -}; +} -export type SeatLayout = { +export interface SeatLayout { gridCols: number; gridRows: number; tables: SeatTable[]; -}; +} diff --git a/src/types/store.ts b/src/types/store.ts index 56f20b8..6eee847 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -9,12 +9,12 @@ export type Day = | "SATURDAY" | "SUNDAY"; -export type Location = { +export interface Location { lat: number; lng: number; -}; +} -export type RestaurantSummary = { +export interface RestaurantSummary { id: number; name: string; address: string; @@ -25,21 +25,21 @@ export type RestaurantSummary = { thumbnailUrl?: string; isOpenNow?: boolean; location?: Location; -}; +} -export type BusinessHour = { +export interface BusinessHour { day: Day; openTime: string | null; closeTime: string | null; isClosed: boolean; -}; +} -export type BreakTime = { +export interface BreakTime { start: string; end: string; -}; +} -export type RestaurantDetail = { +export interface RestaurantDetail { id: number; name: string; description: string; @@ -56,7 +56,7 @@ export type RestaurantDetail = { isOpenNow?: boolean; location?: Location; depositRate?: number; -}; +} export const storeCategoryLabel: Record = { KOREAN: "한식", @@ -68,13 +68,13 @@ export const storeCategoryLabel: Record = { export type DepositRate = "TEN" | "TWENTY" | "THIRTY" | "FORTY" | "FIFTY"; -export type BusinessNumberDto = { +export interface BusinessNumberDto { name: string; businessNumber: string; startDate: string; -}; +} -export type RequestStoreCreateDto = { +export interface RequestStoreCreateDto { storeName: string; businessNumberDto?: BusinessNumberDto; description?: string; @@ -89,34 +89,36 @@ export type RequestStoreCreateDto = { depositRate: DepositRate; bookingIntervalMinutes: number; businessHours: BusinessHour[]; -}; +} -export type ResponseStoreCreateDto = { storeId: number }; +export interface ResponseStoreCreateDto { + storeId: number; +} -export type RequestMainImageDto = { +export interface RequestMainImageDto { mainImage: File; -}; +} -export type ResponseMainImageDto = { +export interface ResponseMainImageDto { storeId: number; mainImageUrl: string; -}; +} -export type UpdateStoreResponse = { +export interface UpdateStoreResponse { storeId: number; storeName: string; description: string; phoneNumber: string; -}; +} -export type AddressSearchResult = { +export interface AddressSearchResult { address: string; addressType: string; bname: string; buildingName: string; sido: string; sigungu: string; -}; +} export interface StoreDetail { storeId: number; @@ -161,7 +163,7 @@ export interface TableImagesResponse { tableImages: TableImage[]; } -export type StoreDetailDataDTO = { +export interface StoreDetailDataDTO { storeId: number | string; storeName: string; description: string; @@ -179,9 +181,9 @@ export type StoreDetailDataDTO = { depositAmount: number; depositRate?: number | null; -}; +} -export type SearchStoreParams = { +export interface SearchStoreParams { keyword: string; lat: number; lng: number; @@ -193,9 +195,9 @@ export type SearchStoreParams = { sido?: string; sigungu?: string; bname?: string; -}; +} -export type ApiStoreSummary = { +export interface ApiStoreSummary { storeId: number; name: string; address: string; @@ -209,7 +211,7 @@ export type ApiStoreSummary = { longitude?: number | string | null; lat?: number | string | null; lng?: number | string | null; -}; +} export interface SearchStoresResult { stores: ApiStoreSummary[]; From 122f23d42e2059ff6c593968f5ffcd342efe7b71 Mon Sep 17 00:00:00 2001 From: Dew Date: Thu, 7 May 2026 00:46:00 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20booking=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/booking.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/types/booking.ts b/src/types/booking.ts index e5a982b..eb29bd3 100644 --- a/src/types/booking.ts +++ b/src/types/booking.ts @@ -13,8 +13,7 @@ export interface Booking { status: ApiBookingStatus; } -export interface BookingResponse { - bookingList: Booking[]; +export interface Pagination { listSize: number; totalPage: number; totalElements: number; @@ -22,6 +21,10 @@ export interface BookingResponse { isLast: boolean; } +export interface BookingResponse extends Pagination { + bookingList: Booking[]; +} + export interface GetBookingParams { page: number; status?: ApiBookingStatus; @@ -45,13 +48,8 @@ export interface BookingListItem { status: ApiBookingStatus; } -export interface UserBookingsResult { +export interface UserBookingsResult extends Pagination { bookingList: BookingListItem[]; - listSize: number; - totalPage: number; - totalElements: number; - isFirst: boolean; - isLast: boolean; } export type UserBookingItem = BookingListItem; From fa1e991f8eb861b96c8d47b35056faf6b473c3e1 Mon Sep 17 00:00:00 2001 From: Dew Date: Thu, 7 May 2026 01:40:08 +0900 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20GetAvailableTablesParams=EB=A5=BC=20?= =?UTF-8?q?interface=EC=97=90=EC=84=9C=20type=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/reservation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/reservation.ts b/src/types/reservation.ts index 004631a..e4f2179 100644 --- a/src/types/reservation.ts +++ b/src/types/reservation.ts @@ -57,14 +57,14 @@ export interface AvailableTable { widthSpan: number; heightSpan: number; } -export interface GetAvailableTablesParams { +export type GetAvailableTablesParams = { storeId: string | number; date: string; time: string; partySize: number; isSplitAccepted: boolean; seatsType?: string; -} +}; export interface AvailableTablesResult { rows: number; From ab9635b7efcd1e37ff88363c598a4b5761e910fa Mon Sep 17 00:00:00 2001 From: Dew Date: Sun, 10 May 2026 19:14:21 +0900 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=EB=9E=98=EB=B9=97?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/endpoints/member.ts | 3 +++ src/hooks/store/useSearchStores.ts | 4 ++-- src/types/booking.ts | 17 ++--------------- src/types/member.ts | 4 ++-- src/types/store.ts | 15 ++++----------- src/types/table.ts | 2 +- 6 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/api/endpoints/member.ts b/src/api/endpoints/member.ts index 8be0605..cb5d337 100644 --- a/src/api/endpoints/member.ts +++ b/src/api/endpoints/member.ts @@ -18,6 +18,9 @@ export async function getMemberInfo() { export async function patchMemberInfo(body: PatchMemberInfo) { const res = await api.patch>("/api/v1/member/info", body); + if (!res.data?.isSuccess) { + throw new Error(res.data?.message ?? "회원정보 수정 실패"); + } return res.data.result; } diff --git a/src/hooks/store/useSearchStores.ts b/src/hooks/store/useSearchStores.ts index be680da..7c6a779 100644 --- a/src/hooks/store/useSearchStores.ts +++ b/src/hooks/store/useSearchStores.ts @@ -16,8 +16,8 @@ const toNum = (v: unknown): number | undefined => { }; function toSummary(s: ApiStoreSummary): RestaurantSummary { - const lat = toNum(s.latitude ?? s.lat); - const lng = toNum(s.longitude ?? s.lng); + const lat = toNum(s.latitude); + const lng = toNum(s.longitude); return { id: s.storeId, name: s.name, diff --git a/src/types/booking.ts b/src/types/booking.ts index eb29bd3..428d49e 100644 --- a/src/types/booking.ts +++ b/src/types/booking.ts @@ -1,18 +1,5 @@ export type ApiBookingStatus = "PENDING" | "CONFIRMED" | "COMPLETED" | "CANCELED"; -export interface Booking { - bookingId: number; - storeName: string; - storeAddress: string; - bookingDate: string; - bookingTime: string; - partySize: number; - tableNumbers: string; - amount: number | null; - paymentMethod: string; - status: ApiBookingStatus; -} - export interface Pagination { listSize: number; totalPage: number; @@ -22,7 +9,7 @@ export interface Pagination { } export interface BookingResponse extends Pagination { - bookingList: Booking[]; + bookingList: BookingListItem[]; } export interface GetBookingParams { @@ -43,7 +30,7 @@ export interface BookingListItem { }; partySize: number; tableNumbers: string; - amount: number; + amount: number | null; paymentMethod: string; status: ApiBookingStatus; } diff --git a/src/types/member.ts b/src/types/member.ts index 9c80e0f..182d4cf 100644 --- a/src/types/member.ts +++ b/src/types/member.ts @@ -7,8 +7,8 @@ export interface MemberInfo { } export interface PatchMemberInfo { - name: string; - phoneNumber: string; + name?: string; + phoneNumber?: string; } export interface ChangePasswordRequest { diff --git a/src/types/store.ts b/src/types/store.ts index 6eee847..4f5b679 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -1,3 +1,5 @@ +import type { ApiResponse } from "./api"; + export type Category = "KOREAN" | "CHINESE" | "JAPANESE" | "WESTERN" | "CAFE"; export type Day = @@ -136,7 +138,7 @@ export interface MyStore { storeId: number; storeName: string; address: string; - category: string; + category: Category; rating: number; totalBookingCount: number; reviewCount: number; @@ -144,14 +146,7 @@ export interface MyStore { isOpenNow: boolean; } -export interface MyStoreResponse { - isSuccess: boolean; - code: string; - message: string; - result: { - stores: MyStore[]; - }; -} +export type MyStoreResponse = ApiResponse<{ stores: MyStore[] }>; export interface TableImage { tableImageId: number; @@ -209,8 +204,6 @@ export interface ApiStoreSummary { isOpenNow?: boolean | null; latitude?: number | string | null; longitude?: number | string | null; - lat?: number | string | null; - lng?: number | string | null; } export interface SearchStoresResult { diff --git a/src/types/table.ts b/src/types/table.ts index 09d1bb7..29da64f 100644 --- a/src/types/table.ts +++ b/src/types/table.ts @@ -29,5 +29,5 @@ export interface UpdatedTable { tableNumber: string; minSeatCount: number; maxSeatCount: number; - seatsType: string; + seatsType: SeatsType; } From 761b36cde86c1a401f08a6526eed262e853c6546 Mon Sep 17 00:00:00 2001 From: Dew Date: Sun, 10 May 2026 19:25:33 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=EC=98=88=EC=95=BD=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EA=B0=9D=EC=B2=B4=20=ED=83=80=EC=9E=85=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/myPage/reservationPage.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/myPage/reservationPage.tsx b/src/pages/myPage/reservationPage.tsx index bb2a38a..ebb36fd 100644 --- a/src/pages/myPage/reservationPage.tsx +++ b/src/pages/myPage/reservationPage.tsx @@ -53,7 +53,9 @@ export default function ReservationPage() { shopName: b.storeName, address: b.storeAddress, date: b.bookingDate, - time: b.bookingTime ?? "--:--", + time: b.bookingTime + ? `${String(b.bookingTime.hour).padStart(2, "0")}:${String(b.bookingTime.minute).padStart(2, "0")}` + : "--:--", people: b.partySize?.toString() ?? "0", payment: `${b.amount?.toLocaleString() ?? 0}원`, method: b.paymentMethod ?? "-",