diff --git a/src/components/HighLightCard/index.tsx b/src/components/HighLightCard/index.tsx index fa39472..96059d3 100644 --- a/src/components/HighLightCard/index.tsx +++ b/src/components/HighLightCard/index.tsx @@ -4,8 +4,8 @@ import { FiDollarSign, } from 'react-icons/fi' import { VariantProps, tv } from 'tailwind-variants' -import { PeriodBalanceProps } from '../../dto/transactions' -import { dateFormatter, priceFormatter } from '../../utils/formatter' +import { priceFormatter } from '../../utils/formatter' +import { PeriodBalanceFormattedType } from '../../dto/transactions' const highLightCard = tv({ slots: { @@ -41,7 +41,7 @@ const highLightCard = tv({ type HighLightCardProps = VariantProps & { value: number lastDate?: string - period?: PeriodBalanceProps + period?: PeriodBalanceFormattedType } export function HighLightCard({ @@ -87,18 +87,14 @@ export function HighLightCard({ {valueFormatted} {lastDate && ( - <> - {`${title[titleVariant].lastDateInitial}${lastDate}`} - + {`${title[titleVariant].lastDateInitial}${lastDate}`} )} {period && ( {`${dateFormatter.format( - new Date(period.initial), - )} - ${dateFormatter.format(new Date(period.final))}`} + >{`${period.initial} - ${period.final}`} )} diff --git a/src/context/transactions/index.tsx b/src/context/transactions/index.tsx index d309e08..d0861a4 100644 --- a/src/context/transactions/index.tsx +++ b/src/context/transactions/index.tsx @@ -4,15 +4,24 @@ import React, { useEffect, useMemo, useReducer, + useState, // useState, } from 'react' // import { api } from '../../server/api' +import { transactionsReducer } from '../../reducers/transactions/reducer' +import { + dateFormatter, + dateFormatterMedium, + periodBetweenDatesFormatted, +} from '../../utils/formatter' +import { getAllTransactions } from '../../storage/transactions/getAllTransactions' +import { registerAllTransactions } from '../../storage/transactions/registerAllTransactions' + import { ITransactions, - PeriodBalanceProps, + PeriodBalanceFormattedType, TRANSACTIONS_REDUCER_INITIAL_STATE, } from '../../dto/transactions' -import { transactionsReducer } from '../../reducers/transactions/reducer' import { addTransaction, calculateBalance, @@ -24,20 +33,11 @@ import { // loadTransactions, removeTransactionById, } from '../../reducers/transactions/actions' -import { dateFormatterMedium } from '../../utils/formatter' -import { - differenceInDays, - differenceInMonths, - differenceInYears, -} from 'date-fns' -import { getAllTransactions } from '../../storage/transactions/getAllTransactions' -import { registerAllTransactions } from '../../storage/transactions/registerAllTransactions' -type PeriodBalanceFormattedProps = { +export type PeriodBalanceFormattedProps = { period: string - dates: PeriodBalanceProps + dates: PeriodBalanceFormattedType } - // type IsDeleteTransactionLoadingProps = { // id: string // value: boolean @@ -76,6 +76,12 @@ function TransactionsProvider({ // INITIAL_IS_DELETE_TRANSACTION_LOADING_VALUE, // ) // const [isAddTransactionLoading, setIsAddTransactionLoading] = useState(false) + // const [lastIncomeAndOutcomeTransaction, setLastIncomeAndOutcomeTransaction] = + // useState( + // {} as LastIncomeAndOutcomeTransactionProps, + // ) + const [periodBalanceFormatted, setPeriodBalanceFormatted] = + useState({} as PeriodBalanceFormattedProps) const [transactionsState, dispatch] = useReducer( transactionsReducer, @@ -110,50 +116,29 @@ function TransactionsProvider({ : '' }, [lastOutcomeTransaction]) - const periodBalanceFormatted = useMemo(() => { + function calculatePeriodBalanceFormatted() { if (periodBalance) { const { initial, final } = periodBalance const start = new Date(initial) const end = new Date(final) - const diffInDays = differenceInDays(end, start) - const diffInMonths = differenceInMonths(end, start) - const diffInYears = differenceInYears(end, start) - - let result = '' + const period = periodBetweenDatesFormatted({ + startDate: start, + endDate: end, + }) - if (diffInYears > 0) { - result += `${diffInYears} ano${diffInYears > 1 ? 's' : ''}` - } - - if (diffInMonths > 0) { - if (result.length > 0) { - result += `, ` - } - result += `${diffInMonths} m${diffInMonths > 1 ? 'eses' : 'ês'}` - } - - if (diffInDays > 0) { - if (result.length > 0) { - result += ` e ` - } - result += `${diffInDays} dia${diffInDays > 1 ? 's' : ''}` - } - - result = result.length > 0 ? result : '0 dias' + const initialDateFormatted = dateFormatter.format(start) + const finalDateFormatted = dateFormatter.format(end) - return { - period: result, + setPeriodBalanceFormatted({ + period, dates: { - initial: start, - final: end, + initial: initialDateFormatted, + final: finalDateFormatted, }, - } as unknown as PeriodBalanceFormattedProps - // 1 ano e 2 meses + }) } - - return undefined - }, [periodBalance]) + } const handleAddNewTransaction = useCallback((transaction: ITransactions) => { dispatch(addTransaction(transaction)) @@ -199,6 +184,11 @@ function TransactionsProvider({ registerAllTransactions(transactions) }, [transactions]) + useEffect(() => { + calculatePeriodBalanceFormatted() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [periodBalance]) + const contextValue = useMemo( () => ({ balance, diff --git a/src/dto/transactions.ts b/src/dto/transactions.ts index fc621f4..0d7f061 100644 --- a/src/dto/transactions.ts +++ b/src/dto/transactions.ts @@ -21,6 +21,11 @@ export type PeriodBalanceProps = { final: Date } +export type PeriodBalanceFormattedType = { + initial: string + final: string +} + export type TransactionsState = { transactions: ITransactions[] incomeTotal: number diff --git a/src/reducers/transactions/reducer.ts b/src/reducers/transactions/reducer.ts index a211375..2819cf7 100644 --- a/src/reducers/transactions/reducer.ts +++ b/src/reducers/transactions/reducer.ts @@ -1,6 +1,7 @@ import { produce } from 'immer' import { ActionTypes, IActions } from './actions' import { TRANSACTION_TYPE, TransactionsState } from '../../dto/transactions' +import { isAfter, isBefore } from 'date-fns' function transactionsReducer(state: TransactionsState, action: IActions) { switch (action.type) { @@ -46,22 +47,39 @@ function transactionsReducer(state: TransactionsState, action: IActions) { case ActionTypes.GET_LAST_INCOME_TRANSACTION: return produce(state, (draft) => { draft.lastIncomeTransaction = draft.transactions.reduce( - (accumulator, transaction) => - transaction.type === TRANSACTION_TYPE.income && - transaction.date > accumulator.date + (accumulator, transaction) => { + const isIncomeTransaction = + transaction.type === TRANSACTION_TYPE.income + + const isCurrentTransactionAfterAccumulatorTransaction = isAfter( + transaction.date, + accumulator.date, + ) + return isIncomeTransaction && + isCurrentTransactionAfterAccumulatorTransaction ? transaction - : accumulator, + : accumulator + }, draft.transactions[0], ) }) + case ActionTypes.GET_LAST_OUTCOME_TRANSACTION: return produce(state, (draft) => { draft.lastOutcomeTransaction = draft.transactions.reduce( - (accumulator, transaction) => - transaction.type === TRANSACTION_TYPE.outcome && - transaction.date > accumulator.date + (accumulator, transaction) => { + const isOutcomeTransaction = + transaction.type === TRANSACTION_TYPE.outcome + + const isCurrentTransactionAfterAccumulatorTransaction = isAfter( + transaction.date, + accumulator.date, + ) + return isOutcomeTransaction && + isCurrentTransactionAfterAccumulatorTransaction ? transaction - : accumulator, + : accumulator + }, draft.transactions[0], ) }) @@ -71,19 +89,23 @@ function transactionsReducer(state: TransactionsState, action: IActions) { draft.transactions.length > 0 ? { initial: draft.transactions.reduce( - (accumulator, transaction) => - transaction.date < accumulator + (accumulator, transaction) => { + const isCurrentTransactionBeforeAccumulatorTransaction = + isBefore(transaction.date, accumulator) + return isCurrentTransactionBeforeAccumulatorTransaction ? transaction.date - : accumulator, - draft.transactions[0].date, - ), - final: draft.transactions.reduce( - (accumulator, transaction) => - transaction.date > accumulator - ? transaction.date - : accumulator, + : accumulator + }, draft.transactions[0].date, ), + final: draft.transactions.reduce((accumulator, transaction) => { + const isCurrentTransactionAfterAccumulatorTransaction = + isAfter(transaction.date, accumulator) + + return isCurrentTransactionAfterAccumulatorTransaction + ? transaction.date + : accumulator + }, draft.transactions[0].date), } : undefined }) diff --git a/src/utils/formatter.ts b/src/utils/formatter.ts index c15cd89..b6b6d39 100644 --- a/src/utils/formatter.ts +++ b/src/utils/formatter.ts @@ -1,3 +1,6 @@ +import { ptBR } from 'date-fns/locale' +import { formatDistance } from 'date-fns' + const dateFormatter = new Intl.DateTimeFormat('pt-BR') const dateFormatterMedium = new Intl.DateTimeFormat('pt-BR', { @@ -10,4 +13,26 @@ const priceFormatter = new Intl.NumberFormat('pt-BR', { style: 'currency', }) -export { dateFormatter, dateFormatterMedium, priceFormatter } +type PeriodBetweenDatesProps = { + startDate: Date + endDate: Date +} + +const periodBetweenDatesFormatted = ({ + startDate, + endDate, +}: PeriodBetweenDatesProps): string => { + const period = formatDistance(startDate, endDate, { + addSuffix: true, + locale: ptBR, + }) + + return period +} + +export { + dateFormatter, + dateFormatterMedium, + priceFormatter, + periodBetweenDatesFormatted, +}