Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] Onboarding 페이지 UI 수정 및 이미지 교체 #99

Merged
merged 10 commits into from
Mar 23, 2025

Conversation

semnil5202
Copy link
Collaborator

@semnil5202 semnil5202 commented Mar 21, 2025

📌 개요

  • 온보딩 디자인 수정 및 화질 개선
  • ⭐ login 과 onboarding 라우팅 분리해야함

화면

2025-03-23.16.50.07.mov

Summary by CodeRabbit

  • 새로운 기능

    • 로그인 페이지와 온보딩 경험을 단순화하여 사용자가 온보딩 과정을 원활하게 진행할 수 있도록 업데이트하였습니다.
    • 슬라이드 기반의 온보딩 인터페이스와 다양한 시각적 요소를 도입하여 더욱 매력적인 첫인상을 제공합니다.
    • 새로운 배경 및 장식 요소를 포함한 다양한 컴포넌트를 추가하였습니다.
  • 스타일 변경

    • 주요 인터페이스에 대해 스와이퍼 스타일을 개선하고, 새로운 페이드인 애니메이션을 추가하여 부드러운 전환 효과를 구현하였습니다.

Copy link

coderabbitai bot commented Mar 21, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

이 PR은 로그인 페이지와 온보딩 경험 관련 컴포넌트 및 설정의 전면 개편을 포함합니다. 로그인 페이지의 복잡한 조건부 로직과 불필요한 컴포넌트 임포트를 제거하고, 온보딩 스크린을 직접 렌더링하도록 단순화했습니다. 또한, 첫 번째, 두 번째, 세 번째 온보딩 단계에 대해 데코레이션, 배경, 카드 등 다양한 신규 컴포넌트와 컨테이너가 추가되었습니다. 기존의 Carousel, Slide, Feature, Header 관련 파일이 삭제되었으며, Swiper 스타일링과 Tailwind 애니메이션 설정도 업데이트되었습니다.

Changes

File(s) Change Summary
src/app/login/page.tsx 로그인 페이지에서 조건부 렌더링 및 상태 관리를 제거하고, OnboardingScreen을 직접 렌더링하도록 변경 (불필요 컴포넌트 임포트 제거)
src/app/onboarding/page.tsx
src/features/onboarding/screen/index.tsx
온보딩 페이지 및 스크린 컴포넌트 추가; Swiper를 이용한 온보딩 슬라이드 전환 로직 구현
src/app/globals.css
src/features/home/containers/CardContainer.tsx
Swiper 관련 클래스에 .home-swiper 접두사를 추가하여 스타일 적용 범위를 제한
src/features/onboarding/config/slides.ts
src/features/onboarding/config/slides.tsx
기존 슬라이드 구성 파일 삭제 및 새로운 슬라이드 설정 파일 추가 (컴포넌트 참조 및 다국어 설명 포함)
First Onboarding 컴포넌트
DecoAura.tsx
DecoCircle.tsx
TagGroup.tsx
FirstBackground.tsx
첫 번째 온보딩 단계용 데코레이션 및 배경 컴포넌트 추가
Second Onboarding 컴포넌트
DecoCard.tsx
DecoCircle.tsx
SecondBackground.tsx
SecondOnboardingContainer.tsx
두 번째 온보딩 단계용 데코레이션 카드, 원형 및 배경 컴포넌트 추가 및 레이아웃 컨테이너 생성
Third Onboarding 컴포넌트
DecoCards.tsx
DecoCircle.tsx
DeveloperCard/DecoDesignerCard.tsx
DeveloperCard/DecoDeveloperCard.tsx
ThirdBackground.tsx
ThirdOnboardingContainer.tsx
세 번째 온보딩 단계용 데코레이션 카드, 원형, 개발자 및 디자이너 카드, 배경 컴포넌트와 해당 컨테이너 추가
그 외 온보딩 컨테이너
FirstOnboardingContainer.tsx
BackgroundContainer.tsx
온보딩 단계별 컴포넌트들을 모아 렌더링하는 컨테이너 추가 (activeIndex에 따른 배경 조건부 렌더링 포함)
삭제된 파일
OnboardingCarousel.tsx
OnboardingSlide.tsx
OnboardingFeature.tsx
OnboardingHeader.tsx
이전 온보딩 로직 관련 컴포넌트 및 인터페이스 삭제
tailwind.config.ts 새로운 애니메이션 fade-in 및 해당 keyframes 설정 추가

Suggested labels

🚀 feature, 💄 style

Suggested reviewers

  • jangwonyoon
  • JaeIn1
  • youngju6143
  • evenway2025

Possibly related PRs

  • [feat] 로그인 온보딩 디자인 구현 #39: The changes in the main PR, which simplify the LoginPage component by removing onboarding logic, are related to the retrieved PR that introduces a new LoginPage component with onboarding functionality, as both involve modifications to the LoginPage component in src/app/login/page.tsx.

📜 Recent review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6d4c46 and 16df935.

📒 Files selected for processing (5)
  • src/app/globals.css (2 hunks)
  • src/app/login/page.tsx (1 hunks)
  • src/features/auth/login/ui/LoginFeature.tsx (1 hunks)
  • src/middleware.ts (3 hunks)
  • tailwind.config.ts (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@semnil5202 semnil5202 marked this pull request as draft March 21, 2025 08:40
Copy link

@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: 6

🔭 Outside diff range comments (2)
src/app/login/page.tsx (1)

7-12: ⚠️ Potential issue

사용되지 않는 상태와 함수가 존재합니다.

showOnboarding 상태와 handleOnboardingComplete 함수가 정의되었지만, 현재 코드에서는 사용되지 않고 있습니다. 불필요한 코드는 제거하여 코드 가독성을 향상시키고 유지보수성을 높이는 것이 좋습니다.

export default function LoginPage() {
-  const [showOnboarding, setShowOnboarding] = useState(true);
-
-  const handleOnboardingComplete = () => {
-    setShowOnboarding(false);
-  };

  return <OnboardingScreen />;
}
🧰 Tools
🪛 ESLint

[error] 8-8: 'showOnboarding' is assigned a value but never used. Allowed unused vars must match /^_/u.

(@typescript-eslint/no-unused-vars)


[error] 10-10: 'handleOnboardingComplete' is assigned a value but never used. Allowed unused vars must match /^_/u.

(@typescript-eslint/no-unused-vars)

src/features/onboarding/ui/OnboardingCarousel.tsx (1)

26-32: 🛠️ Refactor suggestion

OnboardingScreen과 일관성 유지 필요.

OnboardingCarouselOnboardingScreen 컴포넌트 사이에 기능이 중복되고 있습니다. 두 컴포넌트 모두 슬라이드 관리 및 handleNext 로직을 포함하고 있어 일관성 문제가 발생할 수 있습니다. 한 컴포넌트에서 기능을 통합하거나 공통 로직을 분리하는 것이 좋습니다.

한 가지 방법은 OnboardingScreen을 기본 컴포넌트로 사용하고, OnboardingCarousel을 제거하거나 리팩토링하는 것입니다. 또는 공통 로직을 분리하여 두 컴포넌트에서 재사용할 수 있습니다.

🧹 Nitpick comments (4)
src/features/onboarding/ui/components/FirstOnboarding.tsx (1)

5-8: 사용되지 않는 변수와 이미지 최적화 문제

현재 코드에서는 description을 구조 분해 할당으로 가져오지만 사용하지 않고 있습니다. 또한 이미지 품질이 100으로 설정되어 성능에 영향을 줄 수 있습니다.

다음과 같이 개선할 것을 제안합니다:

export const FirstOnboarding = () => {
-  const { id, description, imageUrl } = slides[0];
+  const { id, imageUrl } = slides[0];

-  return <Image src={imageUrl} alt={`onboarding-${id}`} width={375} height={812} priority quality={100} />;
+  return <Image src={imageUrl} alt={`onboarding-${id}`} width={375} height={812} priority quality={85} />;
};

이미지 품질을 85로 낮추어도 대부분의 경우 시각적 차이가 거의 없으면서 로딩 속도와 대역폭 사용량을 개선할 수 있습니다. 필요한 경우 description을 활용하여 추가적인 컨텐츠를 표시하는 것을 고려해 보세요.

🧰 Tools
🪛 ESLint

[error] 6-6: 'description' is assigned a value but never used. Allowed unused vars must match /^_/u.

(@typescript-eslint/no-unused-vars)

src/features/onboarding/ui/OnboardingSlide.tsx (1)

15-15: 이미지 품질 향상에 관한 고려사항

이미지 품질을 100으로 설정하여 온보딩 이미지의 시각적 품질을 향상시켰습니다. 이는 사용자에게 더 나은 첫인상을 제공할 수 있으나, 고품질 이미지는 로딩 시간과 성능에 영향을 줄 수 있습니다.

다음 사항을 고려해보세요:

  • 다양한 연결 환경에서 테스트하여 성능 영향을 확인하기
  • 필요한 경우 반응형 이미지 크기 최적화 전략 적용하기
-<Image src={imageUrl} alt="온보딩 이미지" fill className="object-contain" priority quality={100} />
+<Image 
+  src={imageUrl} 
+  alt="온보딩 이미지" 
+  fill 
+  className="object-contain" 
+  priority 
+  quality={90} 
+/>
src/features/onboarding/screen/index.tsx (1)

37-38: Autoplay 모듈이 포함되었지만 설정이 누락되었습니다.

Swiper에 Autoplay 모듈이 포함되어 있지만 실제 autoplay 설정이 누락되어 있습니다. autoplay 기능을 사용할 계획이 없다면 모듈을 제거하고, 사용할 계획이라면 적절한 설정을 추가해야 합니다.

<Swiper
  className="mx-auto h-dvh w-full max-w-[600px]"
  modules={[Pagination, Autoplay]}
+ autoplay={{
+   delay: 5000,
+   disableOnInteraction: false,
+ }}
  onSwiper={(swiper) => {
    swiperRef.current = swiper;
  }}
  onSlideChange={handleSlideChange}
  pagination={{
    clickable: true,
    el: '.custom-pagination',
    bulletClass: 'inline-block h-2 w-2 rounded-full mx-1 bg-white opacity-50',
    bulletActiveClass: '!opacity-100',
  }}
  navigation={false}
>
src/app/login/page.tsx (1)

3-5: 사용하지 않는 import 제거 필요.

useState를 import 했지만 제안된 코드 변경 후에는 사용되지 않습니다. 불필요한 import는 제거하는 것이 좋습니다.

'use client';

- import { useState } from 'react';

import OnboardingScreen from '@/features/onboarding/screen';
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88b3376 and 892ee2c.

⛔ Files ignored due to path filters (5)
  • public/images/login/onboarding/onboarding-1.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-2.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-3.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-4.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-bg.png is excluded by !**/*.png
📒 Files selected for processing (11)
  • src/app/login/page.tsx (2 hunks)
  • src/features/onboarding/components/FirstOnboarding/Background.tsx (1 hunks)
  • src/features/onboarding/components/FirstOnboarding/DecoAura.tsx (1 hunks)
  • src/features/onboarding/components/FirstOnboarding/DecoCircle.tsx (1 hunks)
  • src/features/onboarding/components/FirstOnboarding/TagGroup.tsx (1 hunks)
  • src/features/onboarding/containers/FirstOnboardingContainer.tsx (1 hunks)
  • src/features/onboarding/screen/index.tsx (1 hunks)
  • src/features/onboarding/ui/OnboardingCarousel.tsx (2 hunks)
  • src/features/onboarding/ui/OnboardingSlide.tsx (1 hunks)
  • src/features/onboarding/ui/components/FirstOnboarding.tsx (1 hunks)
  • src/features/onboarding/ui/components/getOnboardings.tsx (1 hunks)
🧰 Additional context used
🧬 Code Definitions (6)
src/features/onboarding/ui/components/getOnboardings.tsx (1)
src/features/onboarding/ui/components/FirstOnboarding.tsx (1) (1)
  • FirstOnboarding (5-9)
src/features/onboarding/ui/components/FirstOnboarding.tsx (1)
src/features/onboarding/config/slides.tsx (1) (1)
  • slides (1-17)
src/features/onboarding/containers/FirstOnboardingContainer.tsx (3)
src/features/onboarding/components/FirstOnboarding/Background.tsx (1) (1)
  • Background (5-30)
src/features/onboarding/components/FirstOnboarding/DecoCircle.tsx (1) (1)
  • DecoCircle (5-78)
src/features/onboarding/components/FirstOnboarding/DecoAura.tsx (1) (1)
  • DecoAura (5-96)
src/app/login/page.tsx (1)
src/features/onboarding/screen/index.tsx (1) (1)
  • OnboardingScreen (11-57)
src/features/onboarding/screen/index.tsx (2)
src/features/onboarding/config/slides.tsx (1) (1)
  • slides (1-17)
src/features/onboarding/containers/FirstOnboardingContainer.tsx (1) (1)
  • FirstOnboardingContainer (5-15)
src/features/onboarding/ui/OnboardingCarousel.tsx (1)
src/features/onboarding/ui/components/getOnboardings.tsx (1) (1)
  • getOnboardings (3-16)
🪛 ESLint
src/features/onboarding/components/FirstOnboarding/TagGroup.tsx

[error] 1-1: 'props' is defined but never used. Allowed unused args must match /^_/u.

(@typescript-eslint/no-unused-vars)

src/features/onboarding/ui/components/FirstOnboarding.tsx

[error] 6-6: 'description' is assigned a value but never used. Allowed unused vars must match /^_/u.

(@typescript-eslint/no-unused-vars)

src/features/onboarding/screen/index.tsx

[error] 20-20: 'handleNext' is assigned a value but never used. Allowed unused vars must match /^_/u.

(@typescript-eslint/no-unused-vars)

🔇 Additional comments (5)
src/features/onboarding/containers/FirstOnboardingContainer.tsx (1)

5-15: 적절하게 구현된 컨테이너 컴포넌트

FirstOnboardingContainer 컴포넌트는 중앙 정렬 레이아웃과 배경 데코레이션을 포함하여 잘 구현되었습니다.

src/features/onboarding/components/FirstOnboarding/Background.tsx (1)

1-30: 컴포넌트 구조가 잘 설계되었습니다

Background 컴포넌트의 구현이 잘 되어 있습니다. 특히 props 처리 방식과 클래스 관리가 깔끔합니다.

하지만 SVG 요소에 대한 접근성 개선을 고려해볼 수 있습니다:

-<svg width="479" height="538" viewBox="0 0 479 538" fill="none" xmlns="http://www.w3.org/2000/svg">
+<svg 
+  width="479" 
+  height="538" 
+  viewBox="0 0 479 538" 
+  fill="none" 
+  xmlns="http://www.w3.org/2000/svg"
+  aria-hidden="true"
+  role="presentation"
+>
src/features/onboarding/components/FirstOnboarding/DecoCircle.tsx (1)

1-78: 시각적 효과와 코드 구조가 좋습니다

DecoCircle 컴포넌트의 구현이 시각적으로 효과적이고 코드 구조도 잘 정리되어 있습니다.

다만, 몇 가지 개선점을 제안합니다:

  1. SVG의 접근성을 위한 속성 추가
-<svg width="220" height="221" viewBox="0 0 220 221" fill="none" xmlns="http://www.w3.org/2000/svg">
+<svg
+  width="220"
+  height="221"
+  viewBox="0 0 220 221"
+  fill="none"
+  xmlns="http://www.w3.org/2000/svg"
+  aria-hidden="true"
+  role="presentation"
+>
  1. 필터 ID가 다른 컴포넌트와 충돌할 가능성이 있으므로 더 고유한 ID 사용 고려
-<filter id="filter0_i_6472_1001" x="0" y="0.820312" width="219.998" height="219.998" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
+<filter id="decocircle_filter0_i_6472_1001" x="0" y="0.820312" width="219.998" height="219.998" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
  1. 성능 최적화를 위해 SVG를 별도 파일로 분리하고 Image 컴포넌트로 불러오는 방법도 고려해볼 수 있습니다.
src/features/onboarding/components/FirstOnboarding/DecoAura.tsx (1)

1-96: 잘 구현된 시각적 효과 컴포넌트

DecoAura 컴포넌트는 SVG를 활용한 시각적 효과를 잘 구현하였고, props 처리 방식과 코드 구조가 깔끔합니다.

다음과 같은 개선점을 고려해볼 수 있습니다:

  1. SVG의 접근성 향상을 위한 속성 추가
<svg
  className={cn(className)}
  width="529"
  height="529"
  viewBox="0 0 529 529"
  fill="none"
  xmlns="http://www.w3.org/2000/svg"
+  aria-hidden="true"
+  role="presentation"
  {...restProps}
>
  1. 필터 ID가 다른 컴포넌트와 충돌할 수 있으므로 더 고유한 ID 사용 고려
-<filter id="filter0_di_6472_998" x="0.867884" y="0.867884" width="527.901" height="527.901" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
+<filter id="decoaura_filter0_di_6472_998" x="0.867884" y="0.867884" width="527.901" height="527.901" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
  1. 컴포넌트의 메모이제이션을 통한 성능 최적화 고려
-export const DecoAura = (props: SVGProps<SVGSVGElement>) => {
+import { memo } from 'react';
+
+export const DecoAura = memo((props: SVGProps<SVGSVGElement>) => {
  const { className, ...restProps } = props;

  return (
    // 컴포넌트 내용
  );
-};
+});
+
+DecoAura.displayName = 'DecoAura';
src/features/onboarding/ui/OnboardingCarousel.tsx (1)

54-54: className 변경의 영향을 확인해주세요.

클래스명이 "h-full w-full"에서 "max-content w-full"로 변경되었습니다. max-content 값은 내용에 따라 컨테이너 크기가 결정되므로 Swiper의 높이가 내용에 따라 달라질 수 있습니다. 이러한 변경이 의도적인지, 그리고 모든 환경에서 올바르게 표시되는지 확인이 필요합니다.

레이아웃이 모든 화면 크기와 기기에서 의도한 대로 표시되는지 확인해주세요.

Comment on lines 3 to 16
export const getOnboardings = () => [
{
id: 1,
render: () => <FirstOnboarding />,
},
{
id: 2,
render: () => null,
},
{
id: 3,
render: () => null,
},
];
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

타입 정의가 필요하며 일부 슬라이드가 구현되지 않았습니다.

getOnboardings 함수는 타입 정의가 없으며, 2번과 3번 슬라이드는 null을 반환하여 아직 구현되지 않았음을 나타냅니다.

다음과 같이 개선할 것을 제안합니다:

import { FirstOnboarding } from './FirstOnboarding';

+interface OnboardingItem {
+  id: number;
+  render: () => React.ReactNode;
+}

-export const getOnboardings = () => [
+export const getOnboardings = (): OnboardingItem[] => [
  {
    id: 1,
    render: () => <FirstOnboarding />,
  },
  {
    id: 2,
-    render: () => null,
+    render: () => null, // TODO: 두 번째 온보딩 화면 구현 필요
  },
  {
    id: 3,
-    render: () => null,
+    render: () => null, // TODO: 세 번째 온보딩 화면 구현 필요
  },
];

이렇게 함으로써 코드의 타입 안정성을 높이고, 앞으로 구현해야 할 부분을 명확히 할 수 있습니다.

📝 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
export const getOnboardings = () => [
{
id: 1,
render: () => <FirstOnboarding />,
},
{
id: 2,
render: () => null,
},
{
id: 3,
render: () => null,
},
];
import { FirstOnboarding } from './FirstOnboarding';
interface OnboardingItem {
id: number;
render: () => React.ReactNode;
}
export const getOnboardings = (): OnboardingItem[] => [
{
id: 1,
render: () => <FirstOnboarding />,
},
{
id: 2,
render: () => null, // TODO: 두 번째 온보딩 화면 구현 필요
},
{
id: 3,
render: () => null, // TODO: 세 번째 온보딩 화면 구현 필요
},
];

Comment on lines 56 to 58
{getOnboardings().map(({ id, render }) => (
<SwiperSlide key={id}>{render()}</SwiperSlide>
))}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

getOnboardings() 함수가 불완전한 컴포넌트를 반환합니다.

getOnboardings() 함수는 두 번째와 세 번째 슬라이드에 대해 null을 반환하고 있습니다. 이로 인해 사용자는 빈 슬라이드를 보게 됩니다. 모든 슬라이드에 적절한 컴포넌트를 구현해야 합니다.


🏁 Script executed:

#!/bin/bash
# getOnboardings 함수의 구현을 확인합니다
cat src/features/onboarding/ui/components/getOnboardings.tsx

Length of output: 304


코드 수정 필요: 누락된 컴포넌트 문제 해결
getOnboardings() 함수에서 두 번째 및 세 번째 슬라이드에 대해 null을 반환하고 있어, 사용자에게 빈 슬라이드가 표시됩니다. 모든 슬라이드에 대해 유효한 컴포넌트를 반환하도록 수정해 주세요.

  • 파일: src/features/onboarding/ui/components/getOnboardings.tsx
    • id 2 및 id 3 항목에서 현재 render: () => null이 사용되고 있음
    • 모든 항목이 유의미한 UI 컴포넌트를 렌더링하도록 변경 필요

@semnil5202 semnil5202 force-pushed the refactor/change-onboarding branch from 892ee2c to 4e168d4 Compare March 23, 2025 06:19
@semnil5202 semnil5202 added the ♻️ refactor 코드 리팩토링 (기능 변경 없음) label Mar 23, 2025
@semnil5202 semnil5202 changed the title wip - onboarding Onboarding 페이지 UI 수정 및 이미지 교체 Mar 23, 2025
@semnil5202 semnil5202 marked this pull request as ready for review March 23, 2025 07:51
Copy link

@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

🧹 Nitpick comments (17)
src/features/onboarding/components/FirstOnboarding/TagGroup.tsx (1)

10-46: SVG 내용이 매우 상세하게 구현되어 있습니다.

태그 그룹의 시각적 표현이 잘 구현되어 있습니다만, SVG 내용이 상당히 큽니다.

SVG 크기가 크고 복잡한 경우, 별도의 컴포넌트로 분리하거나 외부 파일로 추출하는 것을 고려해보세요. 이렇게 하면 코드의 가독성이 향상되고 유지보수가 더 용이해집니다:

// TagGroupSVG.tsx
export const TagGroupSVG = (props: SVGProps<SVGSVGElement>) => (
  <svg width="249" height="329" viewBox="0 0 249 329" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
    {/* SVG 내용 */}
  </svg>
);

// TagGroup.tsx
import { TagGroupSVG } from './TagGroupSVG';

export const TagGroup = (props: HTMLAttributes<HTMLDivElement>) => {
  const { className, ...restProps } = props;

  return (
    <div className={cn(className)} {...restProps}>
      <TagGroupSVG />
    </div>
  );
};
src/features/onboarding/containers/SecondOnboardingContainer.tsx (1)

1-13: 온보딩 컨테이너의 구조가 명확하고 간결합니다.

컴포넌트의 구조가 잘 설계되어 있으며, Flexbox를 사용한 정렬 방식이 효과적입니다. 다만, 절대 위치(absolute positioning)와 고정 픽셀 값(pt-[256px])을 사용하여 반응형 디자인에 제한이 있을 수 있습니다.

다양한 화면 크기에 대응하기 위해 고정 픽셀 값 대신 상대적인 단위(vh, %)나 Tailwind의 반응형 클래스를 활용하는 것을 고려해 보세요:

-      <div className="flex h-max w-full items-center justify-center pt-[256px]">
+      <div className="flex h-max w-full items-center justify-center pt-16 sm:pt-24 md:pt-[256px]">
src/features/onboarding/components/ThirdOnboarding/DecoCards.tsx (2)

8-44: 복잡한 UI 구조에 대한 문서화가 필요합니다.

이 컴포넌트는 복잡한 SVG와 절대 위치를 사용한 중첩된 구조를 가지고 있어 나중에 유지보수하기 어려울 수 있습니다. 각 요소의 목적과 배치에 대한 주석이나 설명이 있으면 도움이 될 것입니다.

컴포넌트 상단에 간단한 JSDoc 주석을 추가하여 컴포넌트의 목적과 구조를 설명하는 것이 좋습니다:

+/**
+ * DecoCards 컴포넌트
+ * 
+ * 온보딩 세 번째 화면에 표시되는 장식용 카드들을 렌더링합니다.
+ * 디자이너와 개발자 카드를 특정 각도로 회전시켜 배치합니다.
+ * SVG 배경과 함께 시각적 계층을 형성합니다.
+ */
export const DecoCards = (props: HTMLAttributes<HTMLDivElement>) => {

또한 중첩된 div에 대한 설명을 추가하여 각 요소의 목적을 명확히 하는 것도 고려해 보세요.


30-41: 회전 변환이 적용된 카드 배치에 대한 반응형 고려가 필요합니다.

현재 카드들은 절대 위치와 고정 픽셀 값을 사용하여 배치되어 있어, 다양한 화면 크기에서 문제가 발생할 수 있습니다. 특히 작은 화면에서는 회전된 카드가 화면을 벗어나거나 다른 요소와 겹칠 수 있습니다.

반응형 디자인을 위해 미디어 쿼리나 Tailwind의 반응형 클래스를 활용하여 다양한 화면 크기에 맞게 조정하는 방안을 고려해 보세요:

-        <div className="absolute left-12 top-[-200px]">
+        <div className="absolute left-8 sm:left-10 md:left-12 top-[-150px] sm:top-[-175px] md:top-[-200px]">
           <div className="rotate-[8deg]">
             <DecoDesignerCard />
           </div>
         </div>
-        <div className="absolute top-[-120px]">
+        <div className="absolute top-[-90px] sm:top-[-100px] md:top-[-120px]">
           <div className="rotate-[-13deg]">
             <DecoDeveloperCard />
           </div>
         </div>
src/features/onboarding/containers/BackgroundContainer.tsx (1)

1-14: 백그라운드 전환 로직이 명확하게 구현되어 있습니다.

인덱스 기반으로 적절한 배경을 선택하는 로직이 간결하고 효과적입니다. 다만, 범위를 벗어난 인덱스 값에 대한 처리가 명시적이지 않아 혼란을 줄 수 있습니다.

기본 케이스에 대한 명확한 주석을 추가하여 코드의 의도를 분명히 하는 것이 좋습니다:

  if (activeIndex === 0) return <FirstBackground />;
  if (activeIndex === 1) return <SecondBackground />;

+ // 기본적으로 마지막 온보딩 화면(인덱스 2 이상)에는 ThirdBackground를 사용합니다
  return <ThirdBackground />;

또한 가능하다면 switch 문이나 객체 매핑을 사용하여 더 확장 가능한 구조로 리팩토링하는 것도 고려해볼 수 있습니다:

export const BackgroundContainer = ({ activeIndex }: Props) => {
  const backgrounds = {
  };
  
  return backgrounds[activeIndex] || <ThirdBackground />;
};
src/features/onboarding/components/SecondOnboarding/DecoCircle.tsx (2)

1-54: SVG를 활용한 장식 요소가 잘 구현되어 있습니다.

RadialGradient를 사용하여 시각적으로 매력적인 원형 장식을 구현한 것이 좋습니다. 다만, SVG의 width/height(951x551)와 viewBox(732x424)가 일치하지 않아 의도하지 않은 스케일링 이슈가 발생할 수 있습니다.

SVG의 width, height, viewBox 값을 일치시키거나 목적에 맞게 조정하는 것이 좋습니다:

-      <svg width="951" height="551" viewBox="0 0 732 424" fill="none" xmlns="http://www.w3.org/2000/svg">
+      <svg width="732" height="424" viewBox="0 0 732 424" fill="none" xmlns="http://www.w3.org/2000/svg">

또는 의도적으로 다른 비율을 사용하는 경우 preserveAspectRatio 속성을 추가하여 스케일링 방식을 명확히 지정하는 것이 좋습니다:

-      <svg width="951" height="551" viewBox="0 0 732 424" fill="none" xmlns="http://www.w3.org/2000/svg">
+      <svg width="951" height="551" viewBox="0 0 732 424" preserveAspectRatio="xMidYMid meet" fill="none" xmlns="http://www.w3.org/2000/svg">

만약 이 SVG가 순수하게 장식용이라면 접근성을 위해 aria-hidden 속성 추가도 고려해보세요:

-      <svg width="951" height="551" viewBox="0 0 732 424" fill="none" xmlns="http://www.w3.org/2000/svg">
+      <svg width="951" height="551" viewBox="0 0 732 424" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">

9-9: cn 유틸리티 사용 시 고려사항

className 속성에 cn 유틸리티를 사용하고 있지만, 추가 클래스 이름을 제공하지 않고 있습니다. 이는 불필요한 호출로 볼 수 있습니다.

아래와 같이 수정하여 더 명확하게 사용하는 것이 좋습니다:

-    <div className={cn(className)} {...restProps}>
+    <div className={cn('relative', className)} {...restProps}>

또는 단순히:

-    <div className={cn(className)} {...restProps}>
+    <div className={className} {...restProps}>
src/features/onboarding/containers/ThirdOnboardingContainer.tsx (1)

6-11: 레이아웃 구조에 대한 피드백

이 컴포넌트는 잘 구조화되어 있으며 레이아웃에 집중하고 있습니다. 그러나 몇 가지 고려할 점이 있습니다:

  1. absolute 포지셔닝으로 배치된 요소들이 있는데, 상위 컨테이너에 명시적인 position: relative가 없습니다. 현재 구조에서는 작동할 수 있지만, 컴포넌트가 다른 컨텍스트에서 재사용될 경우 문제가 발생할 수 있습니다.

  2. 고정된 pt-[256px] 패딩 값을 사용하고 있습니다. 다양한 화면 크기에서 더 유연하게 대응할 수 있도록 반응형 값을 고려해 보는 것이 좋습니다.

-<div className="flex h-max w-full items-center justify-center pt-[256px]">
+<div className="relative flex h-max w-full items-center justify-center pt-[256px] md:pt-[15vh]">
src/features/onboarding/components/ThirdOnboarding/ThirdBackground.tsx (4)

9-10: z-index 값 관리와 반응형 디자인 개선 필요

배경 컴포넌트에 하드코딩된 z-index 값(z-[-1])을 사용하는 것보다 z-index를 관리하는 상수나 변수를 사용하는 것이 더 유지보수에 용이합니다. 또한 반응형 디자인 측면에서 overlay의 고정 너비(w-[600px])는 작은 화면에서 문제가 될 수 있습니다.

반응형 디자인을 위해 다음과 같이 수정하는 것을 고려해보세요:

- <div className={cn(className, 'relative z-[-1] h-full w-full')} {...restProps}>
+ <div className={cn(className, 'relative z-background h-full w-full')} {...restProps}>
- <div className="bg-[rgba(255,255,255, 0.2)] absolute top-0 h-dvh w-[600px] backdrop-blur-[70px]" />
+ <div className="bg-[rgba(255,255,255, 0.2)] absolute top-0 h-dvh w-full max-w-[600px] backdrop-blur-[70px]" />

z-index 값은 Tailwind 설정에 정의된 z-index 유틸리티 클래스를 사용하는 것이 좋습니다.


11-27: SVG 요소의 반응형 처리 개선 필요

첫 번째 SVG 요소가 고정 크기로 정의되어 있어 다양한 화면 크기에 적절하게 대응하지 못할 수 있습니다. SVG에 viewBox 속성은 있지만, 반응형 크기 조정을 위한 추가 속성이 필요합니다.

SVG를 반응형으로 만들기 위해 다음과 같이 수정하는 것을 고려해보세요:

- <svg width="450" height="538" viewBox="0 0 450 538" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <svg className="w-full max-w-[450px] h-auto" viewBox="0 0 450 538" fill="none" xmlns="http://www.w3.org/2000/svg">

이렇게 하면 SVG가 부모 컨테이너의 너비에 맞게 조정되면서 원래의 비율을 유지할 수 있습니다.


29-70: 두 번째 SVG 요소도 반응형 처리 필요

두 번째 SVG 요소 역시 고정 크기로 정의되어 있어 다양한 화면 크기에 적절하게 대응하지 못할 수 있습니다.

두 번째 SVG도 반응형으로 만들기 위해 다음과 같이 수정하는 것을 고려해보세요:

- <svg width="606" height="366" viewBox="0 0 606 366" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <svg className="w-full h-auto" viewBox="0 0 606 366" preserveAspectRatio="xMidYMid slice" fill="none" xmlns="http://www.w3.org/2000/svg">

preserveAspectRatio="xMidYMid slice" 속성을 추가하면 SVG가 컨테이너를 채우면서 비율을 유지할 수 있습니다.


1-73: 전반적인 디자인 시스템 통합 고려

컴포넌트가 잘 구현되었지만, 일관된 디자인 시스템을 위해 하드코딩된 색상 값 대신 Tailwind의 테마 색상 변수나 CSS 변수를 사용하는 것이 좋습니다. 또한 SVG 요소들을 별도의 컴포넌트로 분리하여 재사용성을 높이는 것도 고려해볼 수 있습니다.

하드코딩된 색상 값 대신 테마 시스템을 활용하는 것을 고려해보세요. 예를 들어 Tailwind 설정에 색상 변수를 추가하고 이를 활용할 수 있습니다. 또한 큰 SVG 요소들은 별도의 컴포넌트로 분리하여 코드의 가독성과 유지보수성을 높일 수 있습니다.

src/features/onboarding/components/ThirdOnboarding/DeveloperCard/DecoDeveloperCard.tsx (2)

11-43: 접근성을 개선하기 위해 SVG에 설명 추가가 필요합니다.

이 SVG 요소는 시각적 디자인 요소이지만 접근성을 위해 aria-label 또는 title 속성을 추가하는 것이 좋습니다. 스크린 리더 사용자에게 이 요소가 무엇인지 알려줄 수 있습니다.

-      <svg width="118" height="169" viewBox="0 0 118 169" fill="none" xmlns="http://www.w3.org/2000/svg">
+      <svg width="118" height="169" viewBox="0 0 118 169" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="개발자 카드 배경 이미지" role="img">

44-61: 두 번째 SVG 요소에도 접근성 속성 추가가 필요합니다.

이 SVG는 "Developer" 텍스트를 표시하는 것으로 보이는데, 접근성을 위해 적절한 aria 속성을 추가하세요.

      <svg
        className="absolute left-[18px] top-5"
        width="84"
        height="135"
        viewBox="0 0 84 135"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
+       aria-label="Developer 텍스트" 
+       role="img"
      >
src/features/onboarding/components/SecondOnboarding/DecoCard.tsx (3)

20-53: SVG 요소에 접근성 향상이 필요합니다.

이 SVG는 시각적 요소이지만, 접근성을 위해 의미 있는 설명을 추가해야 합니다. 스크린 리더 사용자가 이 요소의 목적을 이해할 수 있도록 도움이 됩니다.

      <svg
        width="234"
        height="319"
        viewBox="0 0 234 319"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
        xmlnsXlink="http://www.w3.org/1999/xlink"
+       aria-label="온보딩 장식 카드" 
+       role="img"
      >

49-55: 대용량 base64 인코딩 이미지 사용에 대한 최적화 고려

대용량 base64 인코딩 이미지를 사용하면 초기 로딩 시간과 메모리 사용량에 영향을 줄 수 있습니다. 별도의 이미지 파일로 분리하고 src 속성으로 참조하는 것이 더 효율적일 수 있습니다.

이 인코딩된 이미지를 별도의 이미지 파일로 저장하고 URL로 참조하는 방식을 고려해보세요. 이렇게 하면 코드 사이즈가 줄어들고 브라우저 캐싱의 이점을 활용할 수 있습니다.


1-60: 성능 최적화를 위한 memo 사용 고려

이 컴포넌트는 복잡한 SVG를 렌더링하는데, 불필요한 리렌더링을 방지하기 위해 React.memo를 사용하는 것이 좋습니다.

import { HTMLAttributes } from 'react';
+ import { memo } from 'react';

import { cn } from '@/shared/lib/utils';

-export const DecoCard = (props: HTMLAttributes<HTMLDivElement>) => {
+export const DecoCard = memo((props: HTMLAttributes<HTMLDivElement>) => {
  const { className, ...restProps } = props;

  return (
    <div className={cn(className)} {...restProps}>
      {/* SVG content */}
    </div>
  );
-};
+});
+
+DecoCard.displayName = 'DecoCard';

이렇게 하면 상위 컴포넌트가 리렌더링될 때 props가 변경되지 않았다면 이 복잡한 SVG 컴포넌트의 불필요한 리렌더링을 방지할 수 있습니다.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 892ee2c and e6d4c46.

⛔ Files ignored due to path filters (5)
  • public/images/login/onboarding/onboarding-1.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-2.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-3.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-4.png is excluded by !**/*.png
  • public/images/login/onboarding/onboarding-bg.png is excluded by !**/*.png
📒 Files selected for processing (28)
  • src/app/globals.css (2 hunks)
  • src/app/login/page.tsx (1 hunks)
  • src/app/onboarding/page.tsx (1 hunks)
  • src/features/home/containers/CardContainer.tsx (1 hunks)
  • src/features/onboarding/components/FirstOnboarding/DecoAura.tsx (1 hunks)
  • src/features/onboarding/components/FirstOnboarding/DecoCircle.tsx (1 hunks)
  • src/features/onboarding/components/FirstOnboarding/FirstBackground.tsx (1 hunks)
  • src/features/onboarding/components/FirstOnboarding/TagGroup.tsx (1 hunks)
  • src/features/onboarding/components/SecondOnboarding/DecoCard.tsx (1 hunks)
  • src/features/onboarding/components/SecondOnboarding/DecoCircle.tsx (1 hunks)
  • src/features/onboarding/components/SecondOnboarding/SecondBackground.tsx (1 hunks)
  • src/features/onboarding/components/ThirdOnboarding/DecoCards.tsx (1 hunks)
  • src/features/onboarding/components/ThirdOnboarding/DecoCircle.tsx (1 hunks)
  • src/features/onboarding/components/ThirdOnboarding/DeveloperCard/DecoDesignerCard.tsx (1 hunks)
  • src/features/onboarding/components/ThirdOnboarding/DeveloperCard/DecoDeveloperCard.tsx (1 hunks)
  • src/features/onboarding/components/ThirdOnboarding/ThirdBackground.tsx (1 hunks)
  • src/features/onboarding/config/slides.ts (0 hunks)
  • src/features/onboarding/config/slides.tsx (1 hunks)
  • src/features/onboarding/containers/BackgroundContainer.tsx (1 hunks)
  • src/features/onboarding/containers/FirstOnboardingContainer.tsx (1 hunks)
  • src/features/onboarding/containers/SecondOnboardingContainer.tsx (1 hunks)
  • src/features/onboarding/containers/ThirdOnboardingContainer.tsx (1 hunks)
  • src/features/onboarding/screen/index.tsx (1 hunks)
  • src/features/onboarding/ui/OnboardingCarousel.tsx (0 hunks)
  • src/features/onboarding/ui/OnboardingFeature.tsx (0 hunks)
  • src/features/onboarding/ui/OnboardingHeader.tsx (0 hunks)
  • src/features/onboarding/ui/OnboardingSlide.tsx (0 hunks)
  • tailwind.config.ts (1 hunks)
💤 Files with no reviewable changes (5)
  • src/features/onboarding/config/slides.ts
  • src/features/onboarding/ui/OnboardingHeader.tsx
  • src/features/onboarding/ui/OnboardingCarousel.tsx
  • src/features/onboarding/ui/OnboardingFeature.tsx
  • src/features/onboarding/ui/OnboardingSlide.tsx
✅ Files skipped from review due to trivial changes (3)
  • src/app/onboarding/page.tsx
  • src/features/home/containers/CardContainer.tsx
  • src/app/globals.css
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/features/onboarding/components/FirstOnboarding/DecoCircle.tsx
  • src/features/onboarding/screen/index.tsx
  • src/features/onboarding/components/FirstOnboarding/DecoAura.tsx
🧰 Additional context used
🧬 Code Definitions (7)
src/features/onboarding/containers/SecondOnboardingContainer.tsx (2)
src/features/onboarding/components/SecondOnboarding/DecoCircle.tsx (1)
  • DecoCircle (5-54)
src/features/onboarding/components/SecondOnboarding/DecoCard.tsx (1)
  • DecoCard (5-59)
src/features/onboarding/config/slides.tsx (3)
src/features/onboarding/containers/FirstOnboardingContainer.tsx (1)
  • FirstOnboardingContainer (5-15)
src/features/onboarding/containers/SecondOnboardingContainer.tsx (1)
  • SecondOnboardingContainer (4-13)
src/features/onboarding/containers/ThirdOnboardingContainer.tsx (1)
  • ThirdOnboardingContainer (4-13)
src/features/onboarding/containers/BackgroundContainer.tsx (3)
src/features/onboarding/components/FirstOnboarding/FirstBackground.tsx (1)
  • FirstBackground (5-49)
src/features/onboarding/components/SecondOnboarding/SecondBackground.tsx (1)
  • SecondBackground (5-30)
src/features/onboarding/components/ThirdOnboarding/ThirdBackground.tsx (1)
  • ThirdBackground (5-73)
src/features/onboarding/containers/FirstOnboardingContainer.tsx (3)
src/features/onboarding/components/FirstOnboarding/DecoCircle.tsx (1)
  • DecoCircle (5-78)
src/features/onboarding/components/FirstOnboarding/DecoAura.tsx (1)
  • DecoAura (5-96)
src/features/onboarding/components/FirstOnboarding/TagGroup.tsx (1)
  • TagGroup (5-49)
src/features/onboarding/components/ThirdOnboarding/DecoCards.tsx (2)
src/features/onboarding/components/ThirdOnboarding/DeveloperCard/DecoDesignerCard.tsx (1)
  • DecoDesignerCard (5-66)
src/features/onboarding/components/ThirdOnboarding/DeveloperCard/DecoDeveloperCard.tsx (1)
  • DecoDeveloperCard (5-63)
src/app/login/page.tsx (1)
src/features/onboarding/screen/index.tsx (1)
  • OnboardingScreen (18-83)
src/features/onboarding/containers/ThirdOnboardingContainer.tsx (2)
src/features/onboarding/components/ThirdOnboarding/DecoCircle.tsx (1)
  • DecoCircle (5-73)
src/features/onboarding/components/ThirdOnboarding/DecoCards.tsx (1)
  • DecoCards (8-44)
🔇 Additional comments (12)
src/app/login/page.tsx (1)

1-5: 코드 구조가 크게 개선되었습니다.

로그인 페이지가 크게 단순화되어 온보딩 스크린만 직접 렌더링하도록 변경되었습니다. 이전의 조건부 렌더링 로직과 상태 관리를 제거함으로써 코드가 더 깔끔해졌습니다. 이는 PR의 목표인 "로그인과 온보딩 기능을 위한 라우팅 분리" 요구사항을 잘 충족시키고 있습니다.

OnboardingScreen 컴포넌트가 온보딩 과정을 마치면 '/login' 경로로 라우팅하는 로직을 내부적으로 처리하므로, 관심사의 분리가 더 명확해졌습니다.

src/features/onboarding/config/slides.tsx (1)

5-21: 슬라이드 구성이 깔끔하게 구현되었습니다.

각 슬라이드에 고유 ID와 설명 텍스트, 그리고 해당 컴포넌트가 잘 매핑되어 있습니다. 온보딩 화면 구성에 필요한 데이터가 명확하게 정의되어 있습니다.

다만, 향후 확장성을 위해 타입스크립트 인터페이스를 사용하여 슬라이드 객체의 구조를 정의하는 것을 고려해 보세요:

interface Slide {
  id: number;
  descriptions: string[];
  component: React.ComponentType;
}

export const slides: Slide[] = [
  // 현재 구현과 동일
];
src/features/onboarding/containers/FirstOnboardingContainer.tsx (1)

5-15: 컴포넌트 구조가 잘 구현되었습니다.

Flexbox를 활용한 레이아웃과 절대 위치를 사용한 데코레이션 요소 배치가 적절합니다.

가독성 향상을 위해 각 데코레이션 컴포넌트의 목적을 설명하는 주석을 추가하는 것이 도움이 될 수 있습니다:

    <div className="flex h-full w-full flex-col items-center justify-start">
      <div className="flex h-max w-full items-center justify-center pt-[280px]">
+       {/* 배경 원형 장식 요소 */}
        <DecoCircle className="absolute" />
+       {/* 배경 아우라 효과 */}
        <DecoAura className="absolute" />
+       {/* 태그 그룹 요소 - 약간 위로 이동 */}
        <TagGroup className="absolute translate-y-[-5%]" />
      </div>
    </div>
src/features/onboarding/components/FirstOnboarding/TagGroup.tsx (1)

5-9: 컴포넌트 프롭스 처리가 잘 구현되었습니다.

HTMLAttributes 타입을 활용하여 div 요소의 표준 속성들을 모두 지원하도록 구현된 점이 좋습니다. className과 나머지 속성을 적절히 분리하여 처리하고 있습니다.

tailwind.config.ts (1)

141-149: 애니메이션 설정이 잘 구성되었습니다.

fade-in 애니메이션과 fadeIn 키프레임이 적절하게 정의되어 있습니다. 온보딩 화면 전환에 자연스러운 효과를 줄 수 있을 것입니다.

향후 더 다양한 애니메이션 효과가 필요할 경우를 대비하여 다음과 같이 추가 애니메이션 변형을 고려해 보세요:

  animation: {
    'fade-in': 'fadeIn 1s ease-in-out',
+   'fade-out': 'fadeOut 1s ease-in-out',
+   'slide-in': 'slideIn 0.5s ease-out',
  },
  keyframes: {
    fadeIn: {
      '0%': { opacity: '0' },
      '100%': { opacity: '1' },
    },
+   fadeOut: {
+     '0%': { opacity: '1' },
+     '100%': { opacity: '0' },
+   },
+   slideIn: {
+     '0%': { transform: 'translateY(10px)', opacity: '0' },
+     '100%': { transform: 'translateY(0)', opacity: '1' },
+   },
  },
src/features/onboarding/components/ThirdOnboarding/DecoCards.tsx (1)

1-7: 컴포넌트 임포트 구조가 잘 정리되어 있습니다.

필요한 모듈과 컴포넌트를 적절하게 임포트하여 코드의 가독성이 좋습니다.

src/features/onboarding/components/ThirdOnboarding/DeveloperCard/DecoDesignerCard.tsx (2)

11-43: 첫 번째 SVG 구현이 적절하게 되어 있습니다.

클리핑 패스와 여러 개의 경로를 포함한 복잡한 SVG가 잘 구현되어 있습니다. 그라디언트와 불투명도 설정이 디자인 의도에 맞게 적용되어 있습니다.


45-63: 두 번째 SVG 구현이 적절하게 되어 있습니다.

절대 위치 지정과 적절한 viewBox 설정이 되어 있습니다. 'Designer' 텍스트를 포함한 SVG 경로가 잘 구현되어 있습니다.

src/features/onboarding/components/ThirdOnboarding/DecoCircle.tsx (1)

5-72: DecoCircle 컴포넌트가 적절하게 구현되어 있습니다.

SVG를 사용한 원형 장식 요소가 잘 구현되어 있습니다. 다양한 불투명도와 방사형 그라디언트를 통해 시각적 깊이감을 주는 효과가 좋습니다. props 전달 방식과 클래스명 처리도 적절합니다.

src/features/onboarding/components/FirstOnboarding/FirstBackground.tsx (1)

9-47: FirstBackground 컴포넌트가 적절하게 구현되어 있습니다.

백드롭 블러 효과와 SVG 요소들이 잘 어우러져 시각적으로 매력적인 배경을 구성하고 있습니다. z-index 사용과 절대 위치 지정이 적절합니다. 컬러 그라디언트 사용도 UI 디자인에 맞게 구현되어 있습니다.

src/features/onboarding/components/SecondOnboarding/SecondBackground.tsx (1)

5-30: SecondBackground 컴포넌트가 적절하게 구현되어 있습니다.

첫 번째 배경과 유사한 구조로 일관성 있게 구현되어 있습니다. SVG 사용과 백드롭 블러 효과가 온보딩 UI에 적합한 시각적 효과를 제공합니다. props 전달 방식과 클래스명 처리도 적절합니다.

src/features/onboarding/components/ThirdOnboarding/ThirdBackground.tsx (1)

1-7: 컴포넌트 구조가 깔끔하게 정의되었습니다.

컴포넌트의 구조가 명확하고 타입스크립트 타입이 적절하게 사용되었습니다. HTMLAttributes를 활용한 props 타입 정의와 cn 유틸리티 함수 사용은 좋은 패턴입니다.

const { className, ...restProps } = props;

return (
<div className={(cn(className), 'relative w-max overflow-hidden rounded-md')} {...restProps}>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

클래스명 할당 문법에 오류가 있습니다.

cn 함수 호출 시 괄호 사용에 오류가 있습니다. 현재 코드는 괄호와 쉼표를 잘못 사용하고 있어 className이 제대로 적용되지 않을 수 있습니다.

다음과 같이 수정해주세요:

-    <div className={(cn(className), 'relative w-max overflow-hidden rounded-md')} {...restProps}>
+    <div className={cn(className, 'relative w-max overflow-hidden rounded-md')} {...restProps}>
📝 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={(cn(className), 'relative w-max overflow-hidden rounded-md')} {...restProps}>
<div className={cn(className, 'relative w-max overflow-hidden rounded-md')} {...restProps}>

const { className, ...restProps } = props;

return (
<div className={(cn(className), 'relative w-max overflow-hidden rounded-md')} {...restProps}>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

className 속성이 잘못 사용되었습니다.

className을 설정하는 부분에 괄호와 쉼표 연산자를 잘못 사용하고 있습니다. 이로 인해 실제로는 첫 번째 값(cn(className))이 무시되고 두 번째 문자열만 적용됩니다.

다음과 같이 수정하세요:

-    <div className={(cn(className), 'relative w-max overflow-hidden rounded-md')} {...restProps}>
+    <div className={cn(className, 'relative w-max overflow-hidden rounded-md')} {...restProps}>
📝 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={(cn(className), 'relative w-max overflow-hidden rounded-md')} {...restProps}>
<div className={cn(className, 'relative w-max overflow-hidden rounded-md')} {...restProps}>

@semnil5202 semnil5202 changed the title Onboarding 페이지 UI 수정 및 이미지 교체 [Feat] Onboarding 페이지 UI 수정 및 이미지 교체 Mar 23, 2025
@semnil5202 semnil5202 added the auto approve PR에 대한 Auto Approve입니다. label Mar 23, 2025
@semnil5202 semnil5202 added auto approve PR에 대한 Auto Approve입니다. and removed ♻️ refactor 코드 리팩토링 (기능 변경 없음) auto approve PR에 대한 Auto Approve입니다. labels Mar 23, 2025
Copy link
Collaborator

@evenway2025 evenway2025 left a comment

Choose a reason for hiding this comment

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

제 기준에서 이 코드는 이븐하게 잘 작성된 것 같습니다. 고생하셨습니다. Approve 드리겠습니다. 🎊

@semnil5202 semnil5202 added the ♻️ refactor 코드 리팩토링 (기능 변경 없음) label Mar 23, 2025
@semnil5202 semnil5202 merged commit d8bf9e2 into develop Mar 23, 2025
4 checks passed
@semnil5202 semnil5202 deleted the refactor/change-onboarding branch March 23, 2025 09:06
semnil5202 added a commit that referenced this pull request Mar 23, 2025
* 🐛 Fix: 배포 env 백엔드 API 수정 (#91)

* [Feat] 공통 컴포넌트 Appbar, Toast 편집 (#93)

* ✨ Feat: Appbar 케이스 추가(받은 명함 페이지, 설정 페이지)

* ✨ Feat: Toast 새 케이스 추가(success)

* 🐛 Fix: onRightClickSecond potential issue 해결

* feat: 설정 list view를 구현합니다. (#95)

* ♻️ Refactor: 사용하지 않는 타입 제거

* ♻️ Refactor: 리스트 item 설정 페이지 variant 확장

* ✨ Feat: 설정 리스트 view 구현 (#97)

* [feat] 공통 컴포넌트 모달 구현 (#98)

* ✨ Feat: 간격 lx 28px 확장

* 📦️ Chore: dialog 패키지 설치

* 💄 Style: radius 20px 추가

* 💄 Style: border, spacing 28px, 20px 추가

* ✨ Feat: 모달 컴포넌트 구현, 커스텀 모달 구현

* ✨ Feat: 공통 컴포넌트 버튼 - dialog 버튼 옵션 추가

* ✨ Feat: 세팅 다이얼로그 추가

* ✨ Feat: 공통 모달, 프로그래밍식 닫기 지원

example에 지원 설명

* [feat]: 회원 탈퇴 페이지 UI 구현, react hook form 구현 (#103)

* feat: 회원 탈퇴 스키마 구현

* ✨ Feat: 공통 체크박스 버튼, 체크박스 버튼 그룹 구현

* ✨ Feat: 공통 fixedBottom 버튼 구현

* ✨ Feat: 회원탈퇴 react hook form 적용, ui 구현 완료

* ✨ Feat: 회원탈퇴 router 추가

* ♻️ Refactor: 카드세팅뷰 ; 추가

* ✨ Feat: 회원탈퇴 직접입력 필드 isDirty로 validation

필드가 동작을 하고 나서 validation 추가

* ♻️ Refactor: 가독성 개선, config 분리

* ✨ Feat: 알람 설정 UI 구현 (#105)

* [feat] 받은 명함 상세 페이지 디자인 구현 (#100)

* ♻️ refactor : next.config 이미지 경로 추가

* ✨feat : 수정 , 삭제 svg 추가

* ♻️ refactor : 로그인 후 경로 로직 수정

* ♻️ refactor : 카드 상세 페이지 높이 수정

* ✨feat : 명함 상세 응답 데이터 임시 변경

* ✨feat : 바텀 시트 상태 관리 훅 생성

* ✨feat : 받은 명함 데이터 임시 생성

* ✨feat : 받은 명함 타임 임시 작성

* ♻️ refactor : 내 명함 상세 타입 파일명 수정

* ✨feat : 받은 명함 타입 임시 작성

* ✨feat : 명상 상세 헤더 컴포넌트 한줄 메모 기능 추가

* ♻️ refactor : 명함 상세 페이지 불필요한 import 제거

* ♻️ refactor : 명함 상세 프로젝트 컴포넌트 링크 태그 추가

* ✨feat : 바텀 시트 공통 컴포넌트 생성

* ♻️ refactor : toast 위치 수정

* ♻️ refactor : 변수 주석 추가

* ♻️ refactor : 불필요한 타입 제거 및 예외 처리 추가

* ♻️ refactor :  토스트 중복 호출 제거

* ✨feat : appbar onLeftClick 기능 추가

* ♻️ refactor : memoInput으로 네이밍 수정 , z-index 수정

* ♻️ refactor :  BottomMenuItem에 className 속성 추가

* [Feat] 명함 생성 - 메인화면 UI 구현 (#109)

* 📦️ Chore: install tailwind-scrollbar-hide

* ✨ Feat: 명함 생성 - 메인화면 UI 구현 (흥미로운 명함 카드 제외)

* 💄 Style: Appbar title text color 추가, Thumbnail에 imageurl 추가

* ♻️ Refactor: 명함 상세뷰 분리

* ✨ Feat: useReceivedCardQuery 구현 및 Card previewInfoType의 type 수정

* 🐛 Fix: fix pnpm error

* [Feat] Apple login 구현 (#110)

* refactor: apple login key 수정

* refactor: apple login 구현

* [Feat] Onboarding 페이지 UI 수정 및 이미지 교체 (#99)

* refactor: home swiper classname 지정

* refactor: onboarding image 첫 슬라이드 완성

* refactor: 슬라이드 및 디스크립션 구현

* refactor: second slide 구현

* feat: 세번째 슬라이드 생성

* refactor: 사용하지 않는 컴포넌트 제거 및 온보딩 페이지 라우팅 분리 대기

* refactor: 임시 슬라이드 index 수정

* refactor: 온보딩이랑 로그인 피쳐 분리

* style: 주석 추가

---------

Co-authored-by: 윤장원 <33803975+jangwonyoon@users.noreply.github.com>
Co-authored-by: 영주 <111039206+youngju6143@users.noreply.github.com>
Co-authored-by: JaeIn1 <97165077+JaeIn1@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto approve PR에 대한 Auto Approve입니다. ♻️ refactor 코드 리팩토링 (기능 변경 없음)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants