Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added apps/client/src/assets/chippi_level1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/client/src/assets/chippi_level2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/client/src/assets/chippi_level3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/client/src/assets/chippi_level4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/client/src/assets/chippi_level5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 0 additions & 5 deletions apps/client/src/layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import { Outlet } from 'react-router-dom';
import OptionsMenuButton from '@shared/components/optionsMenuButton/OptionsMenuButton';

const Layout = () => {
return (
<>
{/* TODO: 필요시 레이아웃 추가 */}
{/* TODO: 사이드바 추가 */}
<OptionsMenuButton
onEdit={function (): void {}}
onDelete={function (): void {}}
></OptionsMenuButton>

<Outlet />
</>
Expand Down
57 changes: 53 additions & 4 deletions apps/client/src/pages/level/Level.tsx
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'
Comment on lines +32 to +37
Copy link
Collaborator

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을 쓰신 이유가 궁금합니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

맞습니당 이 코드에 따로 분기나 객체 구분은 없어요-! 다만 한줄로 쭉 나열해서 쓰다보면 가독성이 좋지 않아 cn으로 구분해서 사용했습니다-!

)}
>
<LevelInfoCard />
</div>
</div>
</div>

<Badge text="오늘 모은 도토리 개수" countNum={acorns} />
<div className="flex">
<TreeStatusCard acorns={acorns} />
</div>
</div>
</div>
</div>
</div>
);
}
2 changes: 1 addition & 1 deletion apps/client/src/pages/level/components/LevelInfoCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { cn } from '@pinback/design-system/utils';
import { Level } from '@pinback/design-system/ui';
import { Icon, type IconName } from '@pinback/design-system/icons';
import { TREE_LEVEL_TABLE, type TreeLevel } from '../utils/treeLevel';
import { TREE_LEVEL_TABLE, TreeLevel } from '@pages/level/types/treeLevelType';

const LEVEL_TOOLTIP_ICON = {
1: 'tooltip_1',
Expand Down
34 changes: 34 additions & 0 deletions apps/client/src/pages/level/components/LevelScene.tsx
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
Copy link
Collaborator

Choose a reason for hiding this comment

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

와우 이미지 드래그나 복사 불가하게 제한해둔 거 너무 세심하고 꼼꼼하시네유

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

테스트하다가 드래그되는게 불편해서 따로 처리해뒀습니당-!

/>
</div>
);
}
2 changes: 1 addition & 1 deletion apps/client/src/pages/level/components/TreeStatusCard.tsx
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';
Copy link
Collaborator

Choose a reason for hiding this comment

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

제 코드에도 상대경로로 작업한게 많은데, 이거보고 저도 바꿔놔야겠다고 생각났네요


export interface TreeStatusCardProps {
acorns: number;
Expand Down
25 changes: 25 additions & 0 deletions apps/client/src/pages/level/types/treeLevelType.ts
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;
};
31 changes: 7 additions & 24 deletions apps/client/src/pages/level/utils/treeLevel.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,8 @@
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;
};
import {
TREE_LEVEL_TABLE,
TreeLevelResult,
TreeLevelRow,
} from '@pages/level/types/treeLevelType';

function findLevelRow(count: number, rows: readonly TreeLevelRow[]) {
const idx = rows.findIndex(
Expand All @@ -48,3 +29,5 @@ export function getTreeLevel(acorns: number): TreeLevelResult {
const { row, next } = findLevelRow(acorns, TREE_LEVEL_TABLE);
return { ...row, ...calcProgress(acorns, row, next) };
}

export { TREE_LEVEL_TABLE };
2 changes: 1 addition & 1 deletion packages/tailwind-config/shared-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
--color-gradient-end: #33d08f;

/* Secondary Color */
--color-secondary: #f4f2ec;
--color-subcolor: #f4f2ec;
Copy link
Member

Choose a reason for hiding this comment

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

👍


/* Grayscale */
Comment on lines 182 to 185
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

토큰명 리네임은 합리적이나 Biome 파서 오류로 CI 차단 가능

Tailwind v4 @theme 문법을 Biome(2.1.2)이 아직 정상 파싱하지 못해 parse 에러가 납니다. 코드 자체는 정상 CSS이므로 린터 설정/우회가 필요합니다.

권장 조치:

  • 단기: 해당 파일에서 Biome 파싱을 비활성화(override)하거나 @theme 블록만 무시하도록 설정.
  • 중기: Biome 업데이트 또는 packages/tailwind-config/**/*.css 경로를 Biome 대상에서 제외.

추가로, 점진적 마이그레이션을 위해 이전 토큰도 함께 노출해두면 레거시 클래스(bg-secondary)가 남아 있어도 안전합니다.

   /* 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 || true

Length of output: 11255


Biome 파서 오류로 CI 실패 확인 – 단기 대응 필요

  • Biome(2.1.2)가 packages/tailwind-config/shared-styles.css@theme 블록 내 CSS 변수 정의를 파싱하지 못해 207개 에러 발생 확인
  • 단기: 해당 파일에 대해 Biome 파서 무시/override 설정 추가
  • 중기: Biome 최신 버전으로 업그레이드하거나 packages/tailwind-config/**/*.css 경로를 검사 대상에서 제외
  • 레거시 토큰(--color-secondary) 사용처(packages/design-system/styles.css)가 존재하므로, 점진적 마이그레이션을 위해 alias 변수 추가 권장
   /* Secondary Color */
+  /* temporary alias for backward-compat */
+  --color-secondary: var(--color-subcolor);
📝 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
/* Secondary Color */
--color-secondary: #f4f2ec;
--color-subcolor: #f4f2ec;
/* Grayscale */
/* Secondary Color */
/* temporary alias for backward-compat */
--color-secondary: var(--color-subcolor);
--color-subcolor: #f4f2ec;
/* Grayscale */
🧰 Tools
🪛 Biome (2.1.2)

[error] 183-183: expected , but instead found --color-subcolor

Remove --color-subcolor

(parse)


[error] 183-183: Unexpected value or character.

Expected one of:

(parse)


[error] 183-183: expected , but instead found ;

Remove ;

(parse)

🤖 Prompt for AI Agents
In packages/tailwind-config/shared-styles.css around lines 182 to 185, Biome
2.1.2 fails parsing CSS variable definitions inside the @theme block causing CI
errors; as a short-term fix add a Biome parser override/ignore entry for this
file (or for packages/tailwind-config/**/*.css) in the repo's Biome config so
the file is skipped by the parser, and also add a legacy alias variable
declaration mapping --color-secondary to --color-subcolor within this CSS file
to keep compatibility with packages/design-system/styles.css; for mid-term
consider upgrading Biome or excluding the path from parsing altogether.

--color-gray0: #f7f7fb;
Expand Down
Loading