Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
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
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
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 }}

✅ 스냅샷 변경 없음
9 changes: 8 additions & 1 deletion .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/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;
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@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 Down Expand Up @@ -84,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
26 changes: 0 additions & 26 deletions src/features/expense-management/ui/MemberExpenses/index.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import styled from 'styled-components';
import Text from '@/shared/ui/Text';

export const MemberExpensesContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -28,28 +27,3 @@ export const ProfileContainer = styled.div`
gap: ${({ theme }) => theme.unit[4]};
flex-shrink: 0;
`;

export const ProfileImg = styled.img`
width: ${({ theme }) => theme.unit[36]};
height: ${({ theme }) => theme.unit[36]};
object-fit: contain;
border-radius: 50%;
`;

export const ProfileWrapper = styled.div`
position: relative; // 부모 요소
display: flex;
align-items: flex-start;
justify-content: flex-end;
`;

export const DeleteButtonWrapper = styled.div`
position: absolute; // 자식 요소
width: fit-content;
height: fit-content;
`;

/* 이름 */
export const NameText = styled(Text)`
white-space: nowrap;
`;
21 changes: 8 additions & 13 deletions src/features/expense-management/ui/MemberExpenses/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SystemDanger } from '@/shared/assets/svgs/icon';
import NumberInput from '@/features/expense-management/ui/NumberInput';
import { ExpenseFormMember } from '@/entities/expense/model/expense.type';
import MemberProfile from '@/shared/ui/MemberProfile';
import * as S from './index.styles';

interface MemberExpensesProps {
Expand All @@ -14,18 +14,13 @@ function MemberExpenses({ members, onDelete }: MemberExpensesProps) {
{members.map((member) => (
<S.MemberContainer key={member.id}>
<S.ProfileContainer>
<S.ProfileWrapper>
<S.ProfileImg
src={member.profile}
alt={`${member.name} 프로필 이미지`}
/>
{members.length > 1 ? (
<S.DeleteButtonWrapper onClick={() => onDelete(member.name)}>
<SystemDanger width="0.83331rem" />
</S.DeleteButtonWrapper>
) : null}
</S.ProfileWrapper>
<S.NameText variant="caption">{member.name}</S.NameText>
<MemberProfile
id={member.id}
name={member.name}
profile={member.profile}
canDelete
handleDeleteButtonClick={() => onDelete(member.name)}
/>
</S.ProfileContainer>
<NumberInput
value={member.amount ? member.amount.toLocaleString() : ''}
Expand Down
21 changes: 21 additions & 0 deletions src/pages/addAccountStep/ui/BankNameDrawer/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Meta, StoryObj } from '@storybook/react';
import BankNameDrawer from './index';

const meta: Meta<typeof BankNameDrawer> = {
title: 'ui/BankNameDrawer',
component: BankNameDrawer,
parameters: {
chromatic: { disableSnapshot: false },
},
};

export default meta;
type Story = StoryObj<typeof BankNameDrawer>;

export const Default: Story = {
args: {
open: true,
onClose: () => {},
setBankName: () => {},
},
};
2 changes: 1 addition & 1 deletion src/pages/addAccountStep/ui/BankNameDrawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function BankNameDrawer({ open, onClose, setBankName }: BankNameDrawerProps) {
<Flex
direction="column"
pt={32}
px={5}
px={20}
height="70dvh"
borderRadius={12}
width="100%"
Expand Down
1 change: 1 addition & 0 deletions src/pages/billDetail/ui/CurvedProgressBar/index.style.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled from 'styled-components';

export const Wrapper = styled.div`
margin-top: ${({ theme }) => theme.unit[20]};
display: flex;
justify-content: center;
align-items: center;
Expand Down
6 changes: 0 additions & 6 deletions src/pages/billDetail/ui/ExpenseMemberItem/index.style.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import styled from 'styled-components';
import Accordion from '@/shared/ui/Accordion';
import { ProfileImg as MemberProfileImg } from '@/shared/ui/MemberProfile/index.style';

export const Container = styled(Accordion)<{ isPaid: boolean }>`
padding: ${({ theme }) => theme.unit[20]};
Expand Down Expand Up @@ -30,11 +29,6 @@ export const LeftWrapper = styled.div`
gap: ${({ theme }) => theme.unit[8]};
`;

export const ProfileImg = styled(MemberProfileImg)`
width: ${({ theme }) => theme.unit[48]};
height: ${({ theme }) => theme.unit[48]};
`;

export const SubProfileWrapper = styled.div`
display: flex;
flex-direction: column;
Expand Down
3 changes: 2 additions & 1 deletion src/pages/billDetail/ui/ExpenseMemberItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Close, Confirm, Receipt } from '@/shared/assets/svgs/icon';
import BottomSheet from '@/shared/ui/BottomSheet';
import { MemberSettlement } from '@/entities/settlement/model/settlement.type';
import useUpdatePaymentStatus from '@/features/settlement-details/api/useUpdatePaymentStatus';
import MemberProfileImage from '@/shared/ui/MemberProfileImage';
import * as S from './index.style';
import StatusChip from './ui/StatusChip';

Expand Down Expand Up @@ -64,7 +65,7 @@ function ExpenseMemberItem({
<S.HeaderContainer iconSize={32}>
<S.HeaderContent>
<S.LeftWrapper>
<S.ProfileImg src={member.profile} alt="profile" />
<MemberProfileImage src={member.profile} size="md" />
<S.SubProfileWrapper>
<Text variant="body1Sb">
<span style={{ color: theme.color.primitive.gray[500] }}>
Expand Down
71 changes: 71 additions & 0 deletions src/pages/billDetail/ui/ExpenseTimeHeader/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Meta, StoryObj } from '@storybook/react';
import { waitFor, within } from '@storybook/test';
import { createMemoryRouter, RouterProvider } from 'react-router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { http, HttpResponse } from 'msw';
import ExpenseTimeHeader from './index';

/**
* NOTE
* Flex 컴포넌트의 gap / padding 관련 변경에 대비해서
* 스냅샷 기준을 만들기 위해 추가한 스토리입니다.
*
* 나중에 유지보수가 과도해질 경우 삭제해도 괜찮습니다.
*/

const queryClient = new QueryClient();

const meta: Meta<typeof ExpenseTimeHeader> = {
title: 'ui/ExpenseTimeHeader',
component: ExpenseTimeHeader,
parameters: {
chromatic: { disableSnapshot: false },
msw: {
handlers: [
http.get('http://localhost:3000/api/v1/group/header', () => {
return HttpResponse.json({
groupName: '모또 정기모임',
totalAmount: 150000,
deadline: '2025-12-26T23:59:59Z',
bank: '국민은행',
accountNumber: '123456-78-910111',
});
}),
],
},
},
decorators: [
(Story) => {
const mockRouter = createMemoryRouter([
{
path: '/*',
element: <Story />,
loader: () => ({ groupToken: 'mock-group-token' }),
},
]);
return (
<QueryClientProvider client={queryClient}>
<RouterProvider router={mockRouter} />
</QueryClientProvider>
);
},
],
};

export default meta;
type Story = StoryObj<typeof ExpenseTimeHeader>;

export const Default: Story = {
args: {
totalMember: 6,
paidMember: 3,
status: 'success',
isChecked: false,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await waitFor(() => {
canvas.getByText('정산을 완료해주세요');
});
},
};
9 changes: 7 additions & 2 deletions src/pages/billDetail/ui/ExpenseTimeHeader/index.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ export const ModdoImage = styled.img`
export const ExpenseChip = styled.div`
display: flex;
background: ${({ theme }) => theme.color.semantic.primary.default};
color: ${({ theme }) => theme.color.semantic.text.inverse};
border-radius: ${({ theme }) => theme.radius.circle};
padding: ${({ theme }) => `${theme.unit[12]} ${theme.unit[20]}`};
font-size: ${TextVariant('body1Sb')};
`;

export const TotalMoney = styled.span`
Expand All @@ -56,6 +54,13 @@ export const TimeBox = styled.div`
align-items: center;
`;

export const Timer = styled.div`
display: grid;
width: 174px;
grid-template-columns: repeat(5, auto);
place-items: center;
`;

export const TimeSep = styled.span`
color: ${({ theme }) => theme.color.semantic.secondary.strong};
font-size: 1.75rem;
Expand Down
Loading
Loading