Skip to content

feat - 온보딩 화면 추가#18

Merged
mark77234 merged 9 commits into
devfrom
feat/10
Jan 12, 2026
Merged

feat - 온보딩 화면 추가#18
mark77234 merged 9 commits into
devfrom
feat/10

Conversation

@mark77234

Copy link
Copy Markdown
Collaborator

작업내용

  • 온보딩 화면 추가 작업
  • 키보드 대응 (키보드 바깥 터치 시 키보드 내림)
  • 설정 바텀시트 -> 사이드바로 개선
  • 설정화면 글자 크기, 폰트 통일
  • 설정화면 생년월일 수정 시 DatePicker 컴퐆넌트 사용
  • 출생시간 수정 추가하기

Copilot AI review requested due to automatic review settings January 12, 2026 14:06
@mark77234 mark77234 linked an issue Jan 12, 2026 that may be closed by this pull request
6 tasks
@mark77234 mark77234 merged commit d158bad into dev Jan 12, 2026
2 of 3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a comprehensive onboarding flow to introduce new users to the app's features. The onboarding consists of 5 interactive steps showcasing the app's key functionality, followed by login/signup options.

Changes:

  • Added a full-featured onboarding screen with 5 steps featuring animations and visual demonstrations
  • Updated LoginScreen to accept an initialMode prop for seamless transition from onboarding
  • Modified app flow control to show onboarding before login for first-time users

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 14 comments.

File Description
src/components/Onboarding.tsx Complete rewrite from simple guide to 5-step interactive onboarding with animations, phone mockups, and visual demonstrations
src/components/LoginScreen.tsx Added initialMode prop to allow onboarding to specify whether to show sign-in or sign-up screen
app/index.tsx Updated flow control to show onboarding before login, removed needsOnboarding state, added loginMode state management

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +246 to +249
const travel = Math.max(trackWidth - 80, 0);
const translateX = guideAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, travel],

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The variable name 'travel' is ambiguous. A more descriptive name like 'maxTranslateDistance' or 'dragDistance' would better convey its purpose as the maximum distance the animated pointer can travel.

Suggested change
const travel = Math.max(trackWidth - 80, 0);
const translateX = guideAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, travel],
const maxTranslateDistance = Math.max(trackWidth - 80, 0);
const translateX = guideAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, maxTranslateDistance],

Copilot uses AI. Check for mistakes.
Comment on lines +520 to +521
<Text className="text-xs font-bold text-gray-300">2024</Text>
<Text className="text-xs font-bold text-gray-300">MAY</Text>

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The hardcoded date values "2024" and "MAY" make the mockup less realistic and could confuse users if they see an onboarding screen with outdated dates. Consider using dynamic dates or a more generic representation that doesn't show specific months/years.

Suggested change
<Text className="text-xs font-bold text-gray-300">2024</Text>
<Text className="text-xs font-bold text-gray-300">MAY</Text>
<Text className="text-xs font-bold text-gray-300">
{new Date().getFullYear()}
</Text>
<Text className="text-xs font-bold text-gray-300">
{new Date().toLocaleString(undefined, { month: 'short' }).toUpperCase()}
</Text>

Copilot uses AI. Check for mistakes.
Comment on lines +579 to +585
className="w-full rounded-2xl bg-[#191F28] py-4 active:opacity-90"
>
<Text className="text-center text-base font-bold text-white">로그인</Text>
</Pressable>
<Pressable
onPress={() => onComplete('signUp')}
className="w-full rounded-2xl border border-gray-100 bg-white py-4 active:opacity-90"

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The Pressable buttons lack accessibility labels. Adding accessibilityLabel props would improve the experience for users with screen readers (e.g., accessibilityLabel="로그인하기" and accessibilityLabel="회원가입하기").

Suggested change
className="w-full rounded-2xl bg-[#191F28] py-4 active:opacity-90"
>
<Text className="text-center text-base font-bold text-white">로그인</Text>
</Pressable>
<Pressable
onPress={() => onComplete('signUp')}
className="w-full rounded-2xl border border-gray-100 bg-white py-4 active:opacity-90"
className="w-full rounded-2xl bg-[#191F28] py-4 active:opacity-90"
accessibilityLabel="로그인하기"
>
<Text className="text-center text-base font-bold text-white">로그인</Text>
</Pressable>
<Pressable
onPress={() => onComplete('signUp')}
className="w-full rounded-2xl border border-gray-100 bg-white py-4 active:opacity-90"
accessibilityLabel="회원가입하기"

Copilot uses AI. Check for mistakes.
Comment on lines +117 to 126
<View className="absolute top-6 left-0 right-0 z-20 flex-row items-center justify-center gap-2">
{steps.map((step, index) => (
<View
key={step.key}
className={`h-1 rounded-full ${
index === activeIndex ? 'w-6 bg-[#191F28]' : 'w-1.5 bg-gray-200'
}`}
/>
))}
</View>

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The pagination indicator dots lack accessibility support. Consider adding an accessibilityLabel to the container view that describes the current step and total steps (e.g., "Step 1 of 5" for screen reader users).

Copilot uses AI. Check for mistakes.
<View className="flex-1 items-center justify-center px-10">
<StepText title={title} description={description} titleClassName="text-[28px] leading-[36px]" />
<View className="items-center justify-center">
<View className="absolute h-56 w-56" />

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

This empty View with absolute positioning and no content serves no purpose. If it was intended as a spacing element or shadow container, it should either be implemented properly or removed to avoid confusion.

Suggested change
<View className="absolute h-56 w-56" />

Copilot uses AI. Check for mistakes.
Comment on lines +299 to +303
const Step3Visual: React.FC<PhoneStepProps> = ({ title, description, phoneWidth, phoneHeight }) => {
const scrollAnim = useRef(new Animated.Value(0)).current;
const chevronAnim = useRef(new Animated.Value(0)).current;
const detailsHeight = 280;
const scrollDistance = Math.min(detailsHeight - 16, phoneHeight * 0.55);

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The magic numbers 280 (detailsHeight), 16, and 0.55 should be extracted as named constants (e.g., DETAILS_SECTION_HEIGHT, SCROLL_OFFSET, MAX_SCROLL_PERCENTAGE) to improve code readability and maintainability.

Suggested change
const Step3Visual: React.FC<PhoneStepProps> = ({ title, description, phoneWidth, phoneHeight }) => {
const scrollAnim = useRef(new Animated.Value(0)).current;
const chevronAnim = useRef(new Animated.Value(0)).current;
const detailsHeight = 280;
const scrollDistance = Math.min(detailsHeight - 16, phoneHeight * 0.55);
const DETAILS_SECTION_HEIGHT = 280;
const SCROLL_OFFSET = 16;
const MAX_SCROLL_PERCENTAGE = 0.55;
const Step3Visual: React.FC<PhoneStepProps> = ({ title, description, phoneWidth, phoneHeight }) => {
const scrollAnim = useRef(new Animated.Value(0)).current;
const chevronAnim = useRef(new Animated.Value(0)).current;
const detailsHeight = DETAILS_SECTION_HEIGHT;
const scrollDistance = Math.min(detailsHeight - SCROLL_OFFSET, phoneHeight * MAX_SCROLL_PERCENTAGE);

Copilot uses AI. Check for mistakes.
Comment on lines +178 to +205
}> = ({ day = 14, fullHeight = false, className = '' }) => (
<View className={`w-full ${fullHeight ? 'flex-1' : 'px-4 pt-4'} ${className}`}>
<View className="h-8 w-full rounded-t-sm border-b-2 border-dashed border-gray-100 bg-white items-center justify-center">
<View className="absolute left-4 h-2 w-2 rounded-full bg-gray-200" />
<View className="absolute right-4 h-2 w-2 rounded-full bg-gray-200" />
</View>
<View className="w-full flex-1 rounded-b-sm bg-white p-4">
<View className="w-full flex-row justify-between">
<Text className="text-[12px] font-bold text-gray-300">2024</Text>
<Text className="text-[12px] font-bold text-gray-300">MAY</Text>
</View>
<View className="mt-12 w-full items-center">
<Text
className={`text-[120px] font-bold text-center ${
day % 7 === 0 ? 'text-red-500' : 'text-[#191F28]'
}`}
>
{day}
</Text>
</View>
<View className="mt-12 items-center gap-4">
<View className="h-2 w-32 rounded-full bg-gray-100 " />
<View className="h-2 w-20 rounded-full bg-gray-100" />
</View>
<View className="mt-48 h-px w-full bg-gray-200" />
</View>
</View>
);

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The hardcoded date values "2024" and "MAY" make the mockup less realistic and could confuse users if they see an onboarding screen with outdated dates. Consider using dynamic dates or a more generic representation that doesn't show specific months/years.

Suggested change
}> = ({ day = 14, fullHeight = false, className = '' }) => (
<View className={`w-full ${fullHeight ? 'flex-1' : 'px-4 pt-4'} ${className}`}>
<View className="h-8 w-full rounded-t-sm border-b-2 border-dashed border-gray-100 bg-white items-center justify-center">
<View className="absolute left-4 h-2 w-2 rounded-full bg-gray-200" />
<View className="absolute right-4 h-2 w-2 rounded-full bg-gray-200" />
</View>
<View className="w-full flex-1 rounded-b-sm bg-white p-4">
<View className="w-full flex-row justify-between">
<Text className="text-[12px] font-bold text-gray-300">2024</Text>
<Text className="text-[12px] font-bold text-gray-300">MAY</Text>
</View>
<View className="mt-12 w-full items-center">
<Text
className={`text-[120px] font-bold text-center ${
day % 7 === 0 ? 'text-red-500' : 'text-[#191F28]'
}`}
>
{day}
</Text>
</View>
<View className="mt-12 items-center gap-4">
<View className="h-2 w-32 rounded-full bg-gray-100 " />
<View className="h-2 w-20 rounded-full bg-gray-100" />
</View>
<View className="mt-48 h-px w-full bg-gray-200" />
</View>
</View>
);
}> = ({ day = 14, fullHeight = false, className = '' }) => {
const now = new Date();
const currentYear = now.getFullYear();
const currentMonth = now.toLocaleString('default', { month: 'short' }).toUpperCase();
return (
<View className={`w-full ${fullHeight ? 'flex-1' : 'px-4 pt-4'} ${className}`}>
<View className="h-8 w-full rounded-t-sm border-b-2 border-dashed border-gray-100 bg-white items-center justify-center">
<View className="absolute left-4 h-2 w-2 rounded-full bg-gray-200" />
<View className="absolute right-4 h-2 w-2 rounded-full bg-gray-200" />
</View>
<View className="w-full flex-1 rounded-b-sm bg-white p-4">
<View className="w-full flex-row justify-between">
<Text className="text-[12px] font-bold text-gray-300">{currentYear}</Text>
<Text className="text-[12px] font-bold text-gray-300">{currentMonth}</Text>
</View>
<View className="mt-12 w-full items-center">
<Text
className={`text-[120px] font-bold text-center ${
day % 7 === 0 ? 'text-red-500' : 'text-[#191F28]'
}`}
>
{day}
</Text>
</View>
<View className="mt-12 items-center gap-4">
<View className="h-2 w-32 rounded-full bg-gray-100 " />
<View className="h-2 w-20 rounded-full bg-gray-100" />
</View>
<View className="mt-48 h-px w-full bg-gray-200" />
</View>
</View>
);
};

Copilot uses AI. Check for mistakes.
Comment on lines +285 to +286
<Text className="text-xs font-bold text-gray-300">2024</Text>
<Text className="text-xs font-bold text-gray-300">MAY</Text>

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The hardcoded date values "2024" and "MAY" make the mockup less realistic and could confuse users if they see an onboarding screen with outdated dates. Consider using dynamic dates or a more generic representation that doesn't show specific months/years.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +43
const Onboarding: React.FC<OnboardingProps> = ({ onComplete }) => {
const { width } = useWindowDimensions();
const phoneWidth = Math.min(width * 0.74, 310);
const phoneHeight = Math.round(phoneWidth * 1.68);

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The magic number 1.68 for the aspect ratio should be extracted as a named constant (e.g., PHONE_ASPECT_RATIO) to improve code readability and maintainability.

Suggested change
const Onboarding: React.FC<OnboardingProps> = ({ onComplete }) => {
const { width } = useWindowDimensions();
const phoneWidth = Math.min(width * 0.74, 310);
const phoneHeight = Math.round(phoneWidth * 1.68);
const PHONE_ASPECT_RATIO = 1.68;
const Onboarding: React.FC<OnboardingProps> = ({ onComplete }) => {
const { width } = useWindowDimensions();
const phoneWidth = Math.min(width * 0.74, 310);
const phoneHeight = Math.round(phoneWidth * PHONE_ASPECT_RATIO);

Copilot uses AI. Check for mistakes.
Comment on lines +128 to +134
<ScrollView
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
onScroll={handleScroll}
scrollEventThrottle={16}
>

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

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

The ScrollView is missing a scrollEnabled prop. Consider explicitly setting scrollEnabled={true} or adding a ref to programmatically control scrolling if needed for a guided onboarding experience.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat - 온보딩 화면 추가

2 participants