Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 .env.dev
Original file line number Diff line number Diff line change
@@ -1 +1 @@
NEXT_PUBLIC_API_BASE_URL="https://api.8aladin.shop"
NEXT_PUBLIC_API_BASE_URL=https://api.8aladin.shop
10,700 changes: 5,303 additions & 5,397 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
"build-storybook": "storybook build"
},
"dependencies": {
"antd": "^5.27.4",
"antd": "^6.0.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

antd v6 migration guide breaking changes

💡 Result:

Key breaking changes & migration notes for Ant Design v6 (summary):

  • Minimum React required: React 18 (v6 targets React 18+, React 19 recommended). Migrate your app to React 18+ before upgrading. [1][2]
  • Styling architecture: moved to a pure CSS‑variables styling system / semantic CSS structure (affects theming, custom style overrides and any low‑level CSS assumptions). Update custom themes/CSS accordingly. [1][3]
  • IE11 and legacy browser support removed — polyfills/IE workarounds must be removed or kept on the old major. [1][3]
  • No codemod/compat package needed when upgrading from v5 — upgrade is intended to be “smooth” from v5 (still verify component API changes you use). [2]
  • React Compiler enabled in distributed builds (affects bundling/compat with older React toolchains). [2]
  • Remove or replace any v5->v6 deprecated compatibility shims (e.g., patches for React 19 are no longer required). [2]
  • Expect semantic/structure changes in components (props or DOM structure may change; test UI and custom style/selectors). [1][3]

Recommended migration steps

  • Upgrade React to 18+ (prefer React 19 if possible). [2]
  • Run your test suite and visual checks; search console for deprecation warnings and fix usages before upgrading. [1]
  • Update custom theming and CSS that relied on former Less/CSS implementation to use the new CSS‑variables approach. [1][3]
  • Review components you heavily customized (DOM/className/structure) and test them after upgrade. [1][3]

Sources:
[1] Ant Design v6 migration doc (official). (ant.design)
[2] Ant Design v6 release announcement / GitHub issue. (github.com)
[3] Ant Design X / blog notes on v6 (styling, IE drop, semantic changes). (github.com)

If you want, I can open the official v6 migration page and extract the exact migration checklist and component-level breaking changes for the components you use — tell me which components you rely on.

Citations:


🏁 Script executed:

# Search for Space component usage in the codebase
rg "Space" --type tsx --type ts --type jsx --type js -i -A 2 -B 2

Repository: 8aladin-Project/frontend

Length of output: 95


🏁 Script executed:

# First, check what file types exist in the repo
git ls-files | head -20

# Then search for Space component usage
rg "Space" -i -A 2 -B 2 --max-count 20

Repository: 8aladin-Project/frontend

Length of output: 15473


antd v6 メジャーバージョンアップグレード対応確認必須

antdをv5からv6にアップグレードする場合、複数の破壊的変更に対応が必要です。Spaceコンポーネントのdirectionorientation変更を含む、APIの互換性がなくなる変更があります。既に一部ファイル(ItemList.tsx、ProfileSection.tsx)ではv6 APIへの移行が確認できますが、edit/page.tsxなどではまだ旧APIが使用されています。さらに、antd v6ではスタイリングシステムがCSS変数ベースに変更され、React 18以上が必須となるため、公式マイグレーションガイドに従い、すべてのコンポーネント使用状況とカスタムスタイル、テーマをv6互換に更新してください。

🤖 Prompt for AI Agents
In package.json around line 17, upgrading antd to v6 requires a codebase-wide
migration—identify and update all usages of removed/renamed APIs (e.g., Space:
direction → orientation), update files still using v5 APIs (edit/page.tsx and
any others), ensure React is bumped to >=18 in package.json and lockfiles,
migrate custom styles/themes to the new CSS-variables based styling (replace
legacy token usage and overrides with v6 theme tokens), and follow the official
antd v6 migration guide: run a repo-wide search for antd components, update each
to v6 props/exports, adjust imports and custom CSS, then run the app and tests
to verify visual and runtime regressions.

"axios": "^1.13.2",
"clsx": "^2.1.1",
"next": "^15.5.7",
"react": "^19.1.2",
"react-dom": "^19.1.2"
"react-dom": "^19.1.2",
"recoil": "^0.7.7"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Recoil React 19 compatibility 2025

💡 Result:

Short answer: Recoil is not reliably compatible with React 19 (as of late 2024–2025). The Recoil repo was archived on Jan 1, 2025 and there are open issues/reports of runtime errors when running Recoil on React 19; most community guidance is to stay on React 18 or migrate to a maintained state library (Zustand/Redux/Jotai, etc.). [1][2][3]

Sources:

  • Recoil GitHub (React 19 support issue / repo archived Jan 1, 2025). [1]
  • React v19 announcement (React 19 stable release). [2]
  • Community reports / Q&A showing Recoil errors on React 19 and recommending alternatives. [3]

🌐 Web query:

Recoil Meta discontinued maintenance status 2025

💡 Result:

Short answer: Recoil (facebookexperimental/Recoil) was archived and is no longer actively maintained — the repository was marked read-only on Jan 1, 2025. [1][2]

Sources:

  • GitHub repository archive notice (archived by owner on Jan 1, 2025). [1]
  • GitHub issues/discussions and community threads noting the project is no longer actively maintained and linking the archive. [2][3]

🌐 Web query:

Jotai Zustand active development 2025

💡 Result:

Short answer: Yes — both Jotai and Zustand were actively developed in 2025.

  • Zustand: active repo and releases in 2025 (pmndrs/zustand GitHub activity and 2025 releases). [1][2]
  • Jotai: active repo with recent pushes and ongoing PR activity in 2025; project site and package releases also updated in 2025. [3][4]

Sources:
[1] pmndrs/zustand GitHub.
[2] pmndrs/zustand release notes (2025 releases).
[3] pmndrs/jotai GitHub (last pushed May 27, 2025; active PRs).
[4] jotai.org / package release metadata (2025 releases).


Switch from Recoil to an actively maintained state management library

Recoil was archived and discontinued by Meta on January 1, 2025, and is no longer actively maintained. It has documented compatibility issues with React 19 that cause runtime errors. For long-term project maintenance, consider migrating to actively developed alternatives like Zustand or Jotai.

},
"devDependencies": {
"@chromatic-com/storybook": "^4.1.1",
Expand Down
Binary file added public/googleIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/naverIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 45 additions & 2 deletions src/api/axiosInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,32 @@ const axiosInstance = axios.create({
headers: {
"Content-Type": "application/json",
},
withCredentials: true, // 쿠키를 포함하여 요청 전송
});

// 쿠키에서 accessToken을 읽어오는 유틸리티 함수
function getCookie(name: string): string | null {
if (typeof document === "undefined") return null;

const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);

if (parts.length === 2) {
return parts.pop()?.split(";").shift() || null;
}
return null;
}

// 요청 인터셉터
axiosInstance.interceptors.request.use(
config => {
// 필요시 토큰 추가 등의 로직
// 쿠키에서 accessToken을 읽어서 Authorization 헤더에 추가
const accessToken = getCookie("accessToken");

if (accessToken && config.headers) {
config.headers.Authorization = `Bearer ${accessToken}`;
}

return config;
},
error => {
Expand All @@ -24,7 +44,28 @@ axiosInstance.interceptors.response.use(
return response;
},
error => {
// 에러 처리 로직
// 401 에러 처리
if (error.response?.status === 401) {
// 인증이 필요한 경우에만 로그인 페이지로 리다이렉트
// 채팅방 생성 API는 permitAll이므로 여기서 리다이렉트하지 않음
console.error("인증 오류:", error.response?.data);

// 로그인이 필요한 API에 대해서만 리다이렉트
// 현재 요청 URL이 인증이 필요하지 않은 엔드포인트인지 확인
const url = error.config?.url || "";
const isPublicEndpoint =
url.includes("/api/v1/chatrooms") ||
url.includes("/api/v1/products") ||
url.includes("/api/v1/images");
Comment on lines +56 to +59

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

공개 엔드포인트 목록이 하드코딩되어 있어 유지보수가 어렵습니다. 새로운 공개 API가 추가될 때마다 이 코드를 수정해야 합니다. 엔드포인트 목록을 별도의 설정 파일이나 배열로 관리하여 확장성을 높이는 것을 고려해보세요.

예시:

const publicEndpoints = [
  "/api/v1/chatrooms",
  "/api/v1/products",
  "/api/v1/images",
];

const isPublicEndpoint = publicEndpoints.some(endpoint => url.includes(endpoint));


// 공개 엔드포인트가 아니고, 로그인 페이지가 아닌 경우에만 리다이렉트
if (!isPublicEndpoint && typeof window !== "undefined" && !window.location.pathname.startsWith("/login")) {
// 로그인 페이지로 리다이렉트할 때 현재 URL을 저장
const currentUrl = window.location.pathname + window.location.search;
window.location.href = `/login?redirect=${encodeURIComponent(currentUrl)}`;
}
}

return Promise.reject(error);
}
);
Expand All @@ -33,3 +74,5 @@ export default axiosInstance;





35 changes: 35 additions & 0 deletions src/api/chat/apis.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
import axiosInstance from "../axiosInstance";

// 채팅방 생성 요청 타입
export interface CreateChatRoomRequest {
sellerId: number;
buyerId: number;
productId: number;
}

// 채팅방 생성 응답 타입
export interface ChatRoomResponse {
chatRoomId: number;
sellerId: number;
sellerName: string;
buyerId: number;
buyerName: string;
productId: number;
productTitle: string;
createdAt: string;
updatedAt: string;
}

/**
* 채팅방 생성 API
*/
export async function createChatRoom(
request: CreateChatRoomRequest
): Promise<ChatRoomResponse> {
const response = await axiosInstance.post<ChatRoomResponse>(
"/api/v1/chatrooms",
request
);
return response.data;
}

// 더미 데이터
export async function getChatRoomDetails(roomId: string) {
return {
Expand Down
31 changes: 31 additions & 0 deletions src/api/signup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import axiosInstance from "./axiosInstance";

// 회원가입 요청 타입
export interface SignupRequest {
name: string;
email: string;
password: string;
mobileNumber: string;
}

// 회원가입 응답 타입
export interface SignupResponse {
memberId: number;
name: string;
email: string;
message: string;
}

// 회원가입 API
export async function signup(
signupData: SignupRequest
): Promise<SignupResponse> {
const response = await axiosInstance.post<SignupResponse>(
"/api/v1/members/signup",
signupData
);
console.log("요청 URL:", response.config.url);
console.log("응답 데이터:", response.data);
console.log("요청 데이터:", signupData);
Comment on lines +27 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

디버깅 목적으로 사용된 console.log 구문들이 남아있습니다. 프로덕션 코드에 포함되지 않도록 병합 전에 제거하는 것이 좋습니다.

Comment on lines +27 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

프로덕션 배포 전에 console.log 문을 제거하세요.

디버깅용 console.log 문은 개발 중에는 유용하지만, 프로덕션 코드에는 포함되지 않아야 합니다.

-  console.log("요청 URL:", response.config.url);
-  console.log("응답 데이터:", response.data);
-  console.log("요청 데이터:", signupData);
   return response.data;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log("요청 URL:", response.config.url);
console.log("응답 데이터:", response.data);
console.log("요청 데이터:", signupData);
return response.data;
🤖 Prompt for AI Agents
In src/api/signup.ts around lines 27 to 29 there are console.log statements
printing request URL, response data, and request payload; remove these
console.log calls before production and either delete them or replace them with
calls to the application's structured logger at an appropriate level (e.g.,
logger.debug or logger.info) ensuring sensitive data is not logged (mask or omit
PII/credentials) and that logging respects environment/log level configuration.

return response.data;
}
72 changes: 23 additions & 49 deletions src/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,15 @@

import React from "react";
import { useRouter } from "next/navigation";
import {
handleKakaoLogin,
handleGoogleLogin,
handleNaverLogin,
} from "@/utils/oauthHandlers";

export default function LoginPage() {
const router = useRouter();

const handleKakaoLogin = () => {
console.log("카카오 로그인 시작");
// TODO: 카카오 OAuth 연동
};

const handleGoogleLogin = () => {
console.log("구글 로그인 시작");
// TODO: 구글 OAuth 연동
};

return (
<div className="min-h-screen bg-gradient-to-b from-gray-900 via-black to-gray-900 flex flex-col">
{/* 상단 영역 - 로고 및 타이틀 */}
Expand All @@ -27,24 +22,16 @@ export default function LoginPage() {
<span className="text-white text-4xl font-bold">8</span>
</div>
</div>

{/* 타이틀 */}
<h1 className="text-4xl font-bold text-white mb-3">
8aladin
</h1>
<p className="text-gray-400 text-lg">
안전하고 편리한 중고거래
</p>
<h1 className="text-4xl font-bold text-white mb-3">8aladin</h1>
<p className="text-gray-400 text-lg">안전하고 편리한 중고거래</p>
</div>

{/* 설명 텍스트 */}
<div className="text-center space-y-2 mb-8">
<p className="text-gray-300 text-sm">
간편하게 로그인하고
</p>
<p className="text-gray-300 text-sm">
다양한 중고 상품을 만나보세요
</p>
<p className="text-gray-300 text-sm">간편하게 로그인하고</p>
<p className="text-gray-300 text-sm">다양한 중고 상품을 만나보세요</p>
</div>
</div>

Expand Down Expand Up @@ -75,37 +62,25 @@ export default function LoginPage() {
{/* 구글 로그인 버튼 */}
<button
onClick={handleGoogleLogin}
className="w-full h-14 bg-white hover:bg-gray-50 text-gray-800 font-semibold rounded-xl flex items-center justify-center transition-all duration-200 shadow-lg hover:shadow-xl transform hover:scale-[1.02] active:scale-[0.98]"
className="w-full h-14 bg-[#F2F2F2] hover:bg-gray-50 text-gray-800 font-semibold rounded-xl flex items-center justify-center transition-all duration-200 shadow-lg hover:shadow-xl transform hover:scale-[1.02] active:scale-[0.98]"
>
<div className="flex items-center justify-center gap-3">
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19.805 10.227c0-.709-.064-1.39-.182-2.045H10.1v3.868h5.438a4.648 4.648 0 0 1-2.016 3.049v2.508h3.265c1.91-1.759 3.018-4.35 3.018-7.38Z"
fill="#4285F4"
/>
<path
d="M10.1 20c2.73 0 5.018-.904 6.691-2.453l-3.264-2.509c-.905.609-2.064.968-3.427.968-2.636 0-4.868-1.781-5.664-4.173H1.064v2.59A9.996 9.996 0 0 0 10.1 20Z"
fill="#34A853"
/>
<path
d="M4.436 11.833A6.006 6.006 0 0 1 4.123 10c0-.636.113-1.254.313-1.833V5.577H1.064A9.996 9.996 0 0 0 0 10c0 1.614.386 3.14 1.064 4.423l3.372-2.59Z"
fill="#FBBC04"
/>
<path
d="M10.1 3.994c1.486 0 2.82.51 3.868 1.513l2.9-2.9C15.113.972 12.826 0 10.1 0A9.996 9.996 0 0 0 1.064 5.577l3.372 2.59c.796-2.392 3.028-4.173 5.664-4.173Z"
fill="#EA4335"
/>
</svg>
<img src="/googleIcon.png" alt="구글" className="w-8 h-8" />
<span>구글로 시작하기</span>
</div>
</button>

{/* 네이버 로그인 버튼 */}
<button
onClick={handleNaverLogin}
className="w-full h-14 bg-[#03C75A] hover:bg-[#02B350] text-white font-semibold rounded-xl flex items-center justify-center transition-all duration-200 shadow-lg hover:shadow-xl transform hover:scale-[1.02] active:scale-[0.98]"
>
<div className="flex items-center justify-center gap-3">
<img src="/naverIcon.png" alt="네이버" className="w-8 h-8" />
<span>네이버로 시작하기</span>
</div>
</button>

{/* 구분선 */}
<div className="flex items-center gap-4 py-4">
<div className="flex-1 h-px bg-gray-700"></div>
Expand Down Expand Up @@ -153,4 +128,3 @@ export default function LoginPage() {
</div>
);
}

Loading