Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
314fe0a
refactor: digest re-throw ๊ณตํ†ต ์œ ํ‹ธ ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌ
Seoje1405 Feb 12, 2026
475e0cc
refactor: ๊ฐ€๊ฒฉ ํฌ๋ฉง ์œ ํ‹ธ ํ†ตํ•ฉ
Seoje1405 Feb 12, 2026
e02c312
refactor: ๋ชฉ๋ฐ์ดํ„ฐ ์ œ๊ฑฐ ๋ฐ ๊ฒฐ์ œ ํŽ˜์ด์ง€ ๋ผ์šฐํŒ…
Seoje1405 Feb 12, 2026
c3f0024
feat: ์ƒํ’ˆ ์˜ต์…˜ ์กฐํšŒ ์„œ๋ฒ„ ์•ก์…˜ ์ •์˜
Seoje1405 Feb 12, 2026
1dc54b9
fix: Image src ๋นˆ ๋ฌธ์ž์—ด ๋ฐฉ์–ด ์ฒ˜๋ฆฌ
Seoje1405 Feb 12, 2026
a32d883
refactor: fetchUserBodyInfo ๋ชฉ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„ ์•ก์…˜์œผ๋กœ ๊ต์ฒด
Seoje1405 Feb 12, 2026
4b974c7
feat: ๋น„์Šทํ•œ ์ƒํ’ˆ ์กฐํšŒ ์„œ๋ฒ„ ์•ก์…˜ ์ •์˜
Seoje1405 Feb 12, 2026
03607ca
refactor: ์ถ”์ฒœ ์ƒํ’ˆ ๋ชฉ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„ ์•ก์…˜์œผ๋กœ ๊ต์ฒด
Seoje1405 Feb 12, 2026
9b0ef9b
fix: ๋ชฉ๋ฐ์ดํ„ฐ Math.random ์ œ๊ฑฐ
Seoje1405 Feb 12, 2026
1bbd6b6
refactor: cart-views.tsx๋ฅผ ๊ฐœ๋ณ„ ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌ
Seoje1405 Feb 12, 2026
e550dbb
refactor: ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์˜ต์…˜ ๋ณ€๊ฒฝ ๊ธฐ๋Šฅ ์ถ”๊ฐ€, ์ˆ˜๋Ÿ‰ ์ง์ ‘ ์ž…๋ ฅ ๊ธฐ๋Šฅ ์ถ”๊ฐ€, ๋””๋ฐ”์šด์Šค ์ฒ˜๋ฆฌ
Seoje1405 Feb 12, 2026
cc2ff7f
fix: ์ฝ”๋“œ ๋ž˜๋น— ๋ฐ˜์˜
Seoje1405 Feb 12, 2026
68c4db2
fix: ํ’ˆ์ ˆ ์˜ต์…˜ ์„ ํƒ ์•ˆ๋˜๊ฒŒ ์ˆ˜์ •
Seoje1405 Feb 12, 2026
b375d89
refactor: ๋ชฉ๋ฐ์ดํ„ฐ์šฉ ์ž„์‹œ ๋กœ์ง ์ œ๊ฑฐ
Seoje1405 Feb 12, 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
2 changes: 1 addition & 1 deletion src/app/@modal/(.)body-info/_components/wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useRouter } from 'next/navigation';
import { BodyInfoForm } from '@/components/product/size/body-info-form';
import { UserBodyInfo } from '@/mocks/size';
import { UserBodyInfo } from '@/types/domain/size';

// ์ œ์ถœ์„ฑ๊ณต์‹œ ๋ชจ๋‹ฌ ๋‹ซ๊ธฐ + ๋’ค๋กœ๊ฐ€๊ธฐ ์ฒ˜๋ฆฌ ๋ž˜ํผ ์ปดํฌ๋„ŒํŠธ

Expand Down
6 changes: 4 additions & 2 deletions src/app/@modal/(.)body-info/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { fetchUserBodyInfo } from '@/mocks/size';
import { getMyBodyInfoAction } from '@/app/actions/body-info';
import { BodyInfoModal } from '@/components/ui/body-info-modal';
import { BodyInfoFormWrapper } from './_components/wrapper';
import { CloseButton } from '@/components/ui/close-button';

// ์‚ฌ์ด์ฆˆ ํƒญ์—์„œ '๋‚ด ์‹ ์ฒด ์ •๋ณด ์ˆ˜์ •' ํด๋ฆญ ์‹œ ๋‚˜ํƒ€๋‚˜๋Š” ์ธํ„ฐ์…‰ํŠธ ๋ชจ๋‹ฌ ํŽ˜์ด์ง€

export default async function InterceptedBodyInfoPage() {
const userInfo = await fetchUserBodyInfo();
const result = await getMyBodyInfoAction();
const userInfo =
result.success && result.data?.hasBodyInfo ? result.data : null;

return (
<BodyInfoModal>
Expand Down
9 changes: 5 additions & 4 deletions src/app/actions/body-info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use server';

import { api, ApiError } from '@/lib/api-client';
import { rethrowNextError } from '@/lib/server-action-utils';
import { bodyInfoSchema, BodyInfoSchemaType } from '@/schemas/body-info';
import { SizeOptionsData } from '@/types/domain/size';
import { revalidatePath } from 'next/cache';
Expand Down Expand Up @@ -39,7 +40,7 @@ export async function getBodyInfoTermsAction(): Promise<{
const data = await api.get<TermsData>('/users/body-info/terms');
return { success: true, data };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Failed to fetch terms:', error);
return { success: false, message: '์•ฝ๊ด€ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.' };
}
Expand Down Expand Up @@ -83,7 +84,7 @@ export async function getMyBodyInfoAction(): Promise<{
},
};
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Failed to fetch my body info:', error);
return { success: false, message: '๋‚ด ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.' };
}
Expand Down Expand Up @@ -134,7 +135,7 @@ export async function updateBodyInfoAction(

return { success: true, message: '์ฒดํ˜• ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.' };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Save Error:', error);

// ๋ฐฑ์—”๋“œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ
Expand Down Expand Up @@ -164,7 +165,7 @@ export async function getSizeOptionsAction(): Promise<{
);
return { success: true, data };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Failed to fetch size options:', error);
return { success: false, message: '์‚ฌ์ด์ฆˆ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.' };
}
Expand Down
13 changes: 7 additions & 6 deletions src/app/actions/cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
CartUpdateRequest,
} from '@/types/domain/cart';
import { revalidatePath } from 'next/cache';
import { rethrowNextError } from '@/lib/server-action-utils';

/** ๋‚ด ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ */
export async function getCartItems(): Promise<CartResponse[]> {
try {
const cartItems = await api.get<CartResponse[]>('/carts');
return cartItems;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ ์‹คํŒจ:', error);
return [];
}
Expand All @@ -27,7 +28,7 @@ export async function addToCart(data: CartCreateRequest) {
revalidatePath('/cart');
return { success: true, message: '์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ƒํ’ˆ์„ ๋‹ด์•˜์Šต๋‹ˆ๋‹ค.' };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ ์‹คํŒจ:', error);
return {
success: false,
Expand All @@ -44,7 +45,7 @@ export async function updateCartItem(cartId: number, data: CartUpdateRequest) {
revalidatePath('/cart');
return { success: true, message: '์žฅ๋ฐ”๊ตฌ๋‹ˆ๊ฐ€ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.' };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ • ์‹คํŒจ:', error);
return {
success: false,
Expand All @@ -60,7 +61,7 @@ export async function deleteCartItem(cartId: number) {
revalidatePath('/cart');
return { success: true, message: '์ƒํ’ˆ์ด ์‚ญ์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.' };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ญ์ œ ์‹คํŒจ:', error);
return {
success: false,
Expand All @@ -82,7 +83,7 @@ export async function deleteCartItems(cartIds: number[]) {
revalidatePath('/cart');
return { success: true, message: '์„ ํƒํ•œ ์ƒํ’ˆ์ด ์‚ญ์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.' };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ผ๊ด„ ์‚ญ์ œ ์‹คํŒจ:', error);
return {
success: false,
Expand All @@ -101,7 +102,7 @@ export async function getCartCount(): Promise<number> {
}
return data.count;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ฐœ์ˆ˜ ์กฐํšŒ ์‹คํŒจ:', error);
return 0;
}
Expand Down
15 changes: 8 additions & 7 deletions src/app/actions/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { api } from '@/lib/api-client';
import { revalidatePath } from 'next/cache';
import { redirect, notFound } from 'next/navigation';
import { rethrowNextError } from '@/lib/server-action-utils';
import {
OrderFromCartRequest,
OrderFromProductRequest,
Expand All @@ -29,7 +30,7 @@ export async function createOrderFromCart(
revalidatePath('/cart');
return orderId;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ ์ฃผ๋ฌธ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error
Expand All @@ -50,7 +51,7 @@ export async function createOrderFromProduct(
);
return orderId;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์ƒํ’ˆ ์ง์ ‘ ์ฃผ๋ฌธ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : '์ƒํ’ˆ ์ง์ ‘ ์ฃผ๋ฌธ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
Expand Down Expand Up @@ -136,7 +137,7 @@ export async function getOrders(
});
return response;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์ฃผ๋ฌธ ๋‚ด์—ญ ์กฐํšŒ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : '์ฃผ๋ฌธ ๋‚ด์—ญ ์กฐํšŒ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
Expand All @@ -154,7 +155,7 @@ export async function getRefundInfo(
);
return response;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('ํ™˜๋ถˆ ์ •๋ณด ์กฐํšŒ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : 'ํ™˜๋ถˆ ์ •๋ณด ์กฐํšŒ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
Expand All @@ -175,7 +176,7 @@ export async function cancelOrder(
revalidatePath('/orders');
return response;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์ฃผ๋ฌธ ์ทจ์†Œ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : '์ฃผ๋ฌธ ์ทจ์†Œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
Expand All @@ -189,7 +190,7 @@ export async function getOrderDetail(orderId: number): Promise<OrderDetail> {
const orderDetail = await api.get<OrderDetail>(`/orders/${orderId}`);
return orderDetail;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์ฃผ๋ฌธ ์ƒ์„ธ ์กฐํšŒ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : '์ฃผ๋ฌธ ์ƒ์„ธ ์กฐํšŒ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
Expand All @@ -203,7 +204,7 @@ export async function deleteOrder(orderId: number): Promise<void> {
await api.delete(`/orders/${orderId}`);
revalidatePath('/orders');
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์ฃผ๋ฌธ ๋‚ด์—ญ ์‚ญ์ œ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : '์ฃผ๋ฌธ ๋‚ด์—ญ ์‚ญ์ œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
Expand Down
39 changes: 37 additions & 2 deletions src/app/actions/product.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
'use server';

import { api } from '@/lib/api-client';
import type { ProductDetail } from '@/types/domain/product';
import { rethrowNextError } from '@/lib/server-action-utils';
import type {
Product,
ProductDetail,
ProductOption,
} from '@/types/domain/product';

/** ์ƒํ’ˆ ์ƒ์„ธ ์กฐํšŒ */
export async function getProductDetail(
Expand All @@ -11,10 +16,40 @@ export async function getProductDetail(
const product = await api.get<ProductDetail>(`/products/${productId}`);
return product;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์ƒํ’ˆ ์ƒ์„ธ ์กฐํšŒ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : '์ƒํ’ˆ ์ƒ์„ธ ์กฐํšŒ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
);
}
}

/** ๋น„์Šทํ•œ ์ƒํ’ˆ ์กฐํšŒ */
export async function getSimilarProducts(
productId: number,
): Promise<Product[]> {
try {
const products = await api.get<Product[]>(`/products/${productId}/similar`);
return products;
} catch (error) {
rethrowNextError(error);
console.error('๋น„์Šทํ•œ ์ƒํ’ˆ ์กฐํšŒ ์‹คํŒจ:', error);
return [];
}
}

/** ์ƒํ’ˆ ์˜ต์…˜ ์กฐํšŒ */
export async function getProductOptions(
productId: number,
): Promise<ProductOption[]> {
try {
const options = await api.get<ProductOption[]>(
`/products/${productId}/options`,
);
return options;
} catch (error) {
rethrowNextError(error);
console.error('์ƒํ’ˆ ์˜ต์…˜ ์กฐํšŒ ์‹คํŒจ:', error);
return [];
}
}
3 changes: 2 additions & 1 deletion src/app/actions/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use server';

import { api } from '@/lib/api-client';
import { rethrowNextError } from '@/lib/server-action-utils';
import type { UserInfoResDto } from '@/types/domain/user';

/** ๋‚ด ์ •๋ณด ์กฐํšŒ */
Expand All @@ -12,7 +13,7 @@ export async function getUserInfo(): Promise<UserInfoResDto> {
}
return user;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('์œ ์ € ์ •๋ณด ์กฐํšŒ ์‹คํŒจ:', error);
throw new Error(
error instanceof Error ? error.message : '์œ ์ € ์ •๋ณด ์กฐํšŒ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
Expand Down
7 changes: 4 additions & 3 deletions src/app/actions/wishlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { revalidatePath } from 'next/cache';
import { api } from '@/lib/api-client';
import { rethrowNextError } from '@/lib/server-action-utils';
import { WishlistItem } from '@/types/domain/wishlist';

/**
Expand All @@ -19,7 +20,7 @@ export async function addToWishlist(productId: number) {

return { success: true, data };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Add to wishlist error:', error);
return { success: false, error: '์ฐœํ•˜๊ธฐ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.' };
}
Expand All @@ -36,7 +37,7 @@ export async function deleteFromWishlist(wishlistId: number) {

return { success: true, wishlistId };
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Delete from wishlist error:', error);
return { success: false, error: '์ฐœ ์ทจ์†Œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.' };
}
Expand All @@ -52,7 +53,7 @@ export async function getMyWishlist(categoryId?: number) {

return data;
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Get wishlist error:', error);
return [];
}
Expand Down
6 changes: 4 additions & 2 deletions src/app/body-info/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { fetchUserBodyInfo } from '@/mocks/size';
import { getMyBodyInfoAction } from '@/app/actions/body-info';
import { BodyInfoForm } from '@/components/product/size/body-info-form';
import { CloseButton } from '../../components/ui/close-button';

// ๋‚ด ์‹ ์ฒด ์ •๋ณด ์ˆ˜์ • ํŽ˜์ด์ง€(๋งˆ์ดํŽ˜์ด์ง€์šฉ)

export default async function BodyInfoPage() {
const userInfo = await fetchUserBodyInfo();
const result = await getMyBodyInfoAction();
const userInfo =
result.success && result.data?.hasBodyInfo ? result.data : null;

return (
<div className="flex h-full items-center justify-center bg-gray-50">
Expand Down
11 changes: 5 additions & 6 deletions src/app/cart/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Metadata } from 'next';
import { getCartItems } from '@/app/actions/cart';
import { rethrowNextError } from '@/lib/server-action-utils';
import { CloseButton } from '@/components/ui/close-button';
import { CartProvider } from '@/components/cart/cart-context';
import {
CartHeaderControl,
CartItemList,
CartSummaryFooter,
} from '@/components/cart/cart-views';
import CartHeaderControl from '@/components/cart/cart-header-control';
import CartItemList from '@/components/cart/cart-item-list';
import CartSummaryFooter from '@/components/cart/cart-summary-footer';
import type { CartResponse } from '@/types/domain/cart';

export const metadata: Metadata = {
Expand All @@ -20,7 +19,7 @@ export default async function CartPage() {
try {
cartItems = await getCartItems();
} catch (error) {
if (error instanceof Error && 'digest' in error) throw error;
rethrowNextError(error);
console.error('Failed to fetch cart items:', error);
}

Expand Down
2 changes: 1 addition & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Geist, Geist_Mono } from 'next/font/google';
import './globals.css';
import ServiceWorkerRegister from '@/components/sw-register';
import { Suspense } from 'react';
import { CartDataFetcher } from '@/components/cart/cart-data-fetcher';
import CartDataFetcher from '@/components/cart/cart-data-fetcher';

const geistSans = Geist({
variable: '--font-geist-sans',
Expand Down
Loading