diff --git a/fe/src/components/atoms/Input/index.tsx b/fe/src/components/atoms/Input/index.tsx index 57a149d7..3e070c8b 100644 --- a/fe/src/components/atoms/Input/index.tsx +++ b/fe/src/components/atoms/Input/index.tsx @@ -26,8 +26,6 @@ const Input = ({ inputRef, ...props }: Props): React.ReactElement => { - console.log({ ...props }); - return ( = ({ }): React.ReactElement => { return ( - {`${value.toLocaleString()}원`} + {value === 0 ? '' : `${value.toLocaleString()}원`} ); }; diff --git a/fe/src/components/molecules/DateMoneyHeader/index.stories.tsx b/fe/src/components/molecules/DateMoneyHeader/index.stories.tsx index 33d5340c..91ad05bc 100644 --- a/fe/src/components/molecules/DateMoneyHeader/index.stories.tsx +++ b/fe/src/components/molecules/DateMoneyHeader/index.stories.tsx @@ -11,10 +11,18 @@ export default { export const DateMoneyHeaderSample = () => { const date = new Date(); const value = 1000000; - + const income = 400000; + const expense = 560000; + const unclassified = 0; return ( - + ); }; diff --git a/fe/src/components/molecules/DateMoneyHeader/index.tsx b/fe/src/components/molecules/DateMoneyHeader/index.tsx index 0d7cad24..f66efb7e 100644 --- a/fe/src/components/molecules/DateMoneyHeader/index.tsx +++ b/fe/src/components/molecules/DateMoneyHeader/index.tsx @@ -1,17 +1,31 @@ import React from 'react'; -import PriceTag from 'components/atoms/PriceTag'; +import PriceWithSign from 'components/molecules/PriceWithSign'; +import { categoryType } from 'stores/Category'; import { DateMoneyHeaderStyle, ReducedDate } from './style'; export interface Props { date: Date; totalPayment: number; + unclassified: number; + income: number; + expense: number; } -const DateMoneyHeader = ({ date, totalPayment, ...props }: Props) => { +const DateMoneyHeader = ({ + date, + totalPayment, + unclassified, + income, + expense, + ...props +}: Props) => { return ( - +
+ + +
); }; diff --git a/fe/src/components/molecules/DateMoneyHeader/style.ts b/fe/src/components/molecules/DateMoneyHeader/style.ts index 546d0e5f..bf7a67f9 100644 --- a/fe/src/components/molecules/DateMoneyHeader/style.ts +++ b/fe/src/components/molecules/DateMoneyHeader/style.ts @@ -16,4 +16,8 @@ export const ReducedDate = styled(DateAtom)` export const DateMoneyHeaderStyle = styled.div` display: flex; justify-content: space-between; + .price-container { + display: flex; + align-items: center; + } `; diff --git a/fe/src/components/molecules/PriceWithSign/index.tsx b/fe/src/components/molecules/PriceWithSign/index.tsx new file mode 100644 index 00000000..4f04a364 --- /dev/null +++ b/fe/src/components/molecules/PriceWithSign/index.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { categoryType } from 'stores/Category'; +import PriceTag, { Props } from 'components/atoms/PriceTag'; +import * as S from './style'; + +export interface Prop extends Omit { + price: number; + type: string; +} +const getPriceColor = (type: string) => { + switch (type) { + case categoryType.EXPENSE: + return 'red'; + case categoryType.INCOME: + return 'brandColor'; + default: + return 'black'; + } +}; +const getSigin = ({ type, price }: { type: string; price: number }) => { + if (price === 0) return ''; + switch (type) { + case categoryType.EXPENSE: + return '-'; + case categoryType.INCOME: + return '+'; + default: + return ''; + } +}; +const PriceWithSign = ({ price, type, ...props }: Prop) => { + const color = getPriceColor(type); + const sign = getSigin({ type, price }); + return ( + + {sign} + + + ); +}; +export default PriceWithSign; diff --git a/fe/src/components/molecules/PriceWithSign/style.ts b/fe/src/components/molecules/PriceWithSign/style.ts new file mode 100644 index 00000000..835ef257 --- /dev/null +++ b/fe/src/components/molecules/PriceWithSign/style.ts @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +export interface IPrice { + color: string; + theme: { + [propName: string]: any; + }; +} +export const Price = styled.div` + display: flex; + align-items: center; + color: ${({ theme, color }) => theme.color[color]}; + & + & { + margin-left: 0.5em; + } +`; diff --git a/fe/src/components/molecules/Transaction/index.tsx b/fe/src/components/molecules/Transaction/index.tsx index a1449932..e702775d 100644 --- a/fe/src/components/molecules/Transaction/index.tsx +++ b/fe/src/components/molecules/Transaction/index.tsx @@ -1,5 +1,6 @@ import React from 'react'; import doubleArrowIcon from 'assets/svg/doubleArrow.svg'; +import PriceWithSign from 'components/molecules/PriceWithSign'; import * as S from './style'; export interface Props { @@ -9,6 +10,8 @@ export interface Props { const Transaction = ({ trans, onClick }: Props) => { const classificationString = `${trans.category} | ${trans.method}`; + const type = trans.categoryType; + return ( onClick(trans.id)}> @@ -17,7 +20,7 @@ const Transaction = ({ trans, onClick }: Props) => { {trans.client} {classificationString} - + ); diff --git a/fe/src/components/molecules/Transaction/style.ts b/fe/src/components/molecules/Transaction/style.ts index 224ad227..922c4c3f 100644 --- a/fe/src/components/molecules/Transaction/style.ts +++ b/fe/src/components/molecules/Transaction/style.ts @@ -1,6 +1,5 @@ import styled from 'styled-components'; import Icon from 'components/atoms/Icons'; -import PriceTag from 'components/atoms/PriceTag'; export const TransactionStyle = styled.div` box-sizing: border-box; @@ -33,7 +32,3 @@ export const Classification = styled.div` margin-top: 0.5em; color: ${({ theme }) => theme.color.subText}; `; - -export const Price = styled(PriceTag)` - margin-left: 0.5rem; -`; diff --git a/fe/src/components/organisms/TransactionList/index.tsx b/fe/src/components/organisms/TransactionList/index.tsx index 0fd0b420..75e7c6c5 100644 --- a/fe/src/components/organisms/TransactionList/index.tsx +++ b/fe/src/components/organisms/TransactionList/index.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { categoryConvertBig2Small as convert } from 'stores/Category'; import * as S from './style'; export interface Props { @@ -10,6 +11,9 @@ export interface Props { interface accType { transList: JSX.Element[]; totalPrice: number; + income: number; + expense: number; + unclassified: number; } const TransactionList = ({ date, transactionList, onClick }: Props) => { @@ -22,20 +26,33 @@ const TransactionList = ({ date, transactionList, onClick }: Props) => { />, ); acc.totalPrice += transEl.price; + acc[convert(transEl.categoryType)] = transEl.price; return acc; }; - const { transList, totalPrice } = transactionList.reduce( - reduceTransactionList, - { - transList: [], - totalPrice: 0, - }, - ); + const { + transList, + totalPrice, + income, + expense, + unclassified, + } = transactionList.reduce(reduceTransactionList, { + transList: [], + totalPrice: 0, + income: 0, + expense: 0, + unclassified: 0, + }); return ( - + {transList} ); diff --git a/fe/src/stores/Category/index.ts b/fe/src/stores/Category/index.ts index d9285528..754e27a3 100644 --- a/fe/src/stores/Category/index.ts +++ b/fe/src/stores/Category/index.ts @@ -57,7 +57,7 @@ const categoryConverter = (input: string): string => { return categoryType.UNCLASSIFIED; } }; -export const categoryConvertBig2Small = (input: string): string => { +export const categoryConvertBig2Small = (input: string) => { switch (input) { case categoryType.EXPENSE: case 'expense': diff --git a/fe/src/stores/Transaction/index.ts b/fe/src/stores/Transaction/index.ts index 461c9419..ccf5a671 100644 --- a/fe/src/stores/Transaction/index.ts +++ b/fe/src/stores/Transaction/index.ts @@ -158,10 +158,9 @@ export const TransactionStore = makeAutoObservable({ return calTotalPriceByDateAndType(this.transactions, categoryType.EXPENSE); }, get totalPrices(): { income: number; expense: number } { - if (this.isFiltered) { - return sumAllPricesByType(this.filteredTransactionList); - } - return calTotalPrices(this.getTransactions()); + return this.isFiltered + ? sumAllPricesByType(this.filteredTransactionList) + : calTotalPrices(this.getTransactions()); }, get filteredTransactionList(): types.TransactionDBType[] { if (!this.isFiltered) return []; diff --git a/fe/src/stores/Transaction/transactionStoreUtils.ts b/fe/src/stores/Transaction/transactionStoreUtils.ts index 4c4a72ec..660d2ade 100644 --- a/fe/src/stores/Transaction/transactionStoreUtils.ts +++ b/fe/src/stores/Transaction/transactionStoreUtils.ts @@ -1,18 +1,18 @@ import math from 'utils/math'; import { IDateTotalprice, TransactionDBType, IDateTransactionObj } from 'types'; import { TransactionStore } from 'stores/Transaction'; -import { categoryConvertBig2Small, categoryType } from 'stores/Category'; +import { categoryConvertBig2Small } from 'stores/Category'; import dateUtil from 'utils/date'; export const initTotalPrice = { income: 0, expense: 0, + unclassified: 0, }; export const sumAllPricesByType = (transactions: TransactionDBType[]) => { return transactions.reduce((summedPriceByType, transaction) => { - const type = - transaction.category.type === categoryType.INCOME ? 'income' : 'expense'; + const type = categoryConvertBig2Small(transaction.category.type); return { ...summedPriceByType, [type]: summedPriceByType[type] + transaction.price, @@ -48,6 +48,7 @@ export const convertTransactionDBTypetoTransactionType = (input: any[]) => { id: _id, category: category.title, method: method.title, + categoryType: category.type, }, ]; }, []); @@ -55,11 +56,12 @@ export const convertTransactionDBTypetoTransactionType = (input: any[]) => { export const calTotalPrices = (list: IDateTransactionObj) => { return Object.values(list).reduce( - (acc: { income: number; expense: number }, transactions) => { + (acc, transactions) => { const summedPrices = sumAllPricesByType(transactions); return { income: acc.income + summedPrices.income, expense: acc.expense + summedPrices.expense, + unclassified: acc.unclassified + summedPrices.unclassified, }; }, initTotalPrice,