-
Notifications
You must be signed in to change notification settings - Fork 0
[FEAT] 온보딩 화면 컴포넌트 구현 #120
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
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
d104b7f
feat(design-system): ChevronSmall 아이콘 소스 및 google-logo 에셋 추가 (#118)
ehye1 e43b142
feat(web): 온보딩 컴포넌트 구현 (#118)
ehye1 300728d
feat(web): 온보딩 컴포넌트 next-intl 다국어 매핑 추가 (#118)
ehye1 da35beb
chore(web): develop 머지 충돌 해결 - messages 파일 병합 (#118)
ehye1 032108f
fix(web): 코드래빗 리뷰 반영 - OnboardingButton disabled 처리 및 isSelected 컨벤션 …
ehye1 a5db346
chore(web): 온보딩 페이지 테스트 렌더링 제거 (#118)
ehye1 0d2c23b
fix(web): OnboardingTimeDropdown 제어/비제어 혼합 패턴 수정 (#118)
ehye1 db0fc6c
refactor(web): OnboardingButton boolean 변수명 is 접두사 적용 (#118)
ehye1 bb0fade
refactor(web): OnboardingStepButton div를 ol/li 시맨틱 태그로 교체 (#118)
ehye1 a30df9b
feat(design-system): ChevronDownGray/Up 아이콘 SVG 소스 추가 (#118)
ehye1 3fde177
feat(web): OnboardingTimeDropdown AM/PM 표시 및 피그마 레이아웃 반영 (#118)
ehye1 a45d7f7
fix(web): OnboardingGoogleButton 고정 너비 제거 (#118)
ehye1 d70f58d
refactor(web): OnboardingButton variant discriminated union으로 재설계 (#118)
ehye1 6ee9ec6
fix(config): 전역 webkit 스크롤바 너비 실측값으로 수정 (#118)
ehye1 43c8b5d
chore(web): 온보딩 페이지 렌더링 및 스크롤바 설정 정리 (#118)
ehye1 43dd6d2
refactor(web): OnboardingTimeField _components에서 _containers로 이동 (#118)
ehye1 4b960e0
chore(web): 온보딩 _containers .gitkeep 제거 (#118)
ehye1 6650449
fix(web): OnboardingTimeField의 잘못된 import 경로 수정 (#118)
ehye1 e6155ae
refactor(web): 온보딩 컴포넌트·컨테이너 계층 분리 (#118)
ehye1 3c70014
refactor(web): OnboardingGoogleButtonProps 인터페이스 export 제거 (#118)
ehye1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
71 changes: 71 additions & 0 deletions
71
apps/timo-web/app/[locale]/onboarding/_components/OnboardingButton.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| import { | ||
| ChevronLeftIcon, | ||
| ChevronSmallRightIcon, | ||
| ChevronSmallRightWhiteIcon, | ||
| } from "@repo/timo-design-system/icons"; | ||
| import { cn } from "@repo/timo-design-system/utils"; | ||
|
|
||
| export interface OnboardingButtonProps { | ||
| variant: "next" | "prev" | "start"; | ||
| label: string; | ||
| isActive?: boolean; | ||
| disabled?: boolean; | ||
| onClick?: () => void; | ||
| } | ||
|
|
||
| export const OnboardingButton = ({ | ||
| variant, | ||
| label, | ||
| isActive = false, | ||
| disabled = false, | ||
| onClick, | ||
| }: OnboardingButtonProps) => { | ||
| if (variant === "prev") { | ||
| return ( | ||
| <button | ||
| type="button" | ||
| onClick={onClick} | ||
| className="hover:bg-timo-gray-500 bg-timo-gray-200 flex items-center justify-center gap-2 rounded-[4px] px-4 py-2 transition-colors duration-200 ease-in-out" | ||
| > | ||
| <ChevronLeftIcon width={18} height={18} /> | ||
| <span className="typo-headline-m-16 text-timo-gray-900">{label}</span> | ||
| </button> | ||
| ); | ||
| } | ||
|
|
||
| if (variant === "start") { | ||
| return ( | ||
| <button | ||
| type="button" | ||
| onClick={onClick} | ||
| className="bg-timo-blue-300 flex items-center justify-center gap-2 rounded-[4px] px-4 py-2" | ||
| > | ||
| <span className="typo-headline-m-16 text-white">{label}</span> | ||
| </button> | ||
| ); | ||
| } | ||
|
|
||
| const isDisabled = disabled || !isActive; | ||
|
|
||
| return ( | ||
| <button | ||
| type="button" | ||
| onClick={onClick} | ||
| disabled={isDisabled} | ||
| className={cn( | ||
| "flex items-center justify-center gap-2 rounded-[4px] px-4 py-2", | ||
| isActive ? "bg-timo-blue-300" : "bg-timo-gray-200", | ||
| )} | ||
| > | ||
| <span | ||
| className={cn( | ||
| "typo-headline-m-16", | ||
| isActive ? "text-white" : "text-timo-gray-700", | ||
| )} | ||
| > | ||
| {label} | ||
| </span> | ||
| {isActive ? <ChevronSmallRightWhiteIcon /> : <ChevronSmallRightIcon />} | ||
| </button> | ||
| ); | ||
| }; |
38 changes: 38 additions & 0 deletions
38
apps/timo-web/app/[locale]/onboarding/_components/OnboardingGoogleButton.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import googleLogo from "@repo/timo-design-system/assets/images/google-logo.svg"; | ||
| import { cn } from "@repo/timo-design-system/utils"; | ||
| import Image from "next/image"; | ||
|
|
||
| type OnboardingGoogleButtonVariant = "login" | "connectCalendar"; | ||
|
|
||
| interface OnboardingGoogleButtonProps { | ||
| variant: OnboardingGoogleButtonVariant; | ||
| label: string; | ||
| isSelected?: boolean; | ||
| onClick?: () => void; | ||
| } | ||
|
|
||
| export const OnboardingGoogleButton = ({ | ||
| label, | ||
| isSelected = false, | ||
| onClick, | ||
| }: OnboardingGoogleButtonProps) => { | ||
| return ( | ||
| <button | ||
| type="button" | ||
| onClick={onClick} | ||
| className={cn( | ||
| "flex w-full items-center justify-center rounded-[4px] border py-2.5", | ||
| isSelected | ||
| ? "border-timo-blue-300 bg-timo-blue-50" | ||
| : "border-timo-gray-500 bg-white", | ||
| )} | ||
| > | ||
| <div className="flex items-center gap-2.5 px-2"> | ||
| <div className="flex size-[22px] items-center justify-center"> | ||
| <Image src={googleLogo} alt="Google" width={18} height={18} /> | ||
| </div> | ||
| <span className="typo-headline-m-16 text-timo-blue-300">{label}</span> | ||
| </div> | ||
| </button> | ||
| ); | ||
| }; | ||
32 changes: 32 additions & 0 deletions
32
apps/timo-web/app/[locale]/onboarding/_components/OnboardingStepButton.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { cn } from "@repo/timo-design-system/utils"; | ||
|
|
||
| interface OnboardingStepButtonProps { | ||
| step: 1 | 2 | 3 | 4; | ||
| } | ||
|
|
||
| const STEPS = [1, 2, 3, 4] as const; | ||
|
|
||
| export const OnboardingStepButton = ({ step }: OnboardingStepButtonProps) => { | ||
| return ( | ||
| <ol className="flex items-center gap-2"> | ||
| {STEPS.map((s) => ( | ||
| <li | ||
| key={s} | ||
| className={cn( | ||
| "flex size-[19px] items-center justify-center rounded-full", | ||
| s === step ? "bg-timo-blue-300" : "bg-timo-blue-65", | ||
| )} | ||
| > | ||
| <span | ||
| className={cn( | ||
| "typo-caption-r-10", | ||
| s === step ? "text-white" : "text-timo-blue-100", | ||
| )} | ||
| > | ||
| {s} | ||
| </span> | ||
| </li> | ||
| ))} | ||
| </ol> | ||
| ); | ||
|
ehye1 marked this conversation as resolved.
|
||
| }; | ||
64 changes: 64 additions & 0 deletions
64
apps/timo-web/app/[locale]/onboarding/_components/OnboardingTimeDropdown.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import { | ||
| ChevronDownGrayIcon, | ||
| ChevronUpGrayIcon, | ||
| } from "@repo/timo-design-system/icons"; | ||
| import { Dropdown } from "@repo/timo-design-system/ui"; | ||
| import { cn } from "@repo/timo-design-system/utils"; | ||
|
|
||
| import { getAmPm } from "@/utils/get-am-pm"; | ||
|
|
||
| const TIME_OPTIONS = Array.from( | ||
| { length: 25 }, | ||
| (_, i) => `${String(i).padStart(2, "0")}:00`, | ||
| ); | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| interface OnboardingTimeDropdownProps { | ||
| value: string; | ||
| placeholder?: string; | ||
| onChange: (time: string) => void; | ||
| } | ||
|
|
||
| export const OnboardingTimeDropdown = ({ | ||
| value, | ||
| placeholder, | ||
| onChange, | ||
| }: OnboardingTimeDropdownProps) => { | ||
| return ( | ||
| <Dropdown className="w-[150px]"> | ||
| <Dropdown.Trigger className="group border-timo-gray-500 flex w-full items-center justify-between rounded-[4px] border bg-white px-4 py-3 text-left"> | ||
| {value ? ( | ||
| <div className="flex items-center gap-1"> | ||
| <span className="typo-headline-b-16 text-timo-black">{value}</span> | ||
| <span className="typo-headline-b-16 text-timo-black"> | ||
| {getAmPm(value)} | ||
| </span> | ||
| </div> | ||
| ) : ( | ||
| <span className="typo-headline-b-16 text-timo-gray-700"> | ||
| {placeholder} | ||
| </span> | ||
| )} | ||
| <ChevronDownGrayIcon className="group-aria-expanded:hidden" /> | ||
| <ChevronUpGrayIcon className="hidden group-aria-expanded:block" /> | ||
| </Dropdown.Trigger> | ||
|
|
||
| <Dropdown.Panel className="border-timo-gray-500 mt-1 h-[220px] w-full rounded-[4px] border py-3 pr-2.5 pl-4"> | ||
| <div className="flex h-full w-full flex-col gap-2.5 overflow-y-auto p-1 pr-3.5"> | ||
| {TIME_OPTIONS.map((time) => ( | ||
| <Dropdown.Item | ||
| key={time} | ||
| onClick={() => onChange(time)} | ||
| className={cn( | ||
| "typo-headline-b-16 flex w-full justify-between rounded-none", | ||
| value === time ? "text-timo-blue-300" : "text-timo-gray-700", | ||
| )} | ||
| > | ||
| <span>{time}</span> | ||
| <span>{getAmPm(time)}</span> | ||
| </Dropdown.Item> | ||
| ))} | ||
| </div> | ||
| </Dropdown.Panel> | ||
| </Dropdown> | ||
| ); | ||
| }; | ||
Empty file.
31 changes: 31 additions & 0 deletions
31
apps/timo-web/app/[locale]/onboarding/_containers/OnboardingButtonContainer.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| "use client"; | ||
|
|
||
| import { useTranslations } from "next-intl"; | ||
|
|
||
| import { OnboardingButton } from "@/app/[locale]/onboarding/_components/OnboardingButton"; | ||
|
|
||
| interface OnboardingButtonContainerProps { | ||
| variant: "next" | "prev" | "start"; | ||
| isActive?: boolean; | ||
| disabled?: boolean; | ||
| onClick?: () => void; | ||
| } | ||
|
|
||
| export const OnboardingButtonContainer = ({ | ||
| variant, | ||
| isActive, | ||
| disabled, | ||
| onClick, | ||
| }: OnboardingButtonContainerProps) => { | ||
| const t = useTranslations("Onboarding"); | ||
|
|
||
| return ( | ||
| <OnboardingButton | ||
| variant={variant} | ||
| label={t(`button.${variant}`)} | ||
| isActive={isActive} | ||
| disabled={disabled} | ||
| onClick={onClick} | ||
| /> | ||
| ); | ||
| }; |
28 changes: 28 additions & 0 deletions
28
apps/timo-web/app/[locale]/onboarding/_containers/OnboardingGoogleButtonContainer.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| "use client"; | ||
|
|
||
| import { useTranslations } from "next-intl"; | ||
|
|
||
| import { OnboardingGoogleButton } from "@/app/[locale]/onboarding/_components/OnboardingGoogleButton"; | ||
|
|
||
| interface OnboardingGoogleButtonContainerProps { | ||
| variant: "login" | "connectCalendar"; | ||
| isSelected?: boolean; | ||
| onClick?: () => void; | ||
| } | ||
|
|
||
| export const OnboardingGoogleButtonContainer = ({ | ||
| variant, | ||
| isSelected, | ||
| onClick, | ||
| }: OnboardingGoogleButtonContainerProps) => { | ||
| const t = useTranslations("Onboarding"); | ||
|
|
||
| return ( | ||
| <OnboardingGoogleButton | ||
| variant={variant} | ||
| label={t(`onboardingGoogleButton.${variant}`)} | ||
| isSelected={isSelected} | ||
| onClick={onClick} | ||
| /> | ||
| ); | ||
| }; |
17 changes: 17 additions & 0 deletions
17
apps/timo-web/app/[locale]/onboarding/_containers/OnboardingTimeContainer.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| "use client"; | ||
|
|
||
| import { useState } from "react"; | ||
|
|
||
| import { OnboardingTimeDropdown } from "@/app/[locale]/onboarding/_components/OnboardingTimeDropdown"; | ||
|
|
||
| export const OnboardingTimeContainer = () => { | ||
| const [time, setTime] = useState(""); | ||
|
|
||
| return ( | ||
| <OnboardingTimeDropdown | ||
| value={time} | ||
| placeholder="01:00" | ||
| onChange={setTime} | ||
| /> | ||
| ); | ||
| }; | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| const HOURS_IN_DAY = 24; | ||
|
|
||
| /** | ||
| * "HH:MM" 형식의 시간 문자열에서 오전/오후를 판별합니다. | ||
| * 24시("24:00")는 다음날 자정(오전)으로 취급합니다. | ||
| * | ||
| * @param time - "HH:MM" 형식의 시간 문자열 | ||
| * @returns "AM" 또는 "PM" | ||
| */ | ||
| export const getAmPm = (time: string): "AM" | "PM" => { | ||
| const hour = parseInt(time.split(":")[0] ?? "0", 10); | ||
| return hour >= 12 && hour < HOURS_IN_DAY ? "PM" : "AM"; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
packages/timo-design-system/src/assets/images/google-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
packages/timo-design-system/src/icons/source/chevron-down-gray.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
packages/timo-design-system/src/icons/source/chevron-small-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
packages/timo-design-system/src/icons/source/chevron-small-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
packages/timo-design-system/src/icons/source/chevron-small-right-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
packages/timo-design-system/src/icons/source/chevron-small-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
packages/timo-design-system/src/icons/source/chevron-small-up.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
packages/timo-design-system/src/icons/source/chevron-up-gray.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사소한거긴 한데 PR 설명에는 selected prop이라고 적혀있어서 pr 내용에 실제 코드랑 prop명 일치시키면 좋을 것 같아요-!