Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
9f63334
:heavy_plus_sign: @tanstack/react-query 추가
nijesmik Oct 21, 2025
c27704b
:sparkles: React Query Provider 추가
nijesmik Oct 22, 2025
00565f6
:heavy_plus_sign: jotai 의존성 추가
nijesmik Oct 22, 2025
48be1af
:truck: `App.tsx`에서 `queryClient` 분리
nijesmik Oct 22, 2025
13bf938
:truck: `User` 타입 분리
nijesmik Oct 22, 2025
2908e2c
:recycle: `Collection` 페이지 및 상태관리 리팩토링 #62
nijesmik Oct 22, 2025
6602c99
:truck: `Collection` 타입 디렉토리 이동
nijesmik Oct 22, 2025
839fd9b
:truck: `Collection` 페이지 ui 관련 파일 디렉토리 정리
nijesmik Oct 22, 2025
3cdd6a0
:truck: `Menu` 컴포넌트 이름 변경
nijesmik Oct 22, 2025
7dea061
:truck: 타입 이름 변경
nijesmik Oct 22, 2025
84d3b54
:recycle: `AudioButton` 컴포넌트 memoization
nijesmik Oct 22, 2025
1ca60b9
:recycle: `Home` 페이지 loader 제거
nijesmik Oct 22, 2025
e6cb01a
:recycle: 메뉴 버튼 리팩토링
nijesmik Oct 22, 2025
f3351e2
:fire: `MainInfo` 컴포넌트 삭제
nijesmik Oct 22, 2025
670ee8a
:recycle: `GameInfo` 컴포넌트 리팩토링
nijesmik Oct 22, 2025
a1fc5a9
:recycle: `useUserStatus` 리팩토링 #61
nijesmik Oct 23, 2025
4fa000c
:recycle: `SettingNavigationButton` usage prop 추가
nijesmik Oct 23, 2025
6c1cbcc
:recycle: BasicContentFrame를 레이아웃으로 분리
nijesmik Oct 23, 2025
9b43886
:necktie: 설정 페이지 접근 시 member가 아닌 경우 404 페이지로 이동 #25
nijesmik Oct 23, 2025
a87b753
:truck: 로그인 페이지 및 에러 메시지 디렉토리 분리
nijesmik Oct 23, 2025
8d82143
:recycle: User State 리팩토링 #61
nijesmik Oct 23, 2025
d770c2d
:bug: prevent rendering of image when imgSrc is not provided
nijesmik Oct 23, 2025
5a07b2e
:recycle: 로그아웃 리팩토링
nijesmik Oct 23, 2025
ff4764b
:recycle: 회원가입 리팩토링
nijesmik Oct 23, 2025
32a6dfd
:recycle: 멤버 로그인 리팩토링
nijesmik Oct 23, 2025
e77bbf5
:recycle: 게스트 로그인 리팩토링
nijesmik Oct 23, 2025
f87f493
:recycle: Game State 삭제 및 게임 페이지 리팩토링 #63
nijesmik Oct 23, 2025
3b4fa94
:sparkles: 게임 종료 후 user stale 처리
nijesmik Oct 23, 2025
e9df5b5
:recycle: WebSocket State 리팩토링 #64
nijesmik Oct 23, 2025
17d532a
:recycle: 효과음 상태관리 리팩토링 #65
nijesmik Oct 23, 2025
980b652
:recycle: 배경음 상태관리 리팩토링 #27
nijesmik Oct 24, 2025
b21446b
:heavy_minus_sign: zustand 삭제 #26
nijesmik Oct 24, 2025
13defe1
:fire: states 폴더 삭제 #26
nijesmik Oct 24, 2025
8a41cc5
:truck: collection hook 이름 변경 #62
nijesmik Oct 24, 2025
9fd5e21
:truck: collection data 상태관리 폴더 분리 #62
nijesmik Oct 24, 2025
64d4835
:bug: 효과음 atom 마운트 오류 수정 #65
nijesmik Oct 24, 2025
2020567
:bug: 게임 종료 후 collection 데이터 stale 처리 #62
nijesmik Oct 24, 2025
f8c27df
:necktie: useStore 삭제
nijesmik Oct 24, 2025
06f0983
:truck: rename collection-related functions
nijesmik Oct 24, 2025
0be414e
:fire: 불필요한 타입 삭제
nijesmik Oct 24, 2025
45f90d3
:fire: socket 클래스 중복 method 제거
nijesmik Oct 24, 2025
f3296c1
:truck: webSocket 변수명 변경
nijesmik Oct 24, 2025
d596f94
:truck: finder 페이지 api 파일 위치 변경 #69
nijesmik Oct 24, 2025
ca995ef
:recycle: Map 컴포넌트를 공통 컴포넌트로 분리 #41
nijesmik Oct 24, 2025
fbb941b
:truck: 방 설정 컴포넌트 분리 #69
nijesmik Oct 24, 2025
9f0fca6
:art: finder 페이지 ui 폴더 구조 변경 #69
nijesmik Oct 24, 2025
cbe5f95
:recycle: 방 설정 컴포넌트 리팩토링
nijesmik Oct 24, 2025
5a092ee
:fire: finder 페이지 `constants.ts`, `types.d.ts` 삭제 #69
nijesmik Oct 24, 2025
cf8018b
:truck: 게임 type, api 파일 이동
nijesmik Oct 24, 2025
a1abe98
:recycle: `ResultInfoBox` 컴포넌트 리팩토링 #70
nijesmik Oct 24, 2025
9c2d112
:truck: result 페이지 ui 폴더 정리 #70
nijesmik Oct 24, 2025
5639dd2
:necktie: lobby 이동 시 replace option 추가
nijesmik Oct 25, 2025
2e58c80
:recycle: lobby 페이지 타입 및 컴포넌트 리팩토링
nijesmik Oct 25, 2025
1cad414
:truck: player 관련 constants, types 파일 이동 #68
nijesmik Oct 25, 2025
1d512b5
:truck: map 관련 constants, types 파일 이동 #68
nijesmik Oct 25, 2025
86a16a9
:truck: map 관련 ui 파일 이동 #68
nijesmik Oct 25, 2025
0531ef1
:truck: tier 관련 constants, types 파일 이동 #68
nijesmik Oct 25, 2025
82b5319
:truck: tier 관련 ui 파일 이동 #68
nijesmik Oct 25, 2025
8db61b0
:truck: tier 타입 변수명 변경 #68
nijesmik Oct 25, 2025
83270ba
:truck: finder 페이지 디렉토리 변경 #69
nijesmik Oct 25, 2025
c30dc42
:truck: lobby 페이지 message 상수 분리 #68
nijesmik Oct 25, 2025
c5d5182
:fire: console log 삭제
nijesmik Oct 25, 2025
ddab0d5
:art: 에러 메시지 constants 리팩토링
nijesmik Oct 25, 2025
a68a258
:necktie: 로그인 시 replace 옵션 추가
nijesmik Oct 25, 2025
110acdb
:art: 회원가입 api, type 파일 이동 #68
nijesmik Oct 25, 2025
771bee2
:truck: 회원가입 관련 변수명 변경
nijesmik Oct 25, 2025
680f8cc
:art: finder 페이지 관련 타입 폴더 이동 #69
nijesmik Oct 25, 2025
6d1f88d
:truck: room-setting 디렉토리 이동 #68
nijesmik Oct 25, 2025
e2468bc
:truck: `@/shared/api` 디렉토리 변경 #68
nijesmik Oct 25, 2025
73958d0
:truck: collection 디렉토리 변경 #68
nijesmik Oct 25, 2025
a755f53
:art: user와 auth를 디렉토리 분리 #68
nijesmik Oct 25, 2025
4d3982c
:truck: `@/shared/utils` #68
nijesmik Oct 25, 2025
4df204d
:truck: routes 파일 디렉토리 변경 #68
nijesmik Oct 25, 2025
e2f41aa
:truck: constants 디렉토리 변경 #68
nijesmik Oct 25, 2025
10b86a4
:bug: 게스트 회원 전환 오류 수정
nijesmik Oct 25, 2025
ea3c95d
:fire: 레거시 hook 삭제
nijesmik Oct 25, 2025
38801f2
:art: lobby 페이지 api, type 폴더 구조 수정 #68
nijesmik Oct 25, 2025
638ed26
:sparkles: disable refetch on window focus
nijesmik Oct 25, 2025
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
173 changes: 97 additions & 76 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
"build-storybook": "storybook build"
},
"dependencies": {
"@tanstack/react-query": "^5.90.5",
"axios": "^1.6.8",
"jotai": "^2.15.0",
"lucide-react": "^0.522.0",
"phaser": "^3.80.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.1",
"zustand": "^4.5.2"
"react-router-dom": "^6.22.1"
},
"devDependencies": {
"@chromatic-com/storybook": "^4.1.1",
Expand Down
12 changes: 8 additions & 4 deletions src/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { QueryClientProvider } from '@tanstack/react-query';
import { RouterProvider } from 'react-router-dom';

import router from './router';

import FullScreenPrompt from '@/components/prompt';

import { useSoundSetting } from '@/features/sound';
import { useBackgroundSound } from '@/features/sound';
import { queryClient } from '@/shared/api';

const App = () => {
const { playBgm } = useSoundSetting();
const { playBackgroundSound } = useBackgroundSound();

return (
<div onClick={playBgm} role='presentation'>
<div onClick={playBackgroundSound} role='presentation'>
<FullScreenPrompt />
<RouterProvider router={router} />
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</div>
);
};
Expand Down
116 changes: 60 additions & 56 deletions src/app/router.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
import { createBrowserRouter, Navigate, Outlet } from 'react-router-dom';

import BasicContentFrame from '@/components/frame/with-buttons';

import Collection from '@/pages/collection';
import Error from '@/pages/error';
import Finder, { getRoomList } from '@/pages/finder';
import Home from '@/pages/home';
import Landing from '@/pages/landing';
import LandingLayout from '@/pages/landing/layout';
import LogIn from '@/pages/landing/logIn';
import Finder from '@/pages/play/finder';
import LogIn from '@/pages/logIn';
import Game from '@/pages/play/game';
import Lobby from '@/pages/play/lobby';
import LobbyPage, { getLobbyInfo } from '@/pages/play/lobby';
import Mode from '@/pages/play/mode';
import Ranking from '@/pages/ranking';
import Result from '@/pages/result';
import Result, { getGameResult } from '@/pages/result';
import Settings from '@/pages/settings';
import Tutorial from '@/pages/tutorial';

import { checkToken, getUser } from '@/services/auth';
import { getRoomList } from '@/services/finder';
import { getLobbyInfo } from '@/services/lobby';
import { checkToken } from '@/services/auth';
import { getRank } from '@/services/rank';
import { getGameResult } from '@/services/result';

import { ROUTE } from '@/constants/routes';
import { ROUTE } from '@/shared/constants';

const router = createBrowserRouter([
{
Expand All @@ -40,73 +38,79 @@ const router = createBrowserRouter([
],
},
{
element: <Outlet />,
errorElement: <Navigate to={ROUTE.main} replace />,
loader: checkToken,
element: (
<BasicContentFrame>
<Outlet />
</BasicContentFrame>
),
children: [
{
path: `${ROUTE.tutorial}`,
element: <Tutorial />,
},
{
path: `${ROUTE.home}`,
element: <Home />,
loader: getUser,
},
{
path: `${ROUTE.play}`,
errorElement: <Navigate to={`${ROUTE.error}/401`} replace />,
element: <Outlet />,
errorElement: <Navigate to={ROUTE.main} replace />,
loader: checkToken,
children: [
{
index: true,
element: <Mode />,
loader: getUser,
path: ROUTE.tutorial,
element: <Tutorial />,
},
{
path: ROUTE.home,
element: <Home />,
},
{
path: ROUTE.play,
errorElement: <Navigate to={`${ROUTE.error}/401`} replace />,
children: [
{
index: true,
element: <Mode />,
},
{
path: `${ROUTE.lobby}/:roomId`,
element: <LobbyPage />,
loader: ({ params }) => getLobbyInfo(params.roomId),
},
{
path: ROUTE.finder,
element: <Finder />,
loader: () => getRoomList(1),
},
],
},
{
path: `${ROUTE.lobby}/:roomId`,
element: <Lobby />,
loader: ({ params }) => getLobbyInfo(params.roomId),
path: ROUTE.ranking,
element: <Ranking />,
loader: getRank,
},
{
path: `${ROUTE.finder}`,
element: <Finder />,
loader: () => getRoomList(1),
path: ROUTE.result,
element: <Result />,
errorElement: <Navigate to={ROUTE.home} />,
loader: getGameResult,
},
{
path: `${ROUTE.game}`,
element: <Game />,
path: ROUTE.setting,
element: <Settings />,
},
{
path: ROUTE.collection,
element: <Collection />,
},
],
},
{
path: `${ROUTE.ranking}`,
element: <Ranking />,
loader: getRank,
},
{
path: `${ROUTE.result}`,
element: <Result />,
errorElement: <Navigate to={ROUTE.home} />,
loader: getGameResult,
path: `${ROUTE.error}/:code`,
element: <Error />,
},
{
path: `${ROUTE.setting}`,
element: <Settings />,
},
{
path: `${ROUTE.collection}`,
element: <Collection />,
loader: getUser,
path: '/*',
element: <Navigate to={`${ROUTE.error}/404`} replace />,
},
],
},
{
path: `${ROUTE.error}/:code`,
element: <Error />,
},
{
path: '/*',
element: <Navigate to={`${ROUTE.error}/404`} replace />,
path: ROUTE.game,
element: <Game />,
},
]);

Expand Down
5 changes: 3 additions & 2 deletions src/components/button/ColoredButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import type {
coloredButtonSizeType,
} from '@/components/button/types';

import useEffectSoundStore from "@/states/effect";
import { useEffectSound } from '@/features/sound';

interface Props extends ColorButtonProps {
size: coloredButtonSizeType;
}

const ColoredButton = ({ text, color, size, onClick }: Props) => {
const { playEffectSound } = useEffectSoundStore();
const { playEffectSound } = useEffectSound();

const handleClick = () => {
playEffectSound();
Expand Down
4 changes: 2 additions & 2 deletions src/components/button/ColoredIconButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type {
coloredIconButtonSizeType,
} from '@/components/button/types';

import useEffectSoundStore from "@/states/effect";
import { useEffectSound } from '@/features/sound';

export interface ColoredIconButtonProps extends ColorButtonProps {
icon: string;
Expand All @@ -19,7 +19,7 @@ const ColoredIconButton = ({
size,
onClick,
}: ColoredIconButtonProps) => {
const { playEffectSound } = useEffectSoundStore();
const { playEffectSound } = useEffectSound();

const handleClick = () => {
playEffectSound();
Expand Down
26 changes: 24 additions & 2 deletions src/components/button/SettingNavigationButton/index.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { recipe } from '@vanilla-extract/recipes';
import { sprinkles } from '@/styles/sprinkles.css';
import { vars } from '@/styles/vars.css';

export const positionVariants = {
const position = {
leftTop: {
top: 0,
left: 0,
Expand All @@ -21,6 +21,11 @@ export const positionVariants = {
},
};

const usage = {
frame: {},
modal: {},
};

export const button = recipe({
base: style([
sprinkles({
Expand All @@ -42,6 +47,23 @@ export const button = recipe({
},
]),
variants: {
position: positionVariants,
position,
usage,
},
compoundVariants: [
{
variants: {
position: 'leftTop',
usage: 'frame',
},
style: style({
'@media': {
'screen and (min-height: 463px)': {
top: '-16px',
left: '-16px',
},
},
}),
},
],
});
31 changes: 14 additions & 17 deletions src/components/button/SettingNavigationButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import * as styles from './index.css';
import { type RecipeVariants } from '@vanilla-extract/recipes';

import type { positionType } from '@/components/button/types';
import * as styles from './index.css';

import useEffectSoundStore from "@/states/effect";
import { useEffectSound } from '@/features/sound';

interface Props {
type Props = {
label: string;
onClick: () => void;
position: positionType;
}

const buttonLabel = (label: string, position: positionType) => {
if (position === 'leftTop') {
return `< ${label}`;
}
return `${label} X`;
};
} & RecipeVariants<typeof styles.button>;

const SettingNavigationButton = ({ label, onClick, position }: Props) => {
const { playEffectSound } = useEffectSoundStore();
const SettingNavigationButton = ({
label,
onClick,
position,
usage = 'modal',
}: Props) => {
const { playEffectSound } = useEffectSound();

const handleClick = () => {
playEffectSound();
Expand All @@ -28,10 +25,10 @@ const SettingNavigationButton = ({ label, onClick, position }: Props) => {
return (
<button
type='button'
className={styles.button({ position })}
className={styles.button({ position, usage })}
onClick={handleClick}
>
{buttonLabel(label, position)}
{label}
</button>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/button/SettingTextButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ReactNode } from 'react';

import * as styles from './index.css';

import useEffectSoundStore from '@/states/effect';
import { useEffectSound } from '@/features/sound';

interface Props {
children: ReactNode;
Expand All @@ -16,7 +16,7 @@ const SettingTextButton = ({
onClick,
disabled,
}: Props & styles.ButtonVariantsProps) => {
const { playEffectSound } = useEffectSoundStore();
const { playEffectSound } = useEffectSound();

const handleClick = () => {
playEffectSound();
Expand Down
3 changes: 0 additions & 3 deletions src/components/button/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as constants from './constants';

import { positionVariants } from '@/components/button/SettingNavigationButton/index.css';
import { buttonVariants } from '@/components/button/SettingTextButton/index.css';

type colorType = (typeof constants.BUTTON_COLOR)[number];
Expand All @@ -10,8 +9,6 @@ type coloredButtonSizeType = keyof typeof constants.COLORED_BUTTON_SIZE_PIXEL;
type coloredIconButtonSizeType =
keyof typeof constants.COLORED_ICON_BUTTON_SIZE_PIXEL;

type positionType = keyof typeof positionVariants;

interface ColorButtonProps {
text: string;
color: colorType;
Expand Down
2 changes: 1 addition & 1 deletion src/components/frame/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { vars } from '@/styles/vars.css';

import { IPHONE_14_PRO_MAX, IPHONE_SE } from '@/constants/screen';
import { IPHONE_14_PRO_MAX, IPHONE_SE } from '@/shared/constants';

export const FRAME_STYLE = {
width: {
Expand Down
Loading