Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
ad6cb44
refactor: FSD 전환 1단계 - 페이지 단위로 코드 분리하기
yoouyeon Sep 14, 2025
b581f76
refactor: FSD 전환 2단계 - 페이지 외부 코드를 분리하기
yoouyeon Sep 14, 2025
22db366
refactor: FSD 전환 3단계 - 페이지 간의 cross-imports 해결
yoouyeon Sep 14, 2025
e431d6a
refactor: FSD 전환 3단계 - 페이지 간의 cross-imports 해결
yoouyeon Sep 14, 2025
971bee7
refactor: FSD 전환 3단계 - 페이지 간의 cross-imports 해결
yoouyeon Sep 14, 2025
b2a8c36
refactor: FSD 전환 3단계 - 페이지 간의 cross-imports 해결
yoouyeon Sep 14, 2025
6580d95
refactor: FSD 전환 4단계 - Shared 레이어 정리하기
yoouyeon Sep 14, 2025
cdc36f0
refactor: FSD 전환 5단계 - 기술적 목적별 segment 정리
yoouyeon Sep 14, 2025
5bf916c
refactor: FSD 전환 5단계 - 기술적 목적별 segment 정리
yoouyeon Sep 14, 2025
a9abd7c
style: fsd lint 설정
yoouyeon Sep 14, 2025
8f879ba
refactor: FSD 전환 6단계 - 여러 페이지에서 재사용되는 기능을 domains layer로 분리하기
yoouyeon Sep 14, 2025
185a457
refactor: FSD 전환 - domain 디렉토리 제거와 shared 디렉토리 가볍게 만들기
yoouyeon Sep 21, 2025
b927c9f
refactor: FSD 전환 - pages 디렉토리 가볍게 만들기
yoouyeon Sep 21, 2025
473b4ac
refactor: FSD 전환 - tanstack query 훅들을 features 안으로 이동
yoouyeon Sep 21, 2025
ad9e433
refactor: FSD 전환 - settlement 타입 정리
yoouyeon Sep 21, 2025
c7f49ed
chore: svgr 경로 수정
yoouyeon Sep 21, 2025
739f485
merge: 경로·모듈 구조 재구성 및 라우터·설정 갱신 (#7)
yoouyeon Nov 8, 2025
7051d89
refactor: 인라인 스타일 제거
yoouyeon Dec 26, 2025
aaa6a57
chore: Storybook preview에서 Chromatic 스냅샷 기본 비활성화
yoouyeon Dec 26, 2025
5f7810f
chore: Storybook MSW 애드온 추가
yoouyeon Dec 27, 2025
ecb7743
refactor: 로그인 페이지 진입용 LoginEntranceView 컴포넌트 분리
yoouyeon Dec 27, 2025
0648d54
chore: guest·group 토큰 API에 useMock 옵션 추가
yoouyeon Dec 27, 2025
04f2861
chore: Storybook 8.6.12로 업데이트
yoouyeon Dec 27, 2025
20f17ac
test: Flex 프로퍼티 변경 전 스냅샷 기준용 Storybook 스토리 추가
yoouyeon Dec 27, 2025
64e78e7
chore: Chromatic 스냅샷 변경에 따른 PR 코멘트 로직 개선
yoouyeon Dec 27, 2025
97eb452
fix: 패딩 단위를 디자인 시스템 기준으로 수정
yoouyeon Dec 27, 2025
7127074
feat: Text 컴포넌트에 style prop 추가
yoouyeon Dec 27, 2025
7634487
style: ExpenseTimeHeader 레이아웃 구조 정리
yoouyeon Dec 27, 2025
30f522d
refactor: AddMember 레이아웃 구조 정리
yoouyeon Dec 27, 2025
8b4b01d
fix: Flex spacing 단위를 디자인 시스템 기준으로 수정
yoouyeon Dec 27, 2025
f45060a
design: HomePage 레이아웃 조정
yoouyeon Dec 27, 2025
2f1bb2b
style: LoginEntranceView gap 단위를 디자인 시스템 기준으로 수정
yoouyeon Dec 28, 2025
67a02d4
style: SelectGroupPage 레이아웃·스타일 정리
yoouyeon Dec 28, 2025
747bddc
docs: Flex 컴포넌트 사용 주석 추가
yoouyeon Dec 28, 2025
3a0c907
fix: width 속성 문법 오류 수정
yoouyeon Dec 28, 2025
43ffd5e
merge: Flex 컴포넌트 gap 단위 불일치 문제 수정 (#12)
yoouyeon Jan 13, 2026
1e2f36e
feat: api 요청 설정 supabase에 맞게 변경
yoouyeon Jan 13, 2026
7378662
chore: CI/CD workflow에 Supabase public key 추가
yoouyeon Jan 13, 2026
39f8568
merge: Supabase 환경 변수와 API 클라이언트 설정 업데이트 (#15)
yoouyeon Jan 13, 2026
918a9f9
design: MemberProfileImage 컴포넌트 추가
yoouyeon Jan 13, 2026
33a9fad
refactor: useMock option 제거
yoouyeon Jan 13, 2026
e971b29
refactor: Member 타입 수정
yoouyeon Jan 13, 2026
4a5b32f
refactor: 지출 생성 페이지에 MemberProfile ui 적용
yoouyeon Jan 13, 2026
5690daa
refactor: 지출 확인 페이지에 MemberProfileImage 컴포넌트 적용
yoouyeon Jan 13, 2026
eebc20a
refactor: Member 타입 재수정 (옵셔널 제거)
yoouyeon Jan 13, 2026
4231dd0
refactor: src props를 옵셔널로 변경
yoouyeon Jan 13, 2026
544e48f
merge: 멤버 프로필 컴포넌트 분리 및 API 개선 (#16)
yoouyeon Jan 13, 2026
03e7956
fix: BankNameDrawer story 에서 누락된 props 추가
yoouyeon Jan 13, 2026
40711a3
fix: endsWith 체크를 쿼리 파라미터를 제외한 경로에서만 하도록 수정
yoouyeon Jan 13, 2026
cdc0d2f
fix: MemberProfile story에 delete button handler 추가
yoouyeon Jan 13, 2026
0fbcf29
merge: Flex 컴포넌트 버그 수정과 프로필 컴포넌트 추가, 그리고 supabase 연결 (#17)
yoouyeon Jan 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 8 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
'airbnb/hooks',
'airbnb-typescript',
'plugin:react/recommended',
// '@feature-sliced',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'plugin:jsx-a11y/recommended', // jsx-a11y 규칙은 웹 접근성을 준수하기 위함
Expand Down Expand Up @@ -102,7 +103,13 @@ module.exports = {
},
overrides: [
{
files: ['.eslintrc.cjs', 'public/**', 'src/assets/svgs/**', '**/*.stories.tsx', '**/*.stories.ts'],
files: [
'.eslintrc.cjs',
'public/**',
'src/shared/assets/**',
'**/*.stories.tsx',
'**/*.stories.ts',
],
parserOptions: {
project: './tsconfig.app.json',
},
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/prod-ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
env:
VITE_SERVER_URL: ${{ secrets.VITE_SERVER_URL }}
VITE_KAKAO_JAVASCRIPT_KEY: ${{ secrets.VITE_KAKAO_JAVASCRIPT_KEY }}
VITE_SUPABASE_PUBLIC_KEY: ${{ secrets.VITE_SUPABASE_PUBLIC_KEY }}
run: yarn build

# Step 7: 빌드 결과물 저장
Expand All @@ -58,7 +59,7 @@ jobs:

cd:
runs-on: ubuntu-latest
if: github.event_name == 'push' # push일 때만 실행
if: github.event_name == 'push' # push일 때만 실행
needs: ci
steps:
# Step 1: AWS 인증
Expand Down
20 changes: 18 additions & 2 deletions .github/workflows/publish-storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,23 @@ jobs:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
onlyChanged: true # Only run Chromatic on changed stories

- name: Comment on PR
- name: Comment on PR (with snapshot changes)
if: steps.chromatic.outputs.changeCount != '0'
uses: thollander/actions-comment-pull-request@v3
with:
message: '✨ **Storybook preview** : ${{ steps.chromatic.outputs.storybookUrl }}'
message: |
✨ Storybook
👉 ${{ steps.chromatic.outputs.storybookUrl }}

📸 변경된 스냅샷
👉 ${{ steps.chromatic.outputs.buildUrl }}

- name: Comment on PR (no snapshot changes)
if: steps.chromatic.outputs.changeCount == '0'
uses: thollander/actions-comment-pull-request@v3
with:
message: |
✨ Storybook
👉 ${{ steps.chromatic.outputs.storybookUrl }}

✅ 스냅샷 변경 없음
6 changes: 5 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
stories: [
'../src/**/*.mdx',
'../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
'./**/*.mdx',
],
addons: [
'storybook-addon-pseudo-states',
'@storybook/addon-onboarding',
Expand Down
13 changes: 10 additions & 3 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import type { Preview } from '@storybook/react';

import { initialize, mswLoader } from 'msw-storybook-addon';
import { ThemeProvider } from 'styled-components';
import { withThemeFromJSXProvider } from '@storybook/addon-themes';
import theme from '../src/styles/theme';
import GlobalStyles from '../src/styles/globalStyles';
import theme from '../src/shared/styles/theme';
import GlobalStyles from '../src/shared/styles/globalStyles';

// Initialize MSW
initialize();

const preview: Preview = {
parameters: {
chromatic: { disableSnapshot: true }, // 기본적으로 Chromatic 스냅샷 비활성화 (필요한 스토리에서만 활성화한다)
controls: {
matchers: {
color: /(background|color)$/i,
Expand All @@ -25,6 +29,9 @@ const preview: Preview = {
GlobalStyles,
}),
],

// Provide the MSW addon loader globally
loaders: [mswLoader],
};

export default preview;
2 changes: 1 addition & 1 deletion src/stories/colors.mdx → .storybook/stories/colors.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Meta, ColorPalette, ColorItem } from '@storybook/blocks';
import theme from '../styles/theme';
import theme from '@/shared/styles/theme';

<Meta title="Design Tokens/Colors" />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Meta, IconGallery, IconItem } from '@storybook/addon-docs';
import theme from '../styles/theme';
import * as Icons from '../assets/svgs/icon';
import theme from '@/shared/styles/theme';
import * as Icons from '@/shared/assets/svgs/icon';

<Meta title="Design Tokens/Icon Gallery" />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Meta } from '@storybook/blocks';
import theme from '../styles/theme';
import theme from '@/shared/styles/theme';

<Meta title="Design Tokens/Units & Border Radius" />

Expand Down
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"build": "tsc -b && vite build",
"lint": "eslint src --ext .js,.jsx,.ts,.tsx",
"preview": "vite preview",
"svgr": "npx @svgr/cli -d src/assets/svgs --typescript --no-dimensions public/svgs",
"svgr": "npx @svgr/cli -d src/shared/assets/svgs/icon --typescript --no-dimensions public/svgs",
"pwa": "pwa-assets-generator --preset minimal public/pwa/moddo.svg",
"storybook": "storybook dev -p 6006",
"build-storybook": "STORYBOOK=true storybook build",
Expand Down Expand Up @@ -48,13 +48,14 @@
},
"devDependencies": {
"@chromatic-com/storybook": "^3.2.4",
"@feature-sliced/eslint-config": "^0.1.1",
"@hookform/devtools": "^4.3.3",
"@storybook/addon-essentials": "^8.5.0",
"@storybook/addon-interactions": "^8.5.0",
"@storybook/addon-onboarding": "^8.5.0",
"@storybook/addon-themes": "^8.5.2",
"@storybook/blocks": "^8.5.0",
"@storybook/react": "^8.5.0",
"@storybook/react": "^8.6.12",
"@storybook/react-vite": "^8.5.0",
"@storybook/test": "^8.5.0",
"@tanstack/eslint-plugin-query": "^5.68.0",
Expand All @@ -73,7 +74,8 @@
"eslint-config-airbnb-typescript": "18.0.0",
"eslint-config-prettier": "10.0.1",
"eslint-import-resolver-typescript": "^3.7.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-boundaries": "^5.0.1",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-react": "7.37.4",
Expand All @@ -82,8 +84,9 @@
"eslint-plugin-storybook": "^0.11.2",
"globals": "^15.14.0",
"msw": "^2.7.0",
"msw-storybook-addon": "^2.0.6",
"prettier": "^3.4.2",
"storybook": "^8.5.0",
"storybook": "^8.6.12",
"storybook-addon-pseudo-states": "^4.0.2",
"typescript": "^5.7.3",
"typescript-eslint": "^8.18.2",
Expand Down
15 changes: 7 additions & 8 deletions src/App.tsx → src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import {
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query';
import GlobalStyles from '@/styles/globalStyles';
import theme from '@/styles/theme';
import Layout from '@/common/components/Layout';
import AppRouter from '@/Router';
import GlobalStyles from '@/shared/styles/globalStyles';
import theme from '@/shared/styles/theme';
import AppRouter from '@/app/Router';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import GlobalErrorBoundary from '@/common/components/GlobalErrorBoundary';
import Toast from '@/common/components/Toast';
import useApiError from '@/common/hooks/useApiError';
import GlobalErrorBoundary from '@/app/GlobalErrorBoundary';
import Toast from '@/shared/ui/Toast';
import useApiError from '@/shared/hooks/useApiError';
import Layout from './Layout';
import 'react-toastify/dist/ReactToastify.css';

function App() {
Expand All @@ -35,7 +35,6 @@ function App() {
}),
})
);

return (
<ThemeProvider theme={theme}>
<GlobalErrorBoundary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ErrorBoundary } from 'react-error-boundary';
import ErrorPage from '@/pages/error';
import { ErrorPage } from '@/pages/error';

interface GlobalErrorBoundaryProps {
children: React.ReactNode;
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
import ErrorPage from '@/pages/error';
import { BoundaryError } from '@/common/types/error.type';
import { ErrorPage } from '@/pages/error';
import { BoundaryError } from '@/shared/types/error.type';

type FallbackPageProps = Omit<FallbackProps, 'error'> & {
error: BoundaryError;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useRouteError } from 'react-router';
import { BoundaryError } from '@/common/types/error.type';
import ErrorPage from '@/pages/error';
import { BoundaryError } from '@/shared/types/error.type';
import { ErrorPage } from '@/pages/error';

function RouteErrorElement() {
const error = useRouteError();
Expand Down
66 changes: 47 additions & 19 deletions src/Router.tsx → src/app/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
import { lazy, Suspense } from 'react';
import { createBrowserRouter, Outlet, RouterProvider } from 'react-router';
import { ROUTE } from '@/common/constants/route';
import { checkAuth, groupTokenUrlLoader } from '@/common/loaders';
import getGroupManagerAuth from '@/common/loaders/getGroupManagerAuth';
import RouteErrorBoundary from '@/common/components/RouteErrorBoundary';
import RouteErrorElement from '@/common/components/RouteErrorElement';
import { ROUTE } from '@/shared/config/route';
import RouteErrorBoundary from '@/app/RouteErrorBoundary';
import RouteErrorElement from '@/app/RouteErrorElement';
import checkAuth from '@/entities/auth/lib/checkAuth';
import getGroupManagerAuth from '@/entities/auth/lib/getGroupManagerAuth';
import groupTokenUrlLoader from '@/entities/auth/lib/groupTokenUrlLoader';

const BillDetail = lazy(() => import('@/pages/billDetail'));
const CharacterShare = lazy(() => import('@/pages/billDetail/characterShare'));
const CreateBill = lazy(() => import('@/pages/createBill'));
const GroupSetup = lazy(() => import('@/pages/groupSetup'));
const Home = lazy(() => import('@/pages/home'));
const Login = lazy(() => import('@/pages/auth/login'));
const LoginSuccess = lazy(() => import('@/pages/auth/loginSuccess'));
const Onboarding = lazy(() => import('@/pages/onboarding'));
const SelectGroup = lazy(() => import('@/pages/selectGroup'));
const NotFound = lazy(() => import('@/pages/notFound'));
const BillDetail = lazy(() =>
import('@/pages/billDetail/').then(({ BillDetailPage }) => ({
default: BillDetailPage,
}))
);
const CharacterShare = lazy(() =>
import('@/pages/characterShare').then(({ CharacterSharePage }) => ({
default: CharacterSharePage,
}))
);
const CreateBill = lazy(() =>
import('@/pages/createBill').then(({ CreateBillPage }) => ({
default: CreateBillPage,
}))
);
const GroupSetup = lazy(() =>
import('@/pages/groupSetup').then(({ GroupSetupPage }) => ({
default: GroupSetupPage,
}))
);
const Home = lazy(() =>
import('@/pages/home').then(({ HomePage }) => ({ default: HomePage }))
);
const Login = lazy(() =>
import('@/pages/login').then(({ LoginPage }) => ({ default: LoginPage }))
);
const Onboarding = lazy(() =>
import('@/pages/onboarding').then(({ OnboardingPage }) => ({
default: OnboardingPage,
}))
);
const SelectGroup = lazy(() =>
import('@/pages/selectGroup').then(({ SelectGroupPage }) => ({
default: SelectGroupPage,
}))
);
const NotFound = lazy(() =>
import('@/pages/notFound').then(({ NotFoundPage }) => ({
default: NotFoundPage,
}))
);

function AppRouter() {
const router = createBrowserRouter([
Expand All @@ -36,10 +68,6 @@ function AppRouter() {
path: ROUTE.onboarding,
element: <Onboarding />,
},
{
path: ROUTE.loginSuccess,
element: <LoginSuccess />,
},
{
path: ROUTE.home,
element: <Home />,
Expand Down
2 changes: 0 additions & 2 deletions src/common/constants/storageKey.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/common/loaders/index.ts

This file was deleted.

18 changes: 0 additions & 18 deletions src/common/utils/getRandomColor.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/service/apis/auth.ts → src/entities/auth/api/auth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axiosInstance from './axios';
import axiosInstance from '@/shared/api/axios';

export interface GuestTokenData {
accessToken: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';
import { ROUTE } from '@/common/constants/route';
import { useNavigate } from 'react-router';
import { getGuestToken } from '@/service/apis/auth';
import { useQuery } from '@tanstack/react-query';
import { ROUTE } from '@/shared/config/route';
import { getGuestToken } from './auth';

export const useGetGuestToken = () => {
const navigate = useNavigate();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { redirect } from 'react-router';
import { ROUTE } from '@/common/constants/route';
import { ROUTE } from '@/shared/config/route';

/**
* 페이지에 접근하기 전에 실행되는 함수
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LoaderFunction, redirect } from 'react-router';
import { ROUTE } from '@/common/constants/route';
import { ROUTE } from '@/shared/config/route';

/** 정산 담당자가 필요한 토큰을 모두 가지고 있는지 확인하는 로더 */
const getGroupManagerAuth: LoaderFunction = async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { LoaderFunction, redirect } from 'react-router';
import { ROUTE } from '@/common/constants/route';
import { getGroupHeader } from '@/service/apis/group';
import { isAxiosError } from 'axios';
import { BoundaryError } from '../types/error.type';
import { LoaderFunction, redirect } from 'react-router';
import { getGroupHeader } from '@/entities/group/api/group';
import { ROUTE } from '@/shared/config/route';
import { BoundaryError } from '@/shared/types/error.type';

const groupTokenUrlLoader: LoaderFunction = async ({ params }) => {
const { groupToken } = params;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CharacterData } from '@/common/types/character';
import axiosInstance from './axios';
import { CharacterData } from '@/entities/character/model/character.type';
import axiosInstance from '@/shared/api/axios';

const image = {
// GET GetCharacter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CharacterType } from '@/common/types/character';
import { CharacterType } from '@/entities/character/model/character.type';

export const CHARACTER_IMAGE_SIZE: Record<
CharacterType,
Expand Down
Loading