Skip to content

✨Feat : 로그인 디자인 수정 & api 연결 완료#100

Merged
KongMezu merged 15 commits intodevelopfrom
feat/#98/login-design-api
Nov 10, 2025
Merged

✨Feat : 로그인 디자인 수정 & api 연결 완료#100
KongMezu merged 15 commits intodevelopfrom
feat/#98/login-design-api

Conversation

@KongMezu
Copy link
Copy Markdown
Contributor

@KongMezu KongMezu commented Nov 9, 2025

🔥 작업 내용

  • 로그인 페이지 디자인 수정
  • 소셜 로그인 연동 완료

🤔 추후 작업 사항

  • 헤더 연결

🔗 이슈

PR Point (To Reviewer)

로그인 디자인 수정

피그마 기준 로고를 추가한 로그인 디자인 수정 완료했습니다 :)
로고는 svgo 하려 했으나.. 그냥.. pink mint 일반 넣어놨습니다(수정 필요하면합니다)

소셜 로그인 연동

소셜 로그인 연동 해놨습니다. 따로 auth 페이지 내 api로 작업하려했으나,
유저 정보는 범용적이라 생각해 shared 내 api/auth 로 분리했습니다.

로그인 후 이전 페이지가 있다면 이전 페이지로
없다면 메인페이지로 리다이랙트 하도록 했습니다.

🚀 트러블 슈팅

Api 연결 컴포넌트 pages 내부 컴포넌트 구조 변경

저도 하이브리드형 아키텍처 처음 사용해보면서.. 처음 보는 오류 였고, 꼭 정민님 민균님 두 분 다 보셔야 할 거 같아요..
API 연동 이후 Next.js 15가 pages/** 하위의 모든 .tsx를 라우트 후보로 스캔되면서
pages/auth/components/* 도 전부 페이지로 인식되었고 그 가운데서 build error가 발생했습니다..

그래서 pages/ 아래에서는 단순 라우트 컴포넌트되는 컴포넌트 외
API연결 및 라우팅용이 아닌 UI/로직은 src/features/<domain 이름>/**
브라우저 전용 기능은 클라이언트 훅 + useEffect로만 접근 해야할 거 같습니다.

📸 피그마 스크린샷 or 기능 GIF

구글

-.Clipchamp.mp4

카카오

-.Clipchamp.1.mp4

Summary by CodeRabbit

  • New Features

    • OAuth 콜백 페이지 추가로 임시 토큰 교환 후 자동 리다이렉트 및 로딩 처리 지원
    • 최근 로그인 플랫폼 저장·불러오기용 클라이언트 훅 추가
    • 로고 계열 아이콘 3종(기본·민트·핑크) 추가
  • Improvements

    • 로그인 페이지 UI/레이아웃 개편(중앙 로고, 패딩·간격 조정) 및 최근로그인 표시 개선
    • 로그인 버튼 동작 안정화(클릭 처리 개선, 환경별 오류 처리) 및 접근성 향상
    • 인증 실패 시 안내 및 리다이렉트 처리 강화

@vercel
Copy link
Copy Markdown

vercel bot commented Nov 9, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
af-fe Ready Ready Preview Comment Nov 10, 2025 3:02pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 9, 2025

Walkthrough

OAuth 임시 토큰 교환 콜백 페이지와 관련 API/훅/컴포넌트 및 아이콘 레지스트리 변경을 추가·리팩터링했습니다. 클라이언트 콜백은 temp_token을 교환해 토큰을 저장하고 성공 시 /main으로 리다이렉트합니다.

Changes

Cohort / File(s) 변경 요약
OAuth 콜백 페이지
src/pages/auth/callback.tsx
클라이언트 페이지 추가: 라우터 준비 후 URL에서 temp_token 추출 → exchangeTempToken 호출 → 성공 시 /main으로 이동, 실패/예외 시 /auth로 리다이렉트; 처리 중 Loading 렌더
인증 페이지 리팩토링
src/pages/auth/index.tsx
useRecentLogin 훅 도입으로 최근 플랫폼 저장/복원; 클릭 핸들러에서 플랫폼 저장 후 백엔드 OAuth로 리다이렉트; 비회원 로그인 처리 및 UI·레이아웃/이미지/라우터 정리
토큰 교환 API
src/shared/api/auth.ts
exchangeTempToken(tempToken: string) 추가: /api/auth/temp-token/exchange에 POST, 성공 시 setTokens로 access/refresh 저장하고 응답 반환
API 인스턴스 타입 경로 변경
src/shared/api/instance.ts
ApiResponse, TokenData 타입 임포트 경로를 @/shared/api/types@/shared/types/authtypes로 변경
최근 로그인 훅
src/shared/hooks/useRecentLogin.ts
useRecentLogin() 훅 추가: recentPlatform 상태와 saveRecentPlatform(platform)으로 localStorage(recentLoginPlatform)에 저장/복원 (client-only)
LoginButton 컴포넌트 리팩토링
src/shared/components/auth/LoginButton.tsx
아이콘 경로를 /assets/...로 변경; 플랫폼 검증 추가; onClick이 있으면 우선 실행하고, 없으면 env 기반 OAuth URL 구성·네비게이션 수행; onClick 선택적 prop으로 변경
RecentLoginBubble 내보내기/정렬
src/shared/components/auth/RecentLoginBubble.tsx
export default RecentLoginBubble 복원 및 임포트/포맷 정리 (런타임 동작 유지)
아이콘 레지스트리 및 자산
src/shared/icons/iconNames.ts, src/shared/icons/index.ts
iconNamesLogo, LogoMint, LogoPink 추가 및 해당 SVG 자산 임포트 추가; 일부 import 순서 조정

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AuthPage as /auth
    participant BackendOAuth as Backend OAuth
    participant Callback as /auth/callback
    participant API as /api/auth
    participant Main as /main

    User->>AuthPage: 플랫폼 선택 (Kakao/Google)
    AuthPage->>AuthPage: saveRecentPlatform(platform)
    AuthPage->>BackendOAuth: 리다이렉트 (NEXT_PUBLIC_BACKEND_URL/...)
    BackendOAuth-->>Callback: 리다이렉트 (temp_token 쿼리)
    Callback->>Callback: temp_token 파싱
    Callback->>API: POST /api/auth/temp-token/exchange (exchangeTempToken)
    API-->>Callback: { success, accessToken, refreshToken, message }
    alt 성공
        Callback->>Callback: setTokens(accessToken, refreshToken)
        Callback->>Main: 리다이렉트 (/main)
    else 실패/오류
        Callback->>Callback: alert(message) / 에러 처리
        Callback->>AuthPage: 리다이렉트 (/auth)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 집중 검토 포인트:
    • exchangeTempToken의 에러/응답 처리 및 setTokens 호출 위치
    • useRecentLogin의 클라이언트 전용 초기화(SSR 경계)와 localStorage 접근 시점
    • LoginButton의 env 기반 OAuth URL 구성 및 플랫폼 검증 분기
    • 아이콘 추가로 인한 iconNames 타입 영향과 SVG 임포트 경로 일관성

Possibly related PRs

Suggested labels

feat

Suggested reviewers

  • skyblue1232
  • jjangminii

Poem

🐰 나는 작은 토끼, 토큰을 쫓아 달려가요
임시키로 물고 와서 교환을 마쳐요
기억 한 줌은 localStorage에 담아두고
성공하면 메인으로, 실패면 다시 출발 —
당근 들고 환한 인증의 길을 hop-hop 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 PR의 주요 변경사항을 명확하게 요약하고 있습니다. 로그인 디자인 수정과 API 연결 완료라는 두 가지 핵심 작업을 간결하게 표현했습니다.
Description check ✅ Passed 설명이 템플릿의 필수 섹션을 모두 포함하고 있으며, 작업 내용, 추후 작업, 이슈 링크, 리뷰어를 위한 포인트, GIF 스크린샷을 상세히 제공하고 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#98/login-design-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the api api 연결 label Nov 9, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Nov 9, 2025

🏷️ Labeler has automatically applied labels based on your PR title, branch name, or commit message.
Please verify that they are correct before merging.

1 similar comment
@github-actions
Copy link
Copy Markdown

github-actions bot commented Nov 9, 2025

🏷️ Labeler has automatically applied labels based on your PR title, branch name, or commit message.
Please verify that they are correct before merging.

@github-actions github-actions bot added the comment 필요한 주석 추가 및 변경 label Nov 9, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/auth/components/LoginButton.tsx (1)

1-1: 'use client' 디렉티브 제거 필요

이 프로젝트는 Next.js Pages Router를 사용하고 있어 'use client' 디렉티브가 불필요합니다. App Router에서만 필요한 디렉티브입니다.

Based on learnings

이 diff를 적용하세요:

-'use client';
 import Image from 'next/image';
🧹 Nitpick comments (5)
src/pages/auth/callback.tsx (3)

13-14: router.query 사용 권장

Next.js Pages Router에서는 router.query를 통해 쿼리 파라미터에 직접 접근할 수 있습니다. 수동 파싱보다 안전하고 간결합니다.

이 diff를 적용하세요:

-    const searchParams = new URLSearchParams(router.asPath.split('?')[1]);
-    const tempToken = searchParams.get('temp_token');
+    const tempToken = router.query.temp_token as string | undefined;

15-15: 프로덕션 코드에서 console.log 제거 필요

디버깅용 console.log 문을 제거해주세요.

이 diff를 적용하세요:

     const tempToken = searchParams.get('temp_token');
-    console.log('tempToken:', tempToken);

     if (!tempToken) return;

     const handleLogin = async () => {
       try {
         const res = await exchangeTempToken(tempToken);
-        console.log('API 응답:', res);

         if (res.success) {
-          console.log('redirect to main 페이지');
           router.replace('/main');

Also applies to: 22-22, 25-25


38-38: useEffect 의존성 배열 검토 권장

router.query 사용 시 의존성 배열에 router.query.temp_token를 포함하는 것이 좋습니다. 또는 router 객체 자체를 포함하여 더 안전하게 만들 수 있습니다.

-  }, [router.isReady, router.asPath]);
+  }, [router]);
src/pages/auth/components/LoginButton.tsx (1)

59-68: 환경 변수 검증 추가 권장

process.env.NEXT_PUBLIC_BACKEND_URL이 undefined일 경우를 대비한 검증을 추가하는 것이 좋습니다.

   const handleClick = () => {
     if (onClick) return onClick();
     const base = process.env.NEXT_PUBLIC_BACKEND_URL;
+    if (!base) {
+      console.error('NEXT_PUBLIC_BACKEND_URL is not defined');
+      return;
+    }
     const url =
       platform === 'kakao'
src/pages/auth/index.tsx (1)

14-22: OAuth URL 생성 로직 중복

handleLoginClick의 OAuth URL 생성 로직이 LoginButton.tsxhandleClick과 중복됩니다. 공통 유틸 함수로 추출하는 것을 고려해보세요.

예를 들어, 다음과 같이 공통 함수를 만들 수 있습니다:

// src/shared/utils/oauth.ts
export const getOAuthUrl = (platform: '카카오' | '구글' | 'kakao' | 'google') => {
  const base = process.env.NEXT_PUBLIC_BACKEND_URL;
  if (!base) throw new Error('NEXT_PUBLIC_BACKEND_URL is not defined');
  
  const normalizedPlatform = platform === '카카오' || platform === 'kakao' ? 'kakao' : 'google';
  return `${base}/oauth2/authorization/${normalizedPlatform}`;
};
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 526cfdf and 9191d8d.

⛔ Files ignored due to path filters (3)
  • public/assets/GoogleIcon.svg is excluded by !**/*.svg
  • public/assets/KakaoIcon.svg is excluded by !**/*.svg
  • public/assets/Logo.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • src/pages/auth/callback.tsx (1 hunks)
  • src/pages/auth/components/LoginButton.tsx (1 hunks)
  • src/pages/auth/hooks/useRecentLogin.ts (1 hunks)
  • src/pages/auth/index.tsx (5 hunks)
  • src/shared/api/auth.ts (1 hunks)
  • src/shared/api/instance.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T17:34:04.352Z
Learnt from: jjangminii
Repo: geulDa/FE PR: 64
File: src/pages/map/result/components/ResultMap.tsx:3-3
Timestamp: 2025-10-31T17:34:04.352Z
Learning: The geulDa/FE project uses Next.js Pages Router (not App Router), so components should import useRouter from 'next/router' and should not use the 'use client' directive.

Applied to files:

  • src/pages/auth/index.tsx
  • src/pages/auth/callback.tsx
🧬 Code graph analysis (3)
src/pages/auth/index.tsx (1)
src/pages/auth/hooks/useRecentLogin.ts (1)
  • useRecentLogin (6-20)
src/pages/auth/callback.tsx (2)
src/shared/api/auth.ts (1)
  • exchangeTempToken (5-17)
src/pages/loading/index.tsx (1)
  • Loading (5-37)
src/shared/api/auth.ts (3)
src/shared/api/instance.ts (1)
  • apiAuth (20-23)
src/shared/types/authtypes.ts (2)
  • ApiResponse (1-6)
  • TokenData (8-13)
src/shared/utils/token.ts (1)
  • setTokens (11-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-deploy
🔇 Additional comments (9)
src/shared/api/instance.ts (1)

9-9: 타입 import 경로 정리 확인 완료

타입 정의를 @/shared/types/authtypes로 통합한 것은 좋은 구조입니다. 다른 파일들과의 일관성도 확보되어 있습니다.

src/shared/api/auth.ts (1)

5-17: 임시 토큰 교환 로직 구현 확인 완료

토큰 교환 및 저장 로직이 명확합니다. 에러 핸들링은 호출자(callback.tsx)에서 처리되고 있어 적절합니다.

src/pages/auth/hooks/useRecentLogin.ts (1)

6-20: 최근 로그인 플랫폼 추적 로직 확인 완료

localStorage를 활용한 최근 로그인 플랫폼 추적 구현이 깔끔합니다. useEffect로 클라이언트 사이드에서만 localStorage에 접근하도록 보장되어 있습니다.

src/pages/auth/callback.tsx (1)

24-30: PR 설명과 구현 불일치 확인 필요

PR 설명에는 "로그인 후 이전 페이지 있으면 그곳으로, 없으면 메인 페이지로"라고 명시되어 있으나, 현재 코드는 항상 /main으로 리다이렉트합니다. 의도적으로 나중에 구현 예정인지, 아니면 누락된 것인지 확인이 필요합니다.

이전 페이지로 돌아가는 로직이 필요하다면 다음과 같이 구현할 수 있습니다:

if (res.success) {
  const returnUrl = router.query.returnUrl as string | undefined;
  if (returnUrl) {
    router.replace(returnUrl);
  } else if (document.referrer && document.referrer !== window.location.href) {
    router.back();
  } else {
    router.replace('/main');
  }
}
src/pages/auth/components/LoginButton.tsx (2)

54-57: 플랫폼 유효성 검증 추가 확인 완료

런타임에 잘못된 플랫폼 값을 조기에 감지하는 방어적 코딩이 잘 되어 있습니다.


39-39: 아이콘 파일 경로 검증 완료

지정된 경로에서 아이콘 파일들이 확인되었습니다:

  • public/assets/GoogleIcon.svg
  • public/assets/KakaoIcon.svg

변경된 경로의 파일들이 모두 정상적으로 존재하므로, 아이콘 경로 업데이트가 올바르게 적용되었습니다.

src/pages/auth/index.tsx (3)

25-31: 비회원 로그인 네비게이션 로직 확인 완료

document.referrer를 활용한 이전 페이지 확인 로직이 잘 구현되어 있습니다.


99-99: 최근 로그인 버블 위치 조정 확인 완료

버블 위치가 -3.8rem에서 -2.5rem으로 조정되어 시각적으로 더 적절해 보입니다.

Also applies to: 115-115


72-79: 로고 이미지 최적화 설정 확인 완료

Next.js Image 컴포넌트 사용과 priority 속성 추가로 LCP(Largest Contentful Paint) 최적화가 잘 되어 있습니다. 로고 파일이 올바른 경로(public/assets/Logo.svg)에 존재함을 확인했습니다.

@@ -0,0 +1,41 @@
'use client';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

'use client' 디렉티브 제거 필요

이 프로젝트는 Next.js Pages Router를 사용하고 있어 'use client' 디렉티브가 불필요합니다. App Router에서만 필요한 디렉티브입니다.

Based on learnings

이 diff를 적용하세요:

-'use client';
 import { useEffect } from 'react';
🤖 Prompt for AI Agents
In src/pages/auth/callback.tsx around line 1, remove the top-level "'use
client';" directive because this file lives in the Pages Router and does not
require the App Router client directive; delete that line and verify no other
client-only hooks or browser-only APIs remain that would require converting the
file to a client component.

@@ -0,0 +1,20 @@
'use client';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

'use client' 디렉티브 제거 필요

이 프로젝트는 Next.js Pages Router를 사용하고 있어 'use client' 디렉티브가 불필요합니다. App Router에서만 필요한 디렉티브입니다.

Based on learnings

이 diff를 적용하세요:

-'use client';
 import { useEffect, useState } from 'react';
📝 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
'use client';
import { useEffect, useState } from 'react';
🤖 Prompt for AI Agents
In src/pages/auth/hooks/useRecentLogin.ts around line 1, the file contains a
'use client' directive which is unnecessary for a Pages Router project; remove
the "'use client';" directive from the top of the file (delete that line) so the
hook runs without App Router–specific client directive.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (2)
src/shared/hooks/useRecentLogin.ts (1)

1-1: 'use client' 디렉티브 제거 필요

이 프로젝트는 Next.js Pages Router를 사용하고 있어 'use client' 디렉티브가 불필요합니다.

Based on learnings

-'use client';
 import { useEffect, useState } from 'react';
src/pages/auth/index.tsx (1)

1-1: 'use client' 디렉티브 제거 필요

이 프로젝트는 Next.js Pages Router를 사용하고 있어 'use client' 디렉티브가 불필요합니다.

Based on learnings

-'use client';
 import Image from 'next/image';
🧹 Nitpick comments (1)
src/shared/hooks/useRecentLogin.ts (1)

14-17: localStorage 오류 처리 추가 권장

localStorage.setItem은 저장 공간 초과 또는 비활성화된 경우 예외를 발생시킬 수 있습니다. 에러 처리를 추가하면 더욱 견고한 코드가 됩니다.

다음 diff를 적용하세요:

 const saveRecentPlatform = (platform: string) => {
-  localStorage.setItem(RECENT_LOGIN_KEY, platform);
-  setRecentPlatform(platform);
+  try {
+    localStorage.setItem(RECENT_LOGIN_KEY, platform);
+    setRecentPlatform(platform);
+  } catch (error) {
+    console.error('Failed to save recent login platform:', error);
+  }
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9191d8d and eefa22f.

📒 Files selected for processing (2)
  • src/pages/auth/index.tsx (5 hunks)
  • src/shared/hooks/useRecentLogin.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T17:34:04.352Z
Learnt from: jjangminii
Repo: geulDa/FE PR: 64
File: src/pages/map/result/components/ResultMap.tsx:3-3
Timestamp: 2025-10-31T17:34:04.352Z
Learning: The geulDa/FE project uses Next.js Pages Router (not App Router), so components should import useRouter from 'next/router' and should not use the 'use client' directive.

Applied to files:

  • src/shared/hooks/useRecentLogin.ts
  • src/pages/auth/index.tsx
🧬 Code graph analysis (1)
src/pages/auth/index.tsx (1)
src/shared/hooks/useRecentLogin.ts (1)
  • useRecentLogin (6-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-deploy
🔇 Additional comments (1)
src/pages/auth/index.tsx (1)

72-79: 로고 파일 경로 확인 완료

파일이 public/assets/Logo.svg에 정상적으로 존재하므로 문제가 없습니다. 현재 코드는 올바릅니다.

Comment on lines +25 to 31
const handleGuestClick = () => {
if (document.referrer && document.referrer !== window.location.href) {
router.back();
} else {
router.push('/main');
}
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

document.referrer 사용의 신뢰성 문제

document.referrer는 개인정보 보호 설정, 직접 URL 접근, HTTPS→HTTP 전환 등의 경우 비어있을 수 있어 신뢰할 수 없습니다. 라우터 쿼리 파라미터를 사용하는 것이 더 안정적입니다.

이전 페이지 정보를 라우터 쿼리로 전달하는 방식을 권장합니다:

// 로그인 페이지로 이동할 때
router.push({ pathname: '/auth', query: { returnUrl: router.asPath } });

// handleGuestClick에서
const handleGuestClick = () => {
  const returnUrl = router.query.returnUrl as string;
  if (returnUrl) {
    router.push(returnUrl);
  } else {
    router.push('/main');
  }
};
🤖 Prompt for AI Agents
src/pages/auth/index.tsx around lines 25-31: document.referrer is unreliable;
change handleGuestClick to read a returnUrl from router.query (e.g., const
returnUrl = router.query.returnUrl as string) and if present
router.push(returnUrl) else router.push('/main'); also ensure callers that
navigate to the auth page include the returnUrl in the query (router.push({
pathname: '/auth', query: { returnUrl: router.asPath } })) so the previous page
is reliably preserved; keep a safe fallback to '/main'.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
src/pages/auth/index.tsx (4)

1-1: Pages Router에서는 'use client'가 불필요합니다

Pages Router에서는 기본적으로 클라이언트 컴포넌트이므로 이 디렉티브는 의미가 없고 번들만 늘립니다. 제거해 주세요. Based on learnings


14-20: 표시 문자열로 분기하면 유지보수와 번역 변경 시 바로 깨집니다

OAuth 분기와 최근 로그인 표시가 '카카오', '구글' 같은 한글 레이블에 의존하고 있어 레이블만 바꿔도 로직이 무너집니다. 플랫폼 키와 표시 문자열을 분리해 주세요.

+const PLATFORM = {
+  KAKAO: 'kakao',
+  GOOGLE: 'google',
+} as const;
+
+const PLATFORM_LABEL: Record<(typeof PLATFORM)[keyof typeof PLATFORM], string> = {
+  [PLATFORM.KAKAO]: '카카오',
+  [PLATFORM.GOOGLE]: '구글',
+};
+
-const handleLoginClick = (platform: string) => {
-  saveRecentPlatform(platform);
+const handleLoginClick = (platform: (typeof PLATFORM)[keyof typeof PLATFORM]) => {
+  saveRecentPlatform(PLATFORM_LABEL[platform]);
   const base = process.env.NEXT_PUBLIC_BACKEND_URL;
-  const url =
-    platform === '카카오'
-      ? `${base}/oauth2/authorization/kakao`
-      : `${base}/oauth2/authorization/google`;
+  const url = `${base}/oauth2/authorization/${platform}`;
   window.location.href = url;
 };
 ...
-              <LoginButton
-                platform='kakao'
-                onClick={() => handleLoginClick('카카오')}
-              />
-              {recentPlatform === '카카오' && (
+              <LoginButton
+                platform='kakao'
+                onClick={() => handleLoginClick(PLATFORM.KAKAO)}
+              />
+              {recentPlatform === PLATFORM_LABEL[PLATFORM.KAKAO] && (
 ...
-              <LoginButton
-                platform='google'
-                onClick={() => handleLoginClick('구글')}
-              />
-              {recentPlatform === '구글' && (
+              <LoginButton
+                platform='google'
+                onClick={() => handleLoginClick(PLATFORM.GOOGLE)}
+              />
+              {recentPlatform === PLATFORM_LABEL[PLATFORM.GOOGLE] && (

Also applies to: 94-120


25-30: document.referrer에 의존하면 이전 페이지 복귀가 자주 실패합니다

프라이버시 설정, 직접 접속 등으로 document.referrer가 비어 있으면 원하는 페이지로 돌아가지 못합니다. 쿼리 파라미터로 returnUrl을 넘겨 처리하는 방식으로 신뢰성을 확보해 주세요.

 const handleGuestClick = () => {
-    if (document.referrer && document.referrer !== window.location.href) {
-      router.back();
-    } else {
-      router.push('/main');
-    }
+    const returnUrl = router.query.returnUrl as string | undefined;
+    if (returnUrl) {
+      router.push(returnUrl);
+      return;
+    }
+    router.push('/main');
   };

16-21: 환경 변수 검증 누락으로 로그인 리다이렉트가 깨질 수 있습니다

NEXT_PUBLIC_BACKEND_URL이 비거나 공백이면 undefined/oauth2/...로 이동해 로그인 자체가 막힙니다. 버튼에서도 같은 문제가 있었으니 여기서도 반드시 막아야 합니다.

다음과 같이 방어 로직을 추가해 주세요.

   const handleLoginClick = (platform: string) => {
     saveRecentPlatform(platform);
     const base = process.env.NEXT_PUBLIC_BACKEND_URL;
+    if (!base) {
+      console.error('NEXT_PUBLIC_BACKEND_URL is not defined');
+      return;
+    }
     const url =
       platform === '카카오'
         ? `${base}/oauth2/authorization/kakao`
         : `${base}/oauth2/authorization/google`;
🧹 Nitpick comments (1)
src/shared/components/auth/LoginButton.tsx (1)

29-38: 필수 onClick 때문에 새 폴백 분기가 영원히 실행되지 않습니다

onClick을 필수로 선언하면서 if (onClick) return onClick();으로 즉시 빠져나가고 있어, 기본 리다이렉트 분기는 호출될 수 없습니다. 버튼에서 공통 리다이렉트를 처리하려면 onClick을 옵션으로 낮추거나 폴백 코드를 제거해 중복을 줄여 주세요.

예시는 아래와 같습니다.

-interface LoginButtonProps extends VariantProps<typeof loginButtonVariants> {
-  onClick: () => void;
+interface LoginButtonProps extends VariantProps<typeof loginButtonVariants> {
+  onClick?: () => void;
   className?: string;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eefa22f and e2c0397.

📒 Files selected for processing (3)
  • src/pages/auth/index.tsx (5 hunks)
  • src/shared/components/auth/LoginButton.tsx (1 hunks)
  • src/shared/components/auth/RecentLoginBubble.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T17:34:04.352Z
Learnt from: jjangminii
Repo: geulDa/FE PR: 64
File: src/pages/map/result/components/ResultMap.tsx:3-3
Timestamp: 2025-10-31T17:34:04.352Z
Learning: The geulDa/FE project uses Next.js Pages Router (not App Router), so components should import useRouter from 'next/router' and should not use the 'use client' directive.

Applied to files:

  • src/pages/auth/index.tsx
🧬 Code graph analysis (3)
src/pages/auth/index.tsx (1)
src/shared/hooks/useRecentLogin.ts (1)
  • useRecentLogin (6-20)
src/shared/components/auth/RecentLoginBubble.tsx (1)
src/shared/lib/utils.ts (1)
  • cn (71-73)
src/shared/components/auth/LoginButton.tsx (1)
src/shared/lib/utils.ts (1)
  • cn (71-73)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-deploy

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/shared/icons/index.ts (1)

1-1: 자동 생성 파일을 수동으로 수정함

iconNames.ts와 마찬가지로 이 파일도 "자동 생성 파일입니다. (직접 수정 금지)" 주석이 있지만 수동으로 수정되었습니다. 로고 SVG import 추가 및 backto.svg import 위치 변경이 수동으로 이루어졌습니다.

아이콘 생성 프로세스를 통해 이러한 변경사항을 반영하거나, 파일이 더 이상 자동 생성되지 않는다면 주석을 업데이트하세요.

Also applies to: 2-2, 15-17

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2c0397 and 0a1560a.

⛔ Files ignored due to path filters (24)
  • src/shared/icons/source/CalendarBlank.svg is excluded by !**/*.svg
  • src/shared/icons/source/Caret.svg is excluded by !**/*.svg
  • src/shared/icons/source/ChatCircle.svg is excluded by !**/*.svg
  • src/shared/icons/source/Check.svg is excluded by !**/*.svg
  • src/shared/icons/source/CopySimple.svg is excluded by !**/*.svg
  • src/shared/icons/source/Export.svg is excluded by !**/*.svg
  • src/shared/icons/source/FadersHorizontal.svg is excluded by !**/*.svg
  • src/shared/icons/source/GoogleIcon.svg is excluded by !**/*.svg
  • src/shared/icons/source/HeartStraight.svg is excluded by !**/*.svg
  • src/shared/icons/source/HouseSimple.svg is excluded by !**/*.svg
  • src/shared/icons/source/KakaoIcon.svg is excluded by !**/*.svg
  • src/shared/icons/source/ListButton.svg is excluded by !**/*.svg
  • src/shared/icons/source/Logo.svg is excluded by !**/*.svg
  • src/shared/icons/source/LogoMint.svg is excluded by !**/*.svg
  • src/shared/icons/source/LogoPink.svg is excluded by !**/*.svg
  • src/shared/icons/source/MapPin.svg is excluded by !**/*.svg
  • src/shared/icons/source/MapPin_.svg is excluded by !**/*.svg
  • src/shared/icons/source/NextButton.svg is excluded by !**/*.svg
  • src/shared/icons/source/PressStamp.svg is excluded by !**/*.svg
  • src/shared/icons/source/Save.svg is excluded by !**/*.svg
  • src/shared/icons/source/Stamp.svg is excluded by !**/*.svg
  • src/shared/icons/source/User.svg is excluded by !**/*.svg
  • src/shared/icons/source/backto.svg is excluded by !**/*.svg
  • src/shared/icons/source/x.svg is excluded by !**/*.svg
📒 Files selected for processing (3)
  • src/pages/auth/index.tsx (5 hunks)
  • src/shared/icons/iconNames.ts (1 hunks)
  • src/shared/icons/index.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T17:34:04.352Z
Learnt from: jjangminii
Repo: geulDa/FE PR: 64
File: src/pages/map/result/components/ResultMap.tsx:3-3
Timestamp: 2025-10-31T17:34:04.352Z
Learning: The geulDa/FE project uses Next.js Pages Router (not App Router), so components should import useRouter from 'next/router' and should not use the 'use client' directive.

Applied to files:

  • src/pages/auth/index.tsx
🧬 Code graph analysis (1)
src/pages/auth/index.tsx (1)
src/shared/hooks/useRecentLogin.ts (1)
  • useRecentLogin (6-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-deploy
🔇 Additional comments (3)
src/pages/auth/index.tsx (2)

72-79: 로고 영역 구현 확인

새로 추가된 Logo 아이콘 컴포넌트를 사용하여 깔끔하게 구현되었습니다. 같은 PR에서 아이콘 정의와 사용이 함께 이루어져 일관성이 있습니다.


118-123: 비회원 로그인 버튼 구현 양호

텍스트를 클릭 가능한 요소로 만들고 적절한 시각적 피드백(underline, cursor-pointer)을 제공하여 사용자 경험이 개선되었습니다.

src/shared/icons/iconNames.ts (1)

1-1: 원본 리뷰 코멘트는 부정확합니다

검증 결과, "Logo", "LogoMint", "LogoPink" 세 아이콘은 수동으로 추가된 것이 아닙니다. src/shared/icons/source/ 디렉토리에 실제로 존재하는 SVG 파일들이며, generate-icon-list.ts 스크립트가 이 디렉토리의 모든 SVG 파일을 자동으로 감지하여 iconNames.ts를 생성합니다. 따라서 파일이 재생성되어도 이 아이콘들이 손실되지 않습니다. 현재 상태는 정상이며 조치가 필요 없습니다.

Likely an incorrect or invalid review comment.

Comment on lines +127 to +129
<div className='mt-[5rem] text-label-md text-gray-400 whitespace-nowrap text-ellipsis overflow-hidden text-center'>
<p>비회원은 스탬프 저장과 공유 기능을 사용할 수 없습니다.</p>
</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

중요 안내문이 잘릴 수 있음

whitespace-nowraptext-ellipsis로 인해 좁은 화면에서 비회원 제한사항 안내문이 잘려서 표시될 수 있습니다. 사용자가 게스트 로그인을 선택하기 전에 이 정보를 완전히 읽을 수 있어야 합니다.

다음 diff를 적용하여 텍스트를 여러 줄로 표시하도록 수정하세요:

-        <div className='mt-[5rem] text-label-md text-gray-400 whitespace-nowrap text-ellipsis overflow-hidden text-center'>
+        <div className='mt-[5rem] text-label-md text-gray-400 text-center'>
           <p>비회원은 스탬프 저장과 공유 기능을 사용할 수 없습니다.</p>
         </div>
📝 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
<div className='mt-[5rem] text-label-md text-gray-400 whitespace-nowrap text-ellipsis overflow-hidden text-center'>
<p>비회원은 스탬프 저장과 공유 기능을 사용할 수 없습니다.</p>
</div>
<div className='mt-[5rem] text-label-md text-gray-400 text-center'>
<p>비회원은 스탬프 저장과 공유 기능을 사용할 수 없습니다.</p>
</div>
🤖 Prompt for AI Agents
In src/pages/auth/index.tsx around lines 127 to 129, the guest-notice div uses
whitespace-nowrap and text-ellipsis causing the important message to be
truncated on narrow screens; remove whitespace-nowrap and text-ellipsis and
allow wrapping by replacing them with whitespace-normal and break-words (you can
keep overflow-hidden and text-center if desired) so the paragraph flows to
multiple lines and remains fully readable on small viewports.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/shared/components/auth/LoginButton.tsx (1)

38-53: 성능 최적화: iconData를 컴포넌트 외부로 이동하세요.

iconData 객체가 매 렌더링마다 재생성됩니다. 이 객체는 정적 데이터이므로 컴포넌트 외부에 선언하여 불필요한 메모리 할당을 방지하세요.

컴포넌트 정의 위쪽으로 iconData를 이동하세요:

 );

+const iconData = {
+  google: {
+    src: '/assets/GoogleIcon.svg',
+    alt: 'Google Logo',
+    width: 36,
+    height: 36,
+    label: '구글 로그인',
+  },
+  kakao: {
+    src: '/assets/KakaoIcon.svg',
+    alt: 'Kakao Logo',
+    width: 28,
+    height: 28,
+    label: '카카오 로그인',
+  },
+} as const;
+
 interface LoginButtonProps extends VariantProps<typeof loginButtonVariants> {
   onClick?: () => void;
   className?: string;
 }

 export default function LoginButton({
   onClick,
   platform,
   className,
 }: LoginButtonProps) {
-  const iconData = {
-    google: {
-      src: '/assets/GoogleIcon.svg',
-      alt: 'Google Logo',
-      width: 36,
-      height: 36,
-      label: '구글 로그인',
-    },
-    kakao: {
-      src: '/assets/KakaoIcon.svg',
-      alt: 'Kakao Logo',
-      width: 28,
-      height: 28,
-      label: '카카오 로그인',
-    },
-  };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70e4c51 and bc7356d.

📒 Files selected for processing (3)
  • src/pages/auth/index.tsx (5 hunks)
  • src/shared/components/auth/LoginButton.tsx (1 hunks)
  • src/shared/hooks/useRecentLogin.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/shared/hooks/useRecentLogin.ts
  • src/pages/auth/index.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/shared/components/auth/LoginButton.tsx (2)
src/shared/lib/utils.ts (1)
  • cn (71-73)
src/pages/auth/components/LoginButton.tsx (2)
  • LoginButton (33-67)
  • LoginButtonProps (28-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-deploy
🔇 Additional comments (2)
src/shared/components/auth/LoginButton.tsx (2)

8-26: LGTM!

loginButtonVariants 정의가 올바르며, CVA를 활용한 플랫폼별 스타일링이 적절합니다.


76-85: LGTM!

버튼 JSX가 올바르게 구성되어 있으며, aria-label을 통한 접근성 처리가 적절합니다. priority 속성을 통해 아이콘이 우선적으로 로드되는 점도 좋습니다.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
src/pages/auth/index.tsx (2)

1-1: 'use client' 디렉티브 제거 필요
이 페이지는 Pages Router에서 렌더되므로 'use client'가 아무 효과 없이 빌드 아웃풋만 어지럽힙니다. 최상단 한 줄을 제거해 주세요. Based on learnings


41-46: document.referrer 의존을 제거하고 쿼리 파라미터를 사용하세요
document.referrer는 브라우저/보안 설정에 따라 비어 있을 수 있어 복귀 경로가 자주 유실됩니다. 로그인 진입 시 returnUrl을 쿼리로 넘기고 여기서는 그 값을 읽어 분기하도록 바꿔 주세요. Based on learnings

src/shared/components/auth/LoginButton.tsx (1)

62-71: NEXT_PUBLIC_BACKEND_URL 누락 시 사용자 안내가 없습니다
환경 변수가 빠지면 버튼이 조용히 return되어 로그인 기능이 전혀 동작하지 않습니다. 프로덕션에서도 즉시 알림(토스트/모달 등)을 띄우고, 개발 환경에서는 콘솔 로그나 예외로 원인을 드러내 주세요. 기존 리뷰와 동일한 지적이므로 이번에 처리 부탁드립니다.

-    if (!base) {
-      const message = 'NEXT_PUBLIC_BACKEND_URL is not defined';
-      if (process.env.NODE_ENV === 'development') {
-        throw new Error(message);
-      }
-      console.error(message);
-      return;
-    }
+    if (!base) {
+      const message = 'NEXT_PUBLIC_BACKEND_URL가 설정되지 않아 로그인을 진행할 수 없습니다.';
+      if (process.env.NODE_ENV === 'development') {
+        throw new Error(message);
+      }
+      console.error(message);
+      alert(message); // 전역 알림 유틸이 있다면 그쪽을 호출해 주세요.
+      return;
+    }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc7356d and d326c3d.

📒 Files selected for processing (2)
  • src/pages/auth/index.tsx (5 hunks)
  • src/shared/components/auth/LoginButton.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T17:34:04.352Z
Learnt from: jjangminii
Repo: geulDa/FE PR: 64
File: src/pages/map/result/components/ResultMap.tsx:3-3
Timestamp: 2025-10-31T17:34:04.352Z
Learning: The geulDa/FE project uses Next.js Pages Router (not App Router), so components should import useRouter from 'next/router' and should not use the 'use client' directive.

Applied to files:

  • src/pages/auth/index.tsx
  • src/shared/components/auth/LoginButton.tsx
🧬 Code graph analysis (2)
src/pages/auth/index.tsx (2)
src/shared/hooks/useRecentLogin.ts (1)
  • useRecentLogin (6-21)
src/shared/icons/components/icon.tsx (1)
  • Icon (57-129)
src/shared/components/auth/LoginButton.tsx (1)
src/shared/lib/utils.ts (1)
  • cn (71-73)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-deploy

)?.[0];
if (!platform) return;

saveRecentPlatform(platform);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

최근 로그인 말풍선이 항상 숨겨집니다
saveRecentPlatform에 저장되는 값이 'kakao'/'google'인데 아래 렌더 조건은 '카카오'/'구글'과 비교하고 있어 항상 false가 됩니다. 결과적으로 최근 로그인 말풍선이 표시되지 않는 회귀가 발생합니다. 저장 값을 표시 문자열로 유지하거나 조건식을 PLATFORM 상수와 일치하도록 수정해 주세요.

-    saveRecentPlatform(platform);
+    saveRecentPlatform(platformDisplay);
🤖 Prompt for AI Agents
In src/pages/auth/index.tsx around line 30, the recent-login bubble never shows
because saveRecentPlatform stores 'kakao'/'google' but the render condition
compares against Korean display strings ('카카오'/'구글'), causing a permanent false;
fix by making the condition match the stored value—either change the render
check to use the PLATFORM constant or the lowercase keys ('kakao'/'google') (or
map stored keys to display labels before checking), or alternatively change
saveRecentPlatform to persist the display string consistently; update whichever
side is simplest to keep key/display usage consistent across save and render.

Comment on lines +32 to +37
if (!base) {
console.error('NEXT_PUBLIC_BACKEND_URL is not defined');
return;
}
const url = `${base}/oauth2/authorization/${platform}`;
window.location.href = url;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

환경 변수 누락 시 사용자 피드백 추가 필요
NEXT_PUBLIC_BACKEND_URL이 비어 있으면 콘솔 로그만 남기고 return되어 사용자는 클릭해도 아무 반응이 없는 것처럼 보입니다. 구성 실수 시 로그인 기능이 완전히 막히므로 토스트·알림 등을 통해 즉시 안내하고 개발 환경에서만 상세 로그를 출력해 주세요.

-    if (!base) {
-      console.error('NEXT_PUBLIC_BACKEND_URL is not defined');
-      return;
-    }
+    if (!base) {
+      const message = '로그인 서버 설정이 누락되어 로그인을 진행할 수 없습니다.';
+      if (process.env.NODE_ENV === 'development') {
+        console.error(message);
+      }
+      alert(message); // 앱의 알림/토스트 유틸이 있다면 그쪽을 사용해 주세요.
+      return;
+    }
🤖 Prompt for AI Agents
In src/pages/auth/index.tsx around lines 32 to 37 the code silently returns when
NEXT_PUBLIC_BACKEND_URL is missing; change this so users get immediate feedback
and developers still see details: detect missing base, call the app's
user-facing notification (toast/alert) to show a clear message like "Login
unavailable — backend URL not configured", then return; keep the detailed
console.error or console.debug but only when process.env.NODE_ENV !==
'production' (or use isDev flag) so devs see the error details; ensure you
import/ use the existing notification utility and keep the early return after
notifying the user.

Copy link
Copy Markdown
Contributor

@skyblue1232 skyblue1232 left a comment

Choose a reason for hiding this comment

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

빠른 구현 감사합니다!! 수고하셨습니다!
궁금한 점이 있는데 Next.js로 소셜 로그인 연결하는 방법이 React와 같은가요? 차이점이 있다면 궁금합니다!

@KongMezu
Copy link
Copy Markdown
Contributor Author

빠른 구현 감사합니다!! 수고하셨습니다! 궁금한 점이 있는데 Next.js로 소셜 로그인 연결하는 방법이 React와 같은가요? 차이점이 있다면 궁금합니다!

엄청 큰 차이는 없습니다! OAuth 연결 흐름은 동일하나 SSR 환경을 고려해서 API Route에서 토큰 처리를 한다는 차이..? 정도 있습니다!

@KongMezu KongMezu merged commit 7fbe6f5 into develop Nov 10, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api api 연결 comment 필요한 주석 추가 및 변경

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 로그인 페이지 디자인 변경 & api 연결

3 participants