-
Notifications
You must be signed in to change notification settings - Fork 1
Feat(client): 레벨 페이지 레이아웃 #57
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,54 @@ | ||
| const Level = () => { | ||
| return <div className="bg-secondary flex flex-col gap-[2rem] p-[1rem]"></div>; | ||
| }; | ||
| import { Icon } from '@pinback/design-system/icons'; | ||
| import { cn } from '@pinback/design-system/utils'; | ||
| import LevelScene from '@pages/level/components/LevelScene'; | ||
| import LevelInfoCard from '@pages/level/components/LevelInfoCard'; | ||
| import TreeStatusCard from '@pages/level/components/TreeStatusCard'; | ||
| import { getTreeLevel } from '@pages/level/utils/treeLevel'; | ||
| import { TreeLevel } from '@pages/level/types/treeLevelType'; | ||
| import { Badge } from '@pinback/design-system/ui'; | ||
|
|
||
| export default Level; | ||
| export default function Level() { | ||
| const acorns = 1; // TODO: API 연결되면 교체 | ||
| const info = getTreeLevel(acorns); | ||
|
|
||
| return ( | ||
| <div className={cn('bg-subcolor mx-auto h-dvh w-full overflow-hidden')}> | ||
| <div className="relative h-full w-full overflow-hidden rounded-[1.2rem]"> | ||
| <LevelScene level={info.level as TreeLevel} /> | ||
|
|
||
| <div className="absolute inset-0"> | ||
| <div className="flex flex-col items-start gap-[2rem] px-[8rem] py-[5.2rem]"> | ||
| <div className="flex flex-row items-center gap-[0.8rem]"> | ||
| <h1 className="head3 text-font-black-1">치삐의 지식나무 숲</h1> | ||
| <div className="relative items-center"> | ||
| <button | ||
| type="button" | ||
| className="peer flex items-center justify-center p-[0.4rem]" | ||
| aria-describedby="level-info-card" | ||
| > | ||
| <Icon name="ic_info" width={20} height={20} /> | ||
| </button> | ||
| <div | ||
| id="level-info-card" | ||
| className={cn( | ||
| 'pointer-events-none absolute left-0 top-[3rem] z-[20]', | ||
| 'opacity-0 transition-opacity duration-150', | ||
| 'peer-hover:pointer-events-auto peer-focus-visible:pointer-events-auto', | ||
| 'peer-hover:opacity-100 peer-focus-visible:opacity-100' | ||
| )} | ||
| > | ||
| <LevelInfoCard /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
| <Badge text="오늘 모은 도토리 개수" countNum={acorns} /> | ||
| <div className="flex"> | ||
| <TreeStatusCard acorns={acorns} /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import { cn } from '@pinback/design-system/utils'; | ||
| import { TreeLevel } from '@pages/level/types/treeLevelType'; | ||
| import { HTMLAttributes } from 'react'; | ||
|
|
||
| import chippi_level1 from '../../../assets/chippi_level1.png'; | ||
| import chippi_level2 from '../../../assets/chippi_level2.png'; | ||
| import chippi_level3 from '../../../assets/chippi_level3.png'; | ||
| import chippi_level4 from '../../../assets/chippi_level4.png'; | ||
| import chippi_level5 from '../../../assets/chippi_level5.png'; | ||
|
|
||
| const SCENE_BY_LEVEL: Record<TreeLevel, string> = { | ||
| 1: chippi_level1, | ||
| 2: chippi_level2, | ||
| 3: chippi_level3, | ||
| 4: chippi_level4, | ||
| 5: chippi_level5, | ||
| } as const; | ||
|
|
||
| interface LevelSceneProps extends HTMLAttributes<HTMLDivElement> { | ||
| level: TreeLevel; | ||
| } | ||
|
|
||
| export default function LevelScene({ level, className }: LevelSceneProps) { | ||
| const src = SCENE_BY_LEVEL[level]; | ||
| return ( | ||
| <div className={cn('absolute inset-0', className)} aria-hidden="true"> | ||
| <img | ||
| src={src} | ||
| draggable={false} | ||
| className="pointer-events-none h-full w-full select-none rounded-[1.2rem] object-contain object-[right_bottom]" | ||
|
Comment on lines
+28
to
+30
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 와우 이미지 드래그나 복사 불가하게 제한해둔 거 너무 세심하고 꼼꼼하시네유
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 테스트하다가 드래그되는게 불편해서 따로 처리해뒀습니당-! |
||
| /> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import { Level, Progress } from '@pinback/design-system/ui'; | ||
| import { cn } from '@pinback/design-system/utils'; | ||
| import { getTreeLevel } from '../utils/treeLevel'; | ||
| import { getTreeLevel } from '@pages/level/utils/treeLevel'; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 제 코드에도 상대경로로 작업한게 많은데, 이거보고 저도 바꿔놔야겠다고 생각났네요 |
||
|
|
||
| export interface TreeStatusCardProps { | ||
| acorns: number; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| export type TreeLevelRowShape = { | ||
| level: number; | ||
| name: string; | ||
| min: number; | ||
| max?: number; | ||
| rangeLabel: string; | ||
| }; | ||
|
|
||
| export const TREE_LEVEL_TABLE = [ | ||
| { level: 1, name: '잊힌 기록의 숲', min: 0, max: 0, rangeLabel: '0개' }, | ||
| { level: 2, name: '햇살의 터전', min: 1, max: 2, rangeLabel: '1–2개' }, | ||
| { level: 3, name: '기록의 오솔길', min: 3, max: 4, rangeLabel: '3–4개' }, | ||
| { level: 4, name: '지식 나무 언덕', min: 5, max: 6, rangeLabel: '5–6개' }, | ||
| { level: 5, name: '도토리 만개 숲', min: 7, rangeLabel: '7개 이상' }, | ||
| ] as const satisfies readonly TreeLevelRowShape[]; | ||
|
|
||
| export type TreeLevel = (typeof TREE_LEVEL_TABLE)[number]['level']; | ||
|
|
||
| export type TreeLevelRow = TreeLevelRowShape; | ||
|
|
||
| export type TreeLevelResult = TreeLevelRow & { | ||
| progressToNext: number; | ||
| nextMin?: number; | ||
| remainingToNext?: number; | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -180,7 +180,7 @@ | |||||||||||||||||||||||
| --color-gradient-end: #33d08f; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /* Secondary Color */ | ||||||||||||||||||||||||
| --color-secondary: #f4f2ec; | ||||||||||||||||||||||||
| --color-subcolor: #f4f2ec; | ||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /* Grayscale */ | ||||||||||||||||||||||||
|
Comment on lines
182
to
185
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain토큰명 리네임은 합리적이나 Biome 파서 오류로 CI 차단 가능 Tailwind v4 권장 조치:
추가로, 점진적 마이그레이션을 위해 이전 토큰도 함께 노출해두면 레거시 클래스( /* Secondary Color */
- --color-subcolor: #f4f2ec;
+ --color-subcolor: #f4f2ec;
+ /* temporary alias for backward-compat */
+ --color-secondary: var(--color-subcolor);확인 스크립트: 🏁 Script executed: #!/bin/bash
# 1) 레거시 사용처 존재 여부
rg -nP 'bg-secondary|--color-secondary'
# 2) Biome가 해당 파일에서만 실패하는지 확인
pnpm biome check packages/tailwind-config/shared-styles.css || trueLength of output: 11255 Biome 파서 오류로 CI 실패 확인 – 단기 대응 필요
/* Secondary Color */
+ /* temporary alias for backward-compat */
+ --color-secondary: var(--color-subcolor);📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (2.1.2)[error] 183-183: expected Remove --color-subcolor (parse) [error] 183-183: Unexpected value or character. Expected one of: (parse) [error] 183-183: expected Remove ; (parse) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| --color-gray0: #f7f7fb; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
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.
이거 cn이 스타일값 객체들을 여러개 합칠 때 사용하는 걸로 아는데요!
이 코드 경우에, 분기나 객체 구분이 안보이는데, z-[20] opacity-0 ..처럼 쭉 이어서 나열하지않고 cn을 쓰신 이유가 궁금합니다!
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.
맞습니당 이 코드에 따로 분기나 객체 구분은 없어요-! 다만 한줄로 쭉 나열해서 쓰다보면 가독성이 좋지 않아 cn으로 구분해서 사용했습니다-!