Skip to content
Open
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
File renamed without changes.
10 changes: 10 additions & 0 deletions src/app/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ const LazyMyLinks = lazy(() =>
default: MyLinksPage,
}))
);
const LazyPaymentManagement = lazy(() =>
import('@/pages/paymentManagement').then(({ PaymentManagementPage }) => ({
default: PaymentManagementPage,
}))
);
const LazyMyPage = lazy(() =>
import('@/pages/my').then(({ MyPage }) => ({
default: MyPage,
Expand Down Expand Up @@ -97,6 +102,10 @@ function AppRouter() {
path: ROUTE.myEdit,
element: <LazyMyEditPage />,
},
{
path: ROUTE.paymentManagement,
element: <LazyPaymentManagement />,
},
{
path: ROUTE.selectGroup,
element: <LazySelectGroup />,
Expand All @@ -123,6 +132,7 @@ function AppRouter() {
element: <LazyCharacterShare />,
loader: groupTokenUrlLoader,
},

{
path: '*',
element: <LazyNotFound />,
Expand Down
109 changes: 0 additions & 109 deletions src/pages/home/HomePage.style.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,5 @@
import { Link } from 'react-router';
import styled from 'styled-components';

/** @Todo Button 공통 컴포넌트 제작 */
export const Button = styled.button<{ color?: string; bgColor?: string }>`
display: flex;
justify-content: center;
align-items: center;
background-color: ${({ bgColor }) => bgColor || 'black'};
color: ${({ color }) => color || 'white'};
font-weight: 400;
border-radius: 9999px;
padding: 0.5rem 0.75rem; // 8px 12px
height: fit-content;
width: fit-content;
line-height: 1.5;
font-size: 0.875rem; //14px
cursor: pointer;

&:hover {
filter: brightness(0.9);
transition: filter 0.1s;
}
`;

export const SelectGroupButton = styled.button`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.unit[4]};
background: transparent;
color: ${({ theme }) => theme.color.semantic.orange.default};
`;

export const MainHeader = styled.header`
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.25rem; // 20px
width: 100%;
background-color: ${({ theme }) => theme.color.semantic.background.normal};
`;

export const MainText = styled.h2`
font-size: 1.25rem; // 20px
font-weight: 700;
Expand All @@ -52,72 +12,3 @@ export const SubText = styled.p`
white-space: pre-wrap;
line-height: 1.5;
`;

export const DescriptionImg = styled.img`
width: 9.8rem;
object-fit: contain;
position: absolute;
top: 9%;
right: -0.2rem;
rotate: -2deg;
`;

export const Hr = styled.hr`
border: 0.5rem solid #edeeee;
width: 100%;
`;

export const SettlementTitle = styled.h2`
font-size: 1.25rem; // 20px
font-weight: 700;
padding: 0.5rem 1.25rem; // 8px 20px
white-space: nowrap;
`;

export const SettlementButton = styled(Button)<{ selected?: boolean }>`
background-color: ${({ selected, theme }) =>
selected ? theme.color.semantic.primary : '#F1F3F5'};
color: ${({ selected }) => (selected ? 'white' : 'black')};
`;

export const NoSettlementImg = styled.img`
width: 33vw;
max-width: 200px;
object-fit: contain;
`;

export const BoxButton = styled(Link)`
display: flex;
padding: ${({ theme }) => `${theme.unit[16]} ${theme.unit[20]}`};
position: relative;
height: 5rem;
background-color: ${({ theme }) => theme.color.semantic.orange.subtle};
border-radius: ${({ theme }) => theme.radius.default};

width: 100%;
`;

export const SmallImg = styled.img`
width: 2.75rem;
object-fit: contain;
position: absolute;
right: 1rem;
bottom: 0.5rem;
`;

export const BoxButtonWrapper = styled.div`
display: flex;
max-width: 37.5rem;
margin: ${({ theme }) =>
`0 ${theme.unit[20]} ${theme.unit[32]} ${theme.unit[20]}`};
gap: ${({ theme }) => theme.unit[8]};
`;

export const SettlementListWrapper = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.unit[20]};
margin: ${({ theme }) => `${theme.unit[20]} 0`};
overflow-y: auto;
flex: 1;
`;
179 changes: 8 additions & 171 deletions src/pages/home/HomePage.tsx
Copy link
Contributor

Choose a reason for hiding this comment

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

이 파일 안에 홈에서 사용하는 ui 컴포넌트들이 함께 들어가 있는데,
저희 FSD 구조 활용해서 ui 컴포넌트들은 따로 ui 디렉토리나 features 쪽에 만들어서 넣어두고 page에서는 조합하는 형태로 해보기로 했던 걸로 기억하고 있거든요..!
api 코드 추가되면서 코드가 더 복잡해지기 전에 여기서 디렉토리 정리를 먼저 해두면 어떨까 싶습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

아 넵! FSD 구조에 맞게 이동시키겠습니다!

Original file line number Diff line number Diff line change
@@ -1,181 +1,18 @@
import { useTheme } from 'styled-components';
import { LogoIcon } from '@/shared/assets/svgs';
import MainHamImg2 from '@/shared/assets/pngs/MainHamImg2.png';
import Text from '@/shared/ui/Text';
import { ArrowRight, Bell, Menu, Next } from '@/shared/assets/svgs/icon';
import { useNavigate } from 'react-router';
import { ROUTE } from '@/shared/config/route';
import { useState } from 'react';
import CoinImg from '@/shared/assets/pngs/CoinImg.png';
import LinkMain from '@/shared/assets/pngs/link_main.png';
import CardMain from '@/shared/assets/pngs/card_main.png';
import Divider from '@/shared/ui/Divider';
import Flex from '@/shared/ui/Flex';
import HomeExpenseItem from './ui/HomeExpenseItem';
import * as S from './HomePage.style';

interface HomeExpenseItemType {
date: string;
groupName: string;
totalAmount: number;
paidMember: number;
totalMember: number;
id: number;
}
/**
* @Todo 진행중인 정산 내역 조회 API 함수 호출
* 우선 mock data로 대체
* */
const settlementList: HomeExpenseItemType[] = [
{
id: 1,
date: '2025년 2월 22일',
groupName: 'DND 데모데이',
totalAmount: 120000,
paidMember: 3,
totalMember: 6,
},
{
id: 2,
date: '2025년 1월 14일',
groupName: 'DND 7조 첫모임',
totalAmount: 150000,
paidMember: 5,
totalMember: 6,
},
];
import {
MainHeader,
SettlementBanner,
SettlementList,
} from './ui/HomePageSection';

function HomePage() {
const [settlementType, setSettlementType] = useState<'RECEIVE' | 'SEND'>(
'RECEIVE'
);
const navigate = useNavigate();
const theme = useTheme();

const handleSettlementTypeButtonClick = (type: 'RECEIVE' | 'SEND') => {
if (settlementType === type) {
return;
}
setSettlementType(type);
};

return (
<Flex direction="column" flexGrow={1}>
<S.MainHeader>
<LogoIcon
width={98}
height={36}
fill={theme.color.semantic.orange.default}
onClick={() => navigate(ROUTE.login)}
/>
<Flex gap={16}>
<Bell width={24} height={24} />
<Menu width={24} height={24} />
</Flex>
</S.MainHeader>
<Flex
direction="column"
position="relative"
bgColor={theme.color.semantic.primary.default}
height="136px"
borderRadius={theme.radius.default}
margin={20}
px={20}
py={18}
>
<S.SelectGroupButton onClick={() => navigate(ROUTE.selectGroup)}>
<Text variant="heading2">정산하기</Text>
<ArrowRight
width={theme.unit[20]}
height={theme.unit[20]}
fill={theme.color.semantic.orange.default}
/>
</S.SelectGroupButton>
<Text
variant="body2R"
color="semantic.text.inverse"
style={{ display: 'inline-block', marginTop: theme.unit[4] }}
>
모임은 즐겁게, 정산은 깔끔하게!
<br />
모또만 믿고 맡겨줘!
</Text>
<S.DescriptionImg src={MainHamImg2} alt="" />
</Flex>
<S.BoxButtonWrapper>
<S.BoxButton to={ROUTE.myLinks}>
<Text variant="body1Sb" color="semantic.text.default">
링크 관리
</Text>
<S.SmallImg src={LinkMain} alt="" />
</S.BoxButton>
<S.BoxButton to="/">
<Text variant="body1Sb" color="semantic.text.default">
캐릭터 도감
</Text>
<S.SmallImg src={CardMain} alt="" />
</S.BoxButton>
</S.BoxButtonWrapper>
<MainHeader />
<SettlementBanner />
<Divider />
<Flex direction="column" pt={16} flexGrow={1}>
<S.SettlementTitle>진행중인 정산</S.SettlementTitle>
<Flex
justifyContent="space-between"
px={20}
height={48}
alignItems="center"
>
<Flex gap={8}>
<S.SettlementButton
selected={settlementType === 'RECEIVE'}
onClick={() => handleSettlementTypeButtonClick('RECEIVE')}
>
받을 정산
</S.SettlementButton>
<S.SettlementButton
selected={settlementType === 'SEND'}
onClick={() => handleSettlementTypeButtonClick('SEND')}
>
보낼 정산
</S.SettlementButton>
</Flex>
<Flex alignItems="center">
<Text variant="body2R" color="semantic.text.subtle">
최신순
</Text>
<Next width={theme.unit[24]} height={theme.unit[24]} />
</Flex>
</Flex>
{settlementList.length > 0 && settlementType === 'RECEIVE' && (
<S.SettlementListWrapper>
{settlementList.map((data) => (
<HomeExpenseItem
key={data.id}
date={data.date}
groupName={data.groupName}
totalAmount={data.totalAmount}
paidMember={data.paidMember}
totalMember={data.totalMember}
/>
))}
</S.SettlementListWrapper>
)}
{settlementType === 'SEND' && (
<Flex
direction="column"
py={20}
justifyContent="center"
alignItems="center"
flexGrow={1}
gap={20}
>
<S.NoSettlementImg src={CoinImg} alt="" />
<Text variant="body2R" color="semantic.text.subtle">
아직 진행중인 정산이 없어요.
</Text>
</Flex>
)}
</Flex>
<SettlementList />
</Flex>
);
}
Expand Down
Loading