diff --git a/apps/mobile/app/(app)/(tabs)/index.tsx b/apps/mobile/app/(app)/(tabs)/index.tsx index 1e703e9a..a1781529 100644 --- a/apps/mobile/app/(app)/(tabs)/index.tsx +++ b/apps/mobile/app/(app)/(tabs)/index.tsx @@ -2,7 +2,9 @@ import { AmountFormat } from '@/components/common/amount-format' import { ListSkeleton } from '@/components/common/list-skeleton' import { Toolbar } from '@/components/common/toolbar' import { HomeHeader } from '@/components/home/header' -import { WalletStatistics } from '@/components/home/wallet-statistics' +import { HomeFilter } from '@/components/home/select-filter' +import { TimeRangeControl } from '@/components/home/time-range-control' +import { HomeView, WalletStatistics } from '@/components/home/wallet-statistics' import { HandyArrow } from '@/components/transaction/handy-arrow' import { TransactionItem } from '@/components/transaction/transaction-item' import { Text } from '@/components/ui/text' @@ -28,13 +30,30 @@ export default function HomeScreen() { const { colorScheme } = useColorScheme() const [walletAccountId, setWalletAccountId] = useState() const queryClient = useQueryClient() + const [filter, setFilter] = useState(HomeFilter.All) + const [view, setView] = useState(HomeView.SpentThisWeek) + const [customTimeRange, setCustomTimeRange] = useState<{ + from: Date + to: Date + }>({ + from: dayjsExtended().subtract(10, 'year').startOf('year').toDate(), + to: dayjsExtended().add(10, 'year').endOf('year').toDate(), + }) + + const timeRange = useMemo(() => { + if (filter !== HomeFilter.All) { + return customTimeRange + } + return { + from: dayjsExtended().subtract(10, 'year').startOf('year').toDate(), + to: dayjsExtended().add(10, 'year').endOf('year').toDate(), + } + }, [customTimeRange, filter]) const { transactions, isLoading, isRefetching, refetch } = useTransactionList( { walletAccountId, - // FIXME: This should be dynamic @bkdev98 - from: dayjsExtended().subtract(10, 'year').startOf('year').toDate(), - to: dayjsExtended().add(10, 'year').endOf('year').toDate(), + ...timeRange, }, ) @@ -43,6 +62,26 @@ export default function HomeScreen() { queryClient.invalidateQueries({ queryKey: walletQueries.list._def }) } + const handleSetFilter = (filter: HomeFilter) => { + if (filter === HomeFilter.ByDay) { + setCustomTimeRange({ + from: dayjsExtended().startOf('day').toDate(), + to: dayjsExtended().endOf('day').toDate(), + }) + } else if (filter === HomeFilter.ByWeek) { + setCustomTimeRange({ + from: dayjsExtended().startOf('week').toDate(), + to: dayjsExtended().endOf('week').toDate(), + }) + } else if (filter === HomeFilter.ByMonth) { + setCustomTimeRange({ + from: dayjsExtended().startOf('month').toDate(), + to: dayjsExtended().endOf('month').toDate(), + }) + } + setFilter(filter) + } + const transactionsGroupByDate = useMemo(() => { const groupedByDay = groupBy(transactions, (transaction) => format(new Date(transaction.date), 'yyyy-MM-dd'), @@ -52,7 +91,7 @@ export default function HomeScreen() { key, title: formatDateShort(new Date(key)), data: orderBy(transactions, 'date', 'desc'), - sum: sumBy(transactions, 'amount'), + sum: sumBy(transactions, 'amountInVnd'), })) return Object.values(sectionDict) @@ -63,12 +102,27 @@ export default function HomeScreen() { + {filter !== HomeFilter.All && ( + + )} - - + filter === HomeFilter.All ? ( + + + + ) : null } className="flex-1 bg-card" contentContainerStyle={{ paddingBottom: bottom + 32 }} @@ -97,12 +151,26 @@ export default function HomeScreen() { // }} onEndReachedThreshold={0.5} ListFooterComponent={isLoading ? : null} + ListEmptyComponent={ + filter !== HomeFilter.All && !isLoading ? ( + + {t( + i18n, + )`No transactions`} + + ) : null + } + extraData={filter} /> {!transactions.length && !isLoading && ( - - {t(i18n)`Add your first transaction here`} - - + <> + {filter === HomeFilter.All ? ( + + {t(i18n)`Add your first transaction here`} + + + ) : null} + )} + - {formatDateShort(periodConfigs[index].startDate!)} - {' - '} - {formatDateShort(periodConfigs[index].endDate!)} + {formatDateRange( + periodConfigs[index].startDate!, + periodConfigs[index].endDate!, + )} + ) } diff --git a/apps/mobile/components/home/select-filter.tsx b/apps/mobile/components/home/select-filter.tsx new file mode 100644 index 00000000..c6df0782 --- /dev/null +++ b/apps/mobile/components/home/select-filter.tsx @@ -0,0 +1,97 @@ +import { cn } from '@/lib/utils' +import { t } from '@lingui/macro' +import { useLingui } from '@lingui/react' +import { FilterIcon } from 'lucide-react-native' +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectTrigger, + SelectValue, +} from '../ui/select' + +export enum HomeFilter { + All = 'ALL', + ByDay = 'BY_DAY', + ByWeek = 'BY_WEEK', + ByMonth = 'BY_MONTH', +} + +type SelectFilterProps = { + value?: HomeFilter + onSelect?: (type: HomeFilter) => void +} + +export function SelectFilter({ + value = HomeFilter.All, + onSelect, +}: SelectFilterProps) { + const { i18n } = useLingui() + + const options = [ + { + value: HomeFilter.All, + label: t(i18n)`All entries`, + }, + { + value: HomeFilter.ByDay, + label: t(i18n)`By day`, + }, + { + value: HomeFilter.ByWeek, + label: t(i18n)`By week`, + }, + { + value: HomeFilter.ByMonth, + label: t(i18n)`By month`, + }, + ] + + return ( + + ) +} diff --git a/apps/mobile/components/home/time-range-control.tsx b/apps/mobile/components/home/time-range-control.tsx new file mode 100644 index 00000000..153f0805 --- /dev/null +++ b/apps/mobile/components/home/time-range-control.tsx @@ -0,0 +1,84 @@ +import { formatDateRange } from '@/lib/date' +import { cn } from '@/lib/utils' +import { dayjsExtended } from '@6pm/utilities' +import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react-native' +import { View } from 'react-native' +import { Button } from '../ui/button' +import { Text } from '../ui/text' +import { HomeFilter } from './select-filter' + +type TimeRange = { + from: Date + to: Date +} + +export type TimeRangeControlProps = { + filter: HomeFilter + timeRange: TimeRange + onTimeRangeChange: (timeRange: TimeRange) => void + className?: string +} + +export function TimeRangeControl({ + filter, + timeRange, + onTimeRangeChange, + className, +}: TimeRangeControlProps) { + function handlePrevious() { + if (filter === HomeFilter.ByDay) { + onTimeRangeChange({ + from: dayjsExtended(timeRange.from).subtract(1, 'day').toDate(), + to: dayjsExtended(timeRange.to).subtract(1, 'day').toDate(), + }) + } else if (filter === HomeFilter.ByWeek) { + onTimeRangeChange({ + from: dayjsExtended(timeRange.from).subtract(1, 'week').toDate(), + to: dayjsExtended(timeRange.to).subtract(1, 'week').toDate(), + }) + } else if (filter === HomeFilter.ByMonth) { + onTimeRangeChange({ + from: dayjsExtended(timeRange.from).subtract(1, 'month').toDate(), + to: dayjsExtended(timeRange.to).subtract(1, 'month').toDate(), + }) + } + } + + function handleNext() { + if (filter === HomeFilter.ByDay) { + onTimeRangeChange({ + from: dayjsExtended(timeRange.from).add(1, 'day').toDate(), + to: dayjsExtended(timeRange.to).add(1, 'day').toDate(), + }) + } else if (filter === HomeFilter.ByWeek) { + onTimeRangeChange({ + from: dayjsExtended(timeRange.from).add(1, 'week').toDate(), + to: dayjsExtended(timeRange.to).add(1, 'week').toDate(), + }) + } else if (filter === HomeFilter.ByMonth) { + onTimeRangeChange({ + from: dayjsExtended(timeRange.from).add(1, 'month').toDate(), + to: dayjsExtended(timeRange.to).add(1, 'month').toDate(), + }) + } + } + + return ( + + + + {formatDateRange(timeRange.from, timeRange.to)} + + + + ) +} diff --git a/apps/mobile/components/home/wallet-statistics.tsx b/apps/mobile/components/home/wallet-statistics.tsx index e7e36903..04fe7b75 100644 --- a/apps/mobile/components/home/wallet-statistics.tsx +++ b/apps/mobile/components/home/wallet-statistics.tsx @@ -1,24 +1,172 @@ -import { useTransactionStore } from '@/stores/transaction/store' +import { useTransactionList } from '@/stores/transaction/hooks' +import { dayjsExtended } from '@6pm/utilities' import { t } from '@lingui/macro' import { useLingui } from '@lingui/react' -import { Pressable, View } from 'react-native' +import { useMemo } from 'react' +import { View } from 'react-native' import { AmountFormat } from '../common/amount-format' +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectSeparator, + SelectTrigger, +} from '../ui/select' import { Text } from '../ui/text' -export function WalletStatistics() { +export enum HomeView { + SpentThisWeek = 'SPENT_THIS_WEEK', + SpentThisMonth = 'SPENT_THIS_MONTH', + RevenueThisWeek = 'REVENUE_THIS_WEEK', + RevenueThisMonth = 'REVENUE_THIS_MONTH', + CurrentBalance = 'CURRENT_BALANCE', +} + +type WalletStatisticsProps = { + view?: HomeView + onViewChange?: (view: HomeView) => void + walletAccountId?: string +} + +export function WalletStatistics({ + view = HomeView.SpentThisWeek, + onViewChange, + walletAccountId, +}: WalletStatisticsProps) { const { i18n } = useLingui() - const { transactions } = useTransactionStore() - const currentBalance = transactions.reduce((acc, t) => acc + t.amountInVnd, 0) + const timeRange = useMemo(() => { + if (view === HomeView.SpentThisWeek || view === HomeView.RevenueThisWeek) { + return { + from: dayjsExtended().startOf('week').toDate(), + to: dayjsExtended().endOf('week').toDate(), + } + } + + if ( + view === HomeView.SpentThisMonth || + view === HomeView.RevenueThisMonth + ) { + return { + from: dayjsExtended().startOf('month').toDate(), + to: dayjsExtended().endOf('month').toDate(), + } + } + + return { + from: dayjsExtended().subtract(10, 'year').startOf('year').toDate(), + to: dayjsExtended().add(10, 'year').endOf('year').toDate(), + } + }, [view]) + + const { totalExpense, totalIncome } = useTransactionList({ + walletAccountId, + ...timeRange, + }) + + const totalValue = useMemo(() => { + if (view === HomeView.SpentThisWeek || view === HomeView.SpentThisMonth) { + return totalExpense + } + if ( + view === HomeView.RevenueThisWeek || + view === HomeView.RevenueThisMonth + ) { + return totalIncome + } + if (view === HomeView.CurrentBalance) { + return totalIncome + totalExpense + } + }, [totalExpense, totalIncome, view]) + + const options = [ + { + value: HomeView.SpentThisWeek, + label: t(i18n)`Spent this week`, + }, + { + value: HomeView.SpentThisMonth, + label: t(i18n)`Spent this month`, + }, + { + value: HomeView.RevenueThisWeek, + label: t(i18n)`Revenue this week`, + }, + { + value: HomeView.RevenueThisMonth, + label: t(i18n)`Revenue this month`, + }, + { + value: HomeView.CurrentBalance, + label: t(i18n)`Current balance`, + }, + ] return ( - - - - {t(i18n)`Current balance`} - - - - + ) } diff --git a/apps/mobile/components/ui/select.tsx b/apps/mobile/components/ui/select.tsx index 4f13e6d9..4313849a 100644 --- a/apps/mobile/components/ui/select.tsx +++ b/apps/mobile/components/ui/select.tsx @@ -187,7 +187,7 @@ const SelectSeparator = React.forwardRef< >(({ className, ...props }, ref) => ( )) diff --git a/apps/mobile/lib/date.tsx b/apps/mobile/lib/date.tsx index 278f993a..32ee9f81 100644 --- a/apps/mobile/lib/date.tsx +++ b/apps/mobile/lib/date.tsx @@ -1,9 +1,24 @@ import { t } from '@lingui/macro' -import { format } from 'date-fns/format' -import { isSameYear } from 'date-fns/isSameYear' -import { isToday } from 'date-fns/isToday' -import { isTomorrow } from 'date-fns/isTomorrow' -import { isYesterday } from 'date-fns/isYesterday' + +import { + endOfDay, + endOfMonth, + endOfQuarter, + endOfYear, + format, + getQuarter, + isSameDay, + isSameMinute, + isSameMonth, + isSameYear, + isToday, + isTomorrow, + isYesterday, + startOfDay, + startOfMonth, + startOfQuarter, + startOfYear, +} from 'date-fns' export function formatDateShort(date?: Date) { if (!date) { @@ -28,3 +43,163 @@ export function formatDateShort(date?: Date) { return format(date, 'P') } + +const shortenAmPm = (text: string): string => { + const shortened = (text || '').replace(/ AM/g, 'am').replace(/ PM/g, 'pm') + const withoutDoubleZero = shortened.includes('m') + ? shortened.replace(/:00/g, '') + : shortened + return withoutDoubleZero +} + +const removeLeadingZero = (text: string): string => text.replace(/^0/, '') + +export const formatTime = (date: Date, locale?: string): string => { + return removeLeadingZero( + shortenAmPm( + date.toLocaleTimeString(locale, { + hour: '2-digit', + minute: '2-digit', + }) || '', + ), + ) +} + +const createFormatTime = + (locale?: string) => + (date: Date): string => + formatTime(date, locale) + +const getNavigatorLanguage = (): string => { + if (typeof window === 'undefined') { + return 'en-US' + } + return window.navigator.language +} + +export interface DateRangeFormatOptions { + today?: Date + locale?: string + includeTime?: boolean + separator?: string +} + +export const formatDateRange = ( + from: Date, + to: Date, + { + today = new Date(), + locale = getNavigatorLanguage(), + includeTime = true, + separator = '-', + }: DateRangeFormatOptions = {}, +): string => { + const sameYear = isSameYear(from, to) + const sameMonth = isSameMonth(from, to) + const sameDay = isSameDay(from, to) + const thisYear = isSameYear(from, today) + const thisDay = isSameDay(from, today) + + const yearSuffix = thisYear ? '' : `, ${format(to, 'yyyy')}` + + const formatTime = createFormatTime(locale) + + const startTimeSuffix = + includeTime && !isSameMinute(startOfDay(from), from) + ? `, ${formatTime(from)}` + : '' + + const endTimeSuffix = + includeTime && !isSameMinute(endOfDay(to), to) ? `, ${formatTime(to)}` : '' + + // Check if the range is the entire year + // Example: 2023 + if ( + isSameMinute(startOfYear(from), from) && + isSameMinute(endOfYear(to), to) + ) { + return `${format(from, 'yyyy')}` + } + + // Check if the range is an entire quarter + // Example: Q1 2023 + if ( + isSameMinute(startOfQuarter(from), from) && + isSameMinute(endOfQuarter(to), to) && + getQuarter(from) === getQuarter(to) + ) { + return `Q${getQuarter(from)} ${format(from, 'yyyy')}` + } + + // Check if the range is across entire month + if ( + isSameMinute(startOfMonth(from), from) && + isSameMinute(endOfMonth(to), to) + ) { + if (sameMonth && sameYear) { + // Example: January 2023 + return `${format(from, 'LLLL yyyy')}` + } + // Example: Jan - Feb 2023 + return `${format(from, 'LLL')} ${separator} ${format(to, 'LLL yyyy')}` + } + + // Range across years + // Example: Jan 1 '23 - Feb 12 '24 + if (!sameYear) { + return `${format( + from, + "LLL d ''yy", + )}${startTimeSuffix} ${separator} ${format( + to, + "LLL d ''yy", + )}${endTimeSuffix}` + } + + // Range across months + // Example: Jan 1 - Feb 12[, 2023] + if (!sameMonth) { + return `${format(from, 'LLL d')}${startTimeSuffix} ${separator} ${format( + to, + 'LLL d', + )}${endTimeSuffix}${yearSuffix}` + } + + // Range across days + if (!sameDay) { + // Check for a time suffix, if so print the month twice + // Example: Jan 1, 12:00pm - Jan 2, 1:00pm[, 2023] + if (startTimeSuffix || endTimeSuffix) { + return `${format(from, 'LLL d')}${startTimeSuffix} ${separator} ${format( + to, + 'LLL d', + )}${endTimeSuffix}${yearSuffix}` + } + + // Example: Jan 1 - 12[, 2023] + return `${format(from, 'LLL d')} ${separator} ${format( + to, + 'd', + )}${yearSuffix}` + } + + // Same day, different times + // Example: Jan 1, 12pm - 1pm[, 2023] + if (startTimeSuffix || endTimeSuffix) { + // If it's today, don't include the date + // Example: 12:30pm - 1pm + if (thisDay) { + return `${formatTime(from)} ${separator} ${formatTime(to)}` + } + + // Example: Jan 1, 12pm - 1pm[, 2023] + return `${format( + from, + 'LLL d', + )}${startTimeSuffix} ${separator} ${formatTime(to)}${yearSuffix}` + } + + // Full day + // Example: Fri, Jan 1[, 2023] + return `${format(from, 'eee, LLL d')}${yearSuffix}` +} diff --git a/apps/mobile/locales/en/messages.po b/apps/mobile/locales/en/messages.po index 6f54c08a..08203dcd 100644 --- a/apps/mobile/locales/en/messages.po +++ b/apps/mobile/locales/en/messages.po @@ -21,7 +21,7 @@ msgstr "" msgid "{0} left" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:127 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:145 msgid "{language}" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "Account deleted successfully" msgstr "" -#: apps/mobile/app/(app)/(tabs)/index.tsx:103 +#: apps/mobile/app/(app)/(tabs)/index.tsx:169 msgid "Add your first transaction here" msgstr "" @@ -62,11 +62,16 @@ msgstr "" msgid "All accounts" msgstr "" +#: apps/mobile/components/home/select-filter.tsx:75 #: apps/mobile/components/home/select-wallet-account.tsx:66 #: apps/mobile/components/transaction/select-budget-field.tsx:76 msgid "All Accounts" msgstr "" +#: apps/mobile/components/home/select-filter.tsx:35 +msgid "All entries" +msgstr "" + #: apps/mobile/app/(app)/profile.tsx:206 msgid "All your data will be deleted" msgstr "" @@ -87,7 +92,7 @@ msgstr "" msgid "App is locked. Please authenticate to continue." msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:108 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:126 msgid "App settings" msgstr "" @@ -96,7 +101,7 @@ msgid "App theme" msgstr "" #: apps/mobile/app/(app)/_layout.tsx:94 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:113 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:131 msgid "Appearance" msgstr "" @@ -108,7 +113,7 @@ msgstr "" msgid "Are you sure you want to delete your account? This action cannot be undone." msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:218 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:246 msgid "Are you sure you want to sign out?" msgstr "" @@ -132,11 +137,23 @@ msgstr "" msgid "Budgets" msgstr "" +#: apps/mobile/components/home/select-filter.tsx:39 +msgid "By day" +msgstr "" + +#: apps/mobile/components/home/select-filter.tsx:47 +msgid "By month" +msgstr "" + +#: apps/mobile/components/home/select-filter.tsx:43 +msgid "By week" +msgstr "" + #: apps/mobile/components/transaction/scanner.tsx:139 msgid "Camera permissions are not granted" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:220 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:248 #: apps/mobile/app/(app)/budget/[budgetId]/edit.tsx:43 #: apps/mobile/app/(app)/profile.tsx:120 #: apps/mobile/app/(app)/transaction/[transactionId].tsx:77 @@ -149,7 +166,7 @@ msgid "Cannot extract transaction data" msgstr "" #: apps/mobile/app/(app)/_layout.tsx:126 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:86 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:104 msgid "Categories" msgstr "" @@ -161,7 +178,7 @@ msgstr "" msgid "Choose a preferred theme for the 6pm" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:99 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:117 msgid "Coming soon" msgstr "" @@ -173,7 +190,11 @@ msgstr "" msgid "Continue with Email" msgstr "" -#: apps/mobile/components/home/wallet-statistics.tsx:18 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:67 +msgid "Copied version to clipboard" +msgstr "" + +#: apps/mobile/components/home/wallet-statistics.tsx:102 msgid "Current balance" msgstr "" @@ -274,11 +295,11 @@ msgstr "" msgid "From date" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:72 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:90 msgid "General" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:62 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:80 msgid "Get 6pm Pro" msgstr "" @@ -312,7 +333,7 @@ msgid "Keeping up with your spending and budgets." msgstr "" #: apps/mobile/app/(app)/_layout.tsx:82 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:122 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:140 msgid "Language" msgstr "" @@ -332,7 +353,7 @@ msgstr "" msgid "Login using FaceID" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:95 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:113 msgid "Magic inbox" msgstr "" @@ -380,11 +401,15 @@ msgstr "" msgid "No budget selected" msgstr "" +#: apps/mobile/app/(app)/(tabs)/index.tsx:157 +msgid "No transactions" +msgstr "" + #: apps/mobile/app/(app)/budget/[budgetId]/index.tsx:257 msgid "No transactions found" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:170 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:188 msgid "Others" msgstr "" @@ -408,7 +433,7 @@ msgstr "" msgid "Positive" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:175 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:203 msgid "Privacy policy" msgstr "" @@ -428,23 +453,23 @@ msgstr "" msgid "Profile updated successfully" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:208 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:236 msgid "Proudly open source" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:137 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:155 msgid "Push notifications" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:159 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:177 msgid "Push notifications are disabled" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:157 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:175 msgid "Push notifications are enabled" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:153 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:171 msgid "Push notifications are not enabled" msgstr "" @@ -452,10 +477,18 @@ msgstr "" msgid "Quarterly" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:192 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:220 msgid "Rate 6pm on App Store" msgstr "" +#: apps/mobile/components/home/wallet-statistics.tsx:98 +msgid "Revenue this month" +msgstr "" + +#: apps/mobile/components/home/wallet-statistics.tsx:94 +msgid "Revenue this week" +msgstr "" + #: apps/mobile/components/budget/budget-form.tsx:50 #: apps/mobile/components/category/category-form.tsx:118 #: apps/mobile/components/common/date-picker.tsx:55 @@ -482,6 +515,10 @@ msgstr "" msgid "Search currency..." msgstr "" +#: apps/mobile/app/(app)/(tabs)/settings.tsx:193 +msgid "Seed transactions" +msgstr "" + #: apps/mobile/components/transaction/select-account-field.tsx:63 msgid "Select account" msgstr "" @@ -498,7 +535,7 @@ msgstr "" msgid "Select period type" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:184 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:212 msgid "Send feedback" msgstr "" @@ -518,7 +555,7 @@ msgstr "" msgid "Settings" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:200 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:228 msgid "Share with friends" msgstr "" @@ -534,8 +571,8 @@ msgstr "" msgid "Sign in with Google" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:224 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:237 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:252 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:265 msgid "Sign out" msgstr "" @@ -552,6 +589,14 @@ msgstr "" msgid "Spending" msgstr "" +#: apps/mobile/components/home/wallet-statistics.tsx:90 +msgid "Spent this month" +msgstr "" + +#: apps/mobile/components/home/wallet-statistics.tsx:86 +msgid "Spent this week" +msgstr "" + #: apps/mobile/components/transaction/scanner.tsx:129 #~ msgid "Swift up to scan transaction" #~ msgstr "" @@ -592,11 +637,11 @@ msgstr "" msgid "To date" msgstr "" -#: apps/mobile/lib/date.tsx:14 +#: apps/mobile/lib/date.tsx:29 msgid "Today" msgstr "" -#: apps/mobile/lib/date.tsx:22 +#: apps/mobile/lib/date.tsx:37 msgid "Tomorrow" msgstr "" @@ -631,7 +676,7 @@ msgstr "" msgid "Unlock" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:65 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:83 msgid "Unlocks full AI power and more!" msgstr "" @@ -639,7 +684,7 @@ msgstr "" msgid "Upload new photo" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:245 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:278 msgid "ver." msgstr "" @@ -656,7 +701,7 @@ msgid "Wallet account name" msgstr "" #: apps/mobile/app/(app)/_layout.tsx:99 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:77 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:95 msgid "Wallet accounts" msgstr "" @@ -676,7 +721,7 @@ msgstr "" msgid "Yearly" msgstr "" -#: apps/mobile/lib/date.tsx:18 +#: apps/mobile/lib/date.tsx:33 msgid "Yesterday" msgstr "" diff --git a/apps/mobile/locales/en/messages.ts b/apps/mobile/locales/en/messages.ts index fce5dd83..4565043c 100644 --- a/apps/mobile/locales/en/messages.ts +++ b/apps/mobile/locales/en/messages.ts @@ -1,4 +1,4 @@ /*eslint-disable*/ import type { Messages } from '@lingui/core' export const messages: Messages = JSON.parse( - '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," left"],"FEZKSz":[["language"]],"GDr6hQ":"* you can always change this later.","VE5ikN":"<0><1>Manage your expense seamlessly<2>Let <3>6pm a good time to spend","ejSd6i":"<0>By continuing, you acknowledge that you understand and agree to our <1><2>Privacy Policy","AYTmQ1":"<0>By continuing, you acknowledge that you understand and agree to the <1><2>Terms & Conditions and <3><4>Privacy Policy","LjsgKU":"0.00","y+OdTP":"Account deleted successfully","103Xyi":"Add your first transaction here","sxkWRg":"Advanced","Mxjwaz":"All accounts","pXc4dB":"All Accounts","LcouyV":"All your data will be deleted","Vw8l6h":"An error occurred","bhrKSa":"An error occurred while deleting the transaction","rBd1BM":"An error occurred while updating the transaction","+FI+0t":"App is locked. Please authenticate to continue.","2Yw5Eq":"App settings","rg8lHb":"App theme","aAIQg2":"Appearance","rH4FJH":"Are you sure you want to delete this budget? This action cannot be undone.","TE1tui":"Are you sure you want to delete your account? This action cannot be undone.","apLLSU":"Are you sure you want to sign out?","6foA8n":"Are you sure?","X2pgJW":"Ask AI anything...","kfcRb0":"Avatar","fsBGk0":"Balance","IGsZpB":"Budgets","HjYcC9":"Camera permissions are not granted","dEgA5A":"Cancel","dZYaqU":"Cannot extract transaction data","NUrY9o":"Categories","i+de8A":"Category name","h4wXn9":"Choose a preferred theme for the 6pm","AUYALh":"Coming soon","xGVfLh":"Continue","RvVi9c":"Continue with Email","PxMcud":"Current balance","AJToWu":"Current state","7cFjHo":"Daily reminder","Zz6Cxn":"Danger zone","pvnfJD":"Dark","o5ooMr":"Debt","WRwm0h":"Default currency","cnGeoo":"Delete","chkudi":"Delete 6pm account","VbtMs5":"Delete wallet account will also delete all related transactions!","pfa8F0":"Display name","rrOW2A":"Edit account","j1Jl7s":"Edit category","O3oNi5":"Email","QOINDn":"empty","ak+zF8":"Enable Push Notifications","/AHxlh":"Enable spending alerts","lYGfRP":"English","EmV+r3":"Enter the code sent to your email","xRPn3U":"Enter your email address","/o/2Tm":"Expense","aSBbnl":"Expenses","AL8ocL":"Family budget","xRJSOj":"From date","Weq9zb":"General","h52e9T":"Get 6pm Pro","EVORi1":"Get started by setting your monthly budget.","M1w7jC":"Grant camera permissions","Uq/imr":"If you\'re not sure, start with how much you usually spend per month.","xxsw3W":"Income","Z2b5qm":"Incomes","13aTWr":"Investing","AhuqH6":"Keeping up with your spending and budgets.","vXIe7J":"Language","brkKQW":"Left per day","PRzhQh":"Left this month","1njn7W":"Light","UC3YIm":"Login using FaceID","lkAlEG":"Magic inbox","+8Nek/":"Monthly","iBONBd":"Monthly budget","6YtxFj":"Name","xYG/fs":"Negative","XejmNR":"Negative if your content balance is under zero","6WSYbN":["New ",["0"]],"Kcr9Fr":"New account","5OdwzH":"New budget","tl5vsv":"New category","ApQ2nt":"No budget selected","8bNIKG":"No transactions found","NuKR0h":"Others","198luN":"per day","NtQvjo":"Period","66fYpz":"Period end date","QTWhG5":"Period start date","FHx6kz":"Positive","ScJ9fj":"Privacy policy","LcET2C":"Privacy Policy","Z8pOEI":"Processing transaction...","vERlcd":"Profile","kUlL8W":"Profile updated successfully","++8ZXz":"Proudly open source","SZJG6+":"Push notifications","r7QRqI":"Push notifications are disabled","LI1qx1":"Push notifications are enabled","3yhyIW":"Push notifications are not enabled","kCxe8K":"Quarterly","j75BA9":"Rate 6pm on App Store","tfDRzk":"Save","y3aU20":"Save changes","uF9ruK":"Saving","WDgJiV":"Scanner","P9vd26":"Search currency...","+O3PfQ":"Select account","HfaFKV":"Select balance state","PtoMco":"Select budget type","5dfUzo":"Select period type","RoafuO":"Send feedback","wCqgpu":"Set Budget","oyi6Xa":"Set Monthly Budget","dY304N":"Set your monthly spending goal","Tz0i8g":"Settings","RDprz0":"Share with friends","5lWFkC":"Sign in","+EnZBU":"Sign in with Apple","dbWo0h":"Sign in with Google","fcWrnU":"Sign out","e+RpCP":"Sign up","TOm5Xo":"Specific dates","Q14cFX":"Spending","w5QjWi":"Swift up to scan transaction","J8R0ve":"Swipe up to scan transaction","D+NlUC":"System","IL5Ibf":"Take a picture of your transaction","Yrrg+y":"Target","KWUgwY":"Terms & Conditions","Emv+V7":"Terms of use","OR1t9P":"This will delete the transaction. Are you sure you want to continue?","sH0pkc":"Time to enter your expenses!","w4eKlT":"To date","ecUA8p":"Today","BRMXj0":"Tomorrow","38Gho6":"Transaction created","6D8usS":"transaction note","+zy2Nq":"Type","b2vAoQ":"Uncategorized","Ef7StM":"Unknown","29VNqC":"Unknown error","VAOn4r":"Unlock","QQX2/q":"Unlocks full AI power and more!","wPTug2":"Upload new photo","KALubG":"ver.","AdWhjZ":"Verification code","fROFIL":"Vietnamese","q19YJ1":"Wallet account name","rUcnTU":"Wallet accounts","mdad9N":"Wallet Accounts","4XSc4l":"Weekly","I+fC9+":"Welcome to 6pm!","zkWmBh":"Yearly","y/0uwd":"Yesterday","kDrMSv":"Your display name"}', + '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," left"],"FEZKSz":[["language"]],"GDr6hQ":"* you can always change this later.","VE5ikN":"<0><1>Manage your expense seamlessly<2>Let <3>6pm a good time to spend","ejSd6i":"<0>By continuing, you acknowledge that you understand and agree to our <1><2>Privacy Policy","AYTmQ1":"<0>By continuing, you acknowledge that you understand and agree to the <1><2>Terms & Conditions and <3><4>Privacy Policy","LjsgKU":"0.00","y+OdTP":"Account deleted successfully","103Xyi":"Add your first transaction here","sxkWRg":"Advanced","Mxjwaz":"All accounts","pXc4dB":"All Accounts","HoJ+ka":"All entries","LcouyV":"All your data will be deleted","Vw8l6h":"An error occurred","bhrKSa":"An error occurred while deleting the transaction","rBd1BM":"An error occurred while updating the transaction","+FI+0t":"App is locked. Please authenticate to continue.","2Yw5Eq":"App settings","rg8lHb":"App theme","aAIQg2":"Appearance","rH4FJH":"Are you sure you want to delete this budget? This action cannot be undone.","TE1tui":"Are you sure you want to delete your account? This action cannot be undone.","apLLSU":"Are you sure you want to sign out?","6foA8n":"Are you sure?","X2pgJW":"Ask AI anything...","kfcRb0":"Avatar","fsBGk0":"Balance","IGsZpB":"Budgets","HjGOT5":"By day","kYFORZ":"By month","OTL6lf":"By week","HjYcC9":"Camera permissions are not granted","dEgA5A":"Cancel","dZYaqU":"Cannot extract transaction data","NUrY9o":"Categories","i+de8A":"Category name","h4wXn9":"Choose a preferred theme for the 6pm","AUYALh":"Coming soon","xGVfLh":"Continue","RvVi9c":"Continue with Email","eGKI3t":"Copied version to clipboard","PxMcud":"Current balance","AJToWu":"Current state","7cFjHo":"Daily reminder","Zz6Cxn":"Danger zone","pvnfJD":"Dark","o5ooMr":"Debt","WRwm0h":"Default currency","cnGeoo":"Delete","chkudi":"Delete 6pm account","VbtMs5":"Delete wallet account will also delete all related transactions!","pfa8F0":"Display name","rrOW2A":"Edit account","j1Jl7s":"Edit category","O3oNi5":"Email","QOINDn":"empty","ak+zF8":"Enable Push Notifications","/AHxlh":"Enable spending alerts","lYGfRP":"English","EmV+r3":"Enter the code sent to your email","xRPn3U":"Enter your email address","/o/2Tm":"Expense","aSBbnl":"Expenses","AL8ocL":"Family budget","xRJSOj":"From date","Weq9zb":"General","h52e9T":"Get 6pm Pro","EVORi1":"Get started by setting your monthly budget.","M1w7jC":"Grant camera permissions","Uq/imr":"If you\'re not sure, start with how much you usually spend per month.","xxsw3W":"Income","Z2b5qm":"Incomes","13aTWr":"Investing","AhuqH6":"Keeping up with your spending and budgets.","vXIe7J":"Language","brkKQW":"Left per day","PRzhQh":"Left this month","1njn7W":"Light","UC3YIm":"Login using FaceID","lkAlEG":"Magic inbox","+8Nek/":"Monthly","iBONBd":"Monthly budget","6YtxFj":"Name","xYG/fs":"Negative","XejmNR":"Negative if your content balance is under zero","6WSYbN":["New ",["0"]],"Kcr9Fr":"New account","5OdwzH":"New budget","tl5vsv":"New category","ApQ2nt":"No budget selected","xc4rPs":"No transactions","8bNIKG":"No transactions found","NuKR0h":"Others","198luN":"per day","NtQvjo":"Period","66fYpz":"Period end date","QTWhG5":"Period start date","FHx6kz":"Positive","ScJ9fj":"Privacy policy","LcET2C":"Privacy Policy","Z8pOEI":"Processing transaction...","vERlcd":"Profile","kUlL8W":"Profile updated successfully","++8ZXz":"Proudly open source","SZJG6+":"Push notifications","r7QRqI":"Push notifications are disabled","LI1qx1":"Push notifications are enabled","3yhyIW":"Push notifications are not enabled","kCxe8K":"Quarterly","j75BA9":"Rate 6pm on App Store","GkHlI/":"Revenue this month","8lh/OF":"Revenue this week","tfDRzk":"Save","y3aU20":"Save changes","uF9ruK":"Saving","WDgJiV":"Scanner","P9vd26":"Search currency...","UA6v4Z":"Seed transactions","+O3PfQ":"Select account","HfaFKV":"Select balance state","PtoMco":"Select budget type","5dfUzo":"Select period type","RoafuO":"Send feedback","wCqgpu":"Set Budget","oyi6Xa":"Set Monthly Budget","dY304N":"Set your monthly spending goal","Tz0i8g":"Settings","RDprz0":"Share with friends","5lWFkC":"Sign in","+EnZBU":"Sign in with Apple","dbWo0h":"Sign in with Google","fcWrnU":"Sign out","e+RpCP":"Sign up","TOm5Xo":"Specific dates","Q14cFX":"Spending","FlGoyI":"Spent this month","Ozoj7N":"Spent this week","w5QjWi":"Swift up to scan transaction","J8R0ve":"Swipe up to scan transaction","D+NlUC":"System","IL5Ibf":"Take a picture of your transaction","Yrrg+y":"Target","KWUgwY":"Terms & Conditions","Emv+V7":"Terms of use","OR1t9P":"This will delete the transaction. Are you sure you want to continue?","sH0pkc":"Time to enter your expenses!","w4eKlT":"To date","ecUA8p":"Today","BRMXj0":"Tomorrow","38Gho6":"Transaction created","6D8usS":"transaction note","+zy2Nq":"Type","b2vAoQ":"Uncategorized","Ef7StM":"Unknown","29VNqC":"Unknown error","VAOn4r":"Unlock","QQX2/q":"Unlocks full AI power and more!","wPTug2":"Upload new photo","KALubG":"ver.","AdWhjZ":"Verification code","fROFIL":"Vietnamese","q19YJ1":"Wallet account name","rUcnTU":"Wallet accounts","mdad9N":"Wallet Accounts","4XSc4l":"Weekly","I+fC9+":"Welcome to 6pm!","zkWmBh":"Yearly","y/0uwd":"Yesterday","kDrMSv":"Your display name"}', ) diff --git a/apps/mobile/locales/vi/messages.po b/apps/mobile/locales/vi/messages.po index 81bab442..93a7c6d7 100644 --- a/apps/mobile/locales/vi/messages.po +++ b/apps/mobile/locales/vi/messages.po @@ -21,7 +21,7 @@ msgstr "" msgid "{0} left" msgstr "{0} còn lại" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:127 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:145 msgid "{language}" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "Account deleted successfully" msgstr "Xóa tài khoản thành công" -#: apps/mobile/app/(app)/(tabs)/index.tsx:103 +#: apps/mobile/app/(app)/(tabs)/index.tsx:169 msgid "Add your first transaction here" msgstr "Thêm giao dịch đầu tiên ở đây" @@ -62,11 +62,16 @@ msgstr "Nâng cao" msgid "All accounts" msgstr "Tất cả tài khoản" +#: apps/mobile/components/home/select-filter.tsx:75 #: apps/mobile/components/home/select-wallet-account.tsx:66 #: apps/mobile/components/transaction/select-budget-field.tsx:76 msgid "All Accounts" msgstr "Tất cả tài khoản" +#: apps/mobile/components/home/select-filter.tsx:35 +msgid "All entries" +msgstr "Xem tất cả" + #: apps/mobile/app/(app)/profile.tsx:206 msgid "All your data will be deleted" msgstr "Tất cả dữ liệu của bạn sẽ bị xóa" @@ -87,7 +92,7 @@ msgstr "Có lỗi xảy ra khi cập nhật giao dịch" msgid "App is locked. Please authenticate to continue." msgstr "Ứng dụng đã khóa. Vui lòng xác thực để tiếp tục." -#: apps/mobile/app/(app)/(tabs)/settings.tsx:108 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:126 msgid "App settings" msgstr "Cài đặt ứng dụng" @@ -96,7 +101,7 @@ msgid "App theme" msgstr "Chủ đề ứng dụng" #: apps/mobile/app/(app)/_layout.tsx:94 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:113 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:131 msgid "Appearance" msgstr "Giao diện" @@ -108,7 +113,7 @@ msgstr "Bạn có chắc chắn muốn xóa ngân sách này? Hành động này msgid "Are you sure you want to delete your account? This action cannot be undone." msgstr "Bạn có chắc chắn muốn xóa tài khoản của bạn? Hành động này không thể hoàn tác." -#: apps/mobile/app/(app)/(tabs)/settings.tsx:218 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:246 msgid "Are you sure you want to sign out?" msgstr "Bạn có chắc chắn muốn đăng xuất?" @@ -132,11 +137,23 @@ msgstr "Số dư" msgid "Budgets" msgstr "Ngân sách" +#: apps/mobile/components/home/select-filter.tsx:39 +msgid "By day" +msgstr "Theo ngày" + +#: apps/mobile/components/home/select-filter.tsx:47 +msgid "By month" +msgstr "Theo tháng" + +#: apps/mobile/components/home/select-filter.tsx:43 +msgid "By week" +msgstr "Theo tuần" + #: apps/mobile/components/transaction/scanner.tsx:139 msgid "Camera permissions are not granted" msgstr "Quyền truy cập camera không được cấp" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:220 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:248 #: apps/mobile/app/(app)/budget/[budgetId]/edit.tsx:43 #: apps/mobile/app/(app)/profile.tsx:120 #: apps/mobile/app/(app)/transaction/[transactionId].tsx:77 @@ -149,7 +166,7 @@ msgid "Cannot extract transaction data" msgstr "Không thể xử lý dữ liệu giao dịch" #: apps/mobile/app/(app)/_layout.tsx:126 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:86 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:104 msgid "Categories" msgstr "Danh mục" @@ -161,7 +178,7 @@ msgstr "Tên danh mục" msgid "Choose a preferred theme for the 6pm" msgstr "Chọn chủ đề giao diện cho 6pm" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:99 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:117 msgid "Coming soon" msgstr "Sắp xong" @@ -173,7 +190,11 @@ msgstr "Tiếp tục" msgid "Continue with Email" msgstr "Tiếp tục với Email" -#: apps/mobile/components/home/wallet-statistics.tsx:18 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:67 +msgid "Copied version to clipboard" +msgstr "Đã sao chép số phiên bản" + +#: apps/mobile/components/home/wallet-statistics.tsx:102 msgid "Current balance" msgstr "Số dư hiện tại" @@ -274,11 +295,11 @@ msgstr "Ngân sách gia đình" msgid "From date" msgstr "Từ ngày" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:72 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:90 msgid "General" msgstr "Chung" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:62 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:80 msgid "Get 6pm Pro" msgstr "Nâng Cấp 6pm Pro" @@ -312,7 +333,7 @@ msgid "Keeping up with your spending and budgets." msgstr "Theo dõi kịp tình hình chi tiêu và ngân sách." #: apps/mobile/app/(app)/_layout.tsx:82 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:122 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:140 msgid "Language" msgstr "Ngôn ngữ" @@ -332,7 +353,7 @@ msgstr "Sáng" msgid "Login using FaceID" msgstr "Đăng nhập bằng FaceID" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:95 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:113 msgid "Magic inbox" msgstr "Hộp thư ma thuật" @@ -380,11 +401,15 @@ msgstr "Tạo danh mục mới" msgid "No budget selected" msgstr "Chọn ngân sách" +#: apps/mobile/app/(app)/(tabs)/index.tsx:157 +msgid "No transactions" +msgstr "Không có giao dịch" + #: apps/mobile/app/(app)/budget/[budgetId]/index.tsx:257 msgid "No transactions found" msgstr "Không tìm thấy giao dịch" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:170 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:188 msgid "Others" msgstr "Khác" @@ -408,7 +433,7 @@ msgstr "Ngày bắt đầu" msgid "Positive" msgstr "Dương" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:175 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:203 msgid "Privacy policy" msgstr "Chính sách bảo mật" @@ -428,23 +453,23 @@ msgstr "Hồ sơ" msgid "Profile updated successfully" msgstr "Cập nhật hồ sơ thành công" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:208 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:236 msgid "Proudly open source" msgstr "Mã nguồn mở" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:137 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:155 msgid "Push notifications" msgstr "Thông báo đẩy" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:159 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:177 msgid "Push notifications are disabled" msgstr "Thông báo đẩy bị vô hiệu hóa" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:157 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:175 msgid "Push notifications are enabled" msgstr "Thông báo đẩy đã được bật" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:153 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:171 msgid "Push notifications are not enabled" msgstr "Thông báo đẩy chưa được bật" @@ -452,10 +477,18 @@ msgstr "Thông báo đẩy chưa được bật" msgid "Quarterly" msgstr "Hàng quý" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:192 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:220 msgid "Rate 6pm on App Store" msgstr "Đánh giá 6pm trên App Store" +#: apps/mobile/components/home/wallet-statistics.tsx:98 +msgid "Revenue this month" +msgstr "Doanh thu tháng này" + +#: apps/mobile/components/home/wallet-statistics.tsx:94 +msgid "Revenue this week" +msgstr "Doanh thu tuần này" + #: apps/mobile/components/budget/budget-form.tsx:50 #: apps/mobile/components/category/category-form.tsx:118 #: apps/mobile/components/common/date-picker.tsx:55 @@ -482,6 +515,10 @@ msgstr "Đang lưu" msgid "Search currency..." msgstr "Tìm kiếm đơn vị..." +#: apps/mobile/app/(app)/(tabs)/settings.tsx:193 +msgid "Seed transactions" +msgstr "Tạo giao dịch mẫu" + #: apps/mobile/components/transaction/select-account-field.tsx:63 msgid "Select account" msgstr "Chọn tài khoản" @@ -498,7 +535,7 @@ msgstr "Chọn loại ngân sách" msgid "Select period type" msgstr "Chọn loại chu kỳ" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:184 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:212 msgid "Send feedback" msgstr "Gửi phản hồi" @@ -518,7 +555,7 @@ msgstr "Đặt mục tiêu chi tiêu hàng tháng" msgid "Settings" msgstr "Cài đặt" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:200 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:228 msgid "Share with friends" msgstr "Chia sẻ với bạn bè" @@ -534,8 +571,8 @@ msgstr "Tiếp tục với Apple" msgid "Sign in with Google" msgstr "Tiếp tục với Google" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:224 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:237 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:252 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:265 msgid "Sign out" msgstr "Đăng xuất" @@ -552,6 +589,14 @@ msgstr "Ngày cụ thể" msgid "Spending" msgstr "Chi tiêu" +#: apps/mobile/components/home/wallet-statistics.tsx:90 +msgid "Spent this month" +msgstr "Chi tiêu tháng này" + +#: apps/mobile/components/home/wallet-statistics.tsx:86 +msgid "Spent this week" +msgstr "Chi tiêu tuần này" + #: apps/mobile/components/transaction/scanner.tsx:129 #~ msgid "Swift up to scan transaction" #~ msgstr "Vuốt lên để quét giao dịch" @@ -592,11 +637,11 @@ msgstr "Đến giờ nhập chi tiêu hôm nay!" msgid "To date" msgstr "Đến ngày" -#: apps/mobile/lib/date.tsx:14 +#: apps/mobile/lib/date.tsx:29 msgid "Today" msgstr "Hôm nay" -#: apps/mobile/lib/date.tsx:22 +#: apps/mobile/lib/date.tsx:37 msgid "Tomorrow" msgstr "Ngày mai" @@ -631,7 +676,7 @@ msgstr "Lỗi không xác định" msgid "Unlock" msgstr "Mở khóa" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:65 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:83 msgid "Unlocks full AI power and more!" msgstr "Mở khóa sức mạnh AI và các tính năng khác!" @@ -639,7 +684,7 @@ msgstr "Mở khóa sức mạnh AI và các tính năng khác!" msgid "Upload new photo" msgstr "Tải lên ảnh mới" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:245 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:278 msgid "ver." msgstr "" @@ -656,7 +701,7 @@ msgid "Wallet account name" msgstr "Tên tài khoản ví" #: apps/mobile/app/(app)/_layout.tsx:99 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:77 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:95 msgid "Wallet accounts" msgstr "Quản lý tài khoản ví" @@ -676,7 +721,7 @@ msgstr "Chào mừng đến 6pm!" msgid "Yearly" msgstr "Hàng năm" -#: apps/mobile/lib/date.tsx:18 +#: apps/mobile/lib/date.tsx:33 msgid "Yesterday" msgstr "Hôm qua" diff --git a/apps/mobile/locales/vi/messages.ts b/apps/mobile/locales/vi/messages.ts index 261787e5..c4b6f2f9 100644 --- a/apps/mobile/locales/vi/messages.ts +++ b/apps/mobile/locales/vi/messages.ts @@ -1,4 +1,4 @@ /*eslint-disable*/ import type { Messages } from '@lingui/core' export const messages: Messages = JSON.parse( - '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," còn lại"],"FEZKSz":[["language"]],"GDr6hQ":"* bạn có thể cập nhật lại sau.","VE5ikN":"<0><1>Quản lý chi tiêu hiệu quả<2>Không lo cháy túi mỗi <3>6pm","ejSd6i":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Chính sách bảo mật của 6pm.","AYTmQ1":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Điều khoản sử dụng và <3><4>Chính sách bảo mật của 6pm.","LjsgKU":"0.00","y+OdTP":"Xóa tài khoản thành công","103Xyi":"Thêm giao dịch đầu tiên ở đây","sxkWRg":"Nâng cao","Mxjwaz":"Tất cả tài khoản","pXc4dB":"Tất cả tài khoản","LcouyV":"Tất cả dữ liệu của bạn sẽ bị xóa","Vw8l6h":"Có lỗi xảy ra","bhrKSa":"Có lỗi xảy ra khi xóa giao dịch","rBd1BM":"Có lỗi xảy ra khi cập nhật giao dịch","+FI+0t":"Ứng dụng đã khóa. Vui lòng xác thực để tiếp tục.","2Yw5Eq":"Cài đặt ứng dụng","rg8lHb":"Chủ đề ứng dụng","aAIQg2":"Giao diện","rH4FJH":"Bạn có chắc chắn muốn xóa ngân sách này? Hành động này không thể hoàn tác.","TE1tui":"Bạn có chắc chắn muốn xóa tài khoản của bạn? Hành động này không thể hoàn tác.","apLLSU":"Bạn có chắc chắn muốn đăng xuất?","6foA8n":"Bạn chắc chưa?","X2pgJW":"Hỏi AI bất kỳ gì...","kfcRb0":"Ảnh đại diện","fsBGk0":"Số dư","IGsZpB":"Ngân sách","HjYcC9":"Quyền truy cập camera không được cấp","dEgA5A":"Huỷ","dZYaqU":"Không thể xử lý dữ liệu giao dịch","NUrY9o":"Danh mục","i+de8A":"Tên danh mục","h4wXn9":"Chọn chủ đề giao diện cho 6pm","AUYALh":"Sắp xong","xGVfLh":"Tiếp tục","RvVi9c":"Tiếp tục với Email","PxMcud":"Số dư hiện tại","AJToWu":"Trạng thái","7cFjHo":"Nhắc nhở hàng ngày","Zz6Cxn":"Vùng nguy hiểm","pvnfJD":"Tối","o5ooMr":"Nợ","WRwm0h":"Đơn vị mặc định","cnGeoo":"Xóa","chkudi":"Xóa tài khoản 6pm","VbtMs5":"Xóa tài khoản ví sẽ cũng xóa tất cả các giao dịch liên quan!","pfa8F0":"Tên hiển thị","rrOW2A":"Chỉnh sửa tài khoản","j1Jl7s":"Chỉnh sửa danh mục","O3oNi5":"Email","QOINDn":"trống","ak+zF8":"Bật Thông Báo Đẩy","/AHxlh":"Nhận thông báo chi tiêu","lYGfRP":"Tiếng Anh","EmV+r3":"Nhập mã xác nhận gửi đến email của bạn","xRPn3U":"Nhập địa chỉ email của bạn","/o/2Tm":"Chi tiêu","aSBbnl":"Chi tiêu","AL8ocL":"Ngân sách gia đình","xRJSOj":"Từ ngày","Weq9zb":"Chung","h52e9T":"Nâng Cấp 6pm Pro","EVORi1":"Bắt đầu bằng cách đặt ngân sách hàng tháng của bạn.","M1w7jC":"Cấp quyền truy cập camera","Uq/imr":"Nếu không chắc chắn, hãy nhập số tiền bạn thường chi tiêu hàng tháng.","xxsw3W":"Thu nhập","Z2b5qm":"Thu nhập","13aTWr":"Đầu tư","AhuqH6":"Theo dõi kịp tình hình chi tiêu và ngân sách.","vXIe7J":"Ngôn ngữ","brkKQW":"Còn lại mỗi ngày","PRzhQh":"Còn lại tháng này","1njn7W":"Sáng","UC3YIm":"Đăng nhập bằng FaceID","lkAlEG":"Hộp thư ma thuật","+8Nek/":"Hàng tháng","iBONBd":"Ngân sách tháng","6YtxFj":"Tên","xYG/fs":"Âm","XejmNR":"Âm nếu số dư tài khoản dưới 0","6WSYbN":["Tạo mới ",["0"]],"Kcr9Fr":"Tạo tài khoản mới","5OdwzH":"Tạo ngân sách","tl5vsv":"Tạo danh mục mới","ApQ2nt":"Chọn ngân sách","8bNIKG":"Không tìm thấy giao dịch","NuKR0h":"Khác","198luN":"mỗi ngày","NtQvjo":"Period","66fYpz":"Ngày kết thúc","QTWhG5":"Ngày bắt đầu","FHx6kz":"Dương","ScJ9fj":"Chính sách bảo mật","LcET2C":"Chính sách bảo mật","Z8pOEI":"Đang xử lý giao dịch...","vERlcd":"Hồ sơ","kUlL8W":"Cập nhật hồ sơ thành công","++8ZXz":"Mã nguồn mở","SZJG6+":"Thông báo đẩy","r7QRqI":"Thông báo đẩy bị vô hiệu hóa","LI1qx1":"Thông báo đẩy đã được bật","3yhyIW":"Thông báo đẩy chưa được bật","kCxe8K":"Hàng quý","j75BA9":"Đánh giá 6pm trên App Store","tfDRzk":"Lưu","y3aU20":"Lưu thay đổi","uF9ruK":"Đang lưu","WDgJiV":"Quét hoá đơn","P9vd26":"Tìm kiếm đơn vị...","+O3PfQ":"Chọn tài khoản","HfaFKV":"Chọn trạng thái số dư","PtoMco":"Chọn loại ngân sách","5dfUzo":"Chọn loại chu kỳ","RoafuO":"Gửi phản hồi","wCqgpu":"Lưu Ngân Sách","oyi6Xa":"Đặt Ngân Sách Tháng","dY304N":"Đặt mục tiêu chi tiêu hàng tháng","Tz0i8g":"Cài đặt","RDprz0":"Chia sẻ với bạn bè","5lWFkC":"Đăng nhập","+EnZBU":"Tiếp tục với Apple","dbWo0h":"Tiếp tục với Google","fcWrnU":"Đăng xuất","e+RpCP":"Đăng ký","TOm5Xo":"Ngày cụ thể","Q14cFX":"Chi tiêu","w5QjWi":"Vuốt lên để quét giao dịch","J8R0ve":"Vuốt lên để quét giao dịch","D+NlUC":"Hệ thống","IL5Ibf":"Chụp ảnh giao dịch của bạn","Yrrg+y":"Mục tiêu","KWUgwY":"Điều khoản sử dụng","Emv+V7":"Điều khoản sử dụng","OR1t9P":"Hành động này sẽ xóa giao dịch. Bạn có chắc chắn muốn tiếp tục không?","sH0pkc":"Đến giờ nhập chi tiêu hôm nay!","w4eKlT":"Đến ngày","ecUA8p":"Hôm nay","BRMXj0":"Ngày mai","38Gho6":"Giao dịch đã được tạo","6D8usS":"ghi chú giao dịch","+zy2Nq":"Loại","b2vAoQ":"Chưa phân loại","Ef7StM":"Không xác định","29VNqC":"Lỗi không xác định","VAOn4r":"Mở khóa","QQX2/q":"Mở khóa sức mạnh AI và các tính năng khác!","wPTug2":"Tải lên ảnh mới","KALubG":"ver.","AdWhjZ":"Mã xác nhận","fROFIL":"Tiếng Việt","q19YJ1":"Tên tài khoản ví","rUcnTU":"Quản lý tài khoản ví","mdad9N":"Các tài khoản","4XSc4l":"Hàng tuần","I+fC9+":"Chào mừng đến 6pm!","zkWmBh":"Hàng năm","y/0uwd":"Hôm qua","kDrMSv":"Tên hiển thị của bạn"}', + '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," còn lại"],"FEZKSz":[["language"]],"GDr6hQ":"* bạn có thể cập nhật lại sau.","VE5ikN":"<0><1>Quản lý chi tiêu hiệu quả<2>Không lo cháy túi mỗi <3>6pm","ejSd6i":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Chính sách bảo mật của 6pm.","AYTmQ1":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Điều khoản sử dụng và <3><4>Chính sách bảo mật của 6pm.","LjsgKU":"0.00","y+OdTP":"Xóa tài khoản thành công","103Xyi":"Thêm giao dịch đầu tiên ở đây","sxkWRg":"Nâng cao","Mxjwaz":"Tất cả tài khoản","pXc4dB":"Tất cả tài khoản","HoJ+ka":"Xem tất cả","LcouyV":"Tất cả dữ liệu của bạn sẽ bị xóa","Vw8l6h":"Có lỗi xảy ra","bhrKSa":"Có lỗi xảy ra khi xóa giao dịch","rBd1BM":"Có lỗi xảy ra khi cập nhật giao dịch","+FI+0t":"Ứng dụng đã khóa. Vui lòng xác thực để tiếp tục.","2Yw5Eq":"Cài đặt ứng dụng","rg8lHb":"Chủ đề ứng dụng","aAIQg2":"Giao diện","rH4FJH":"Bạn có chắc chắn muốn xóa ngân sách này? Hành động này không thể hoàn tác.","TE1tui":"Bạn có chắc chắn muốn xóa tài khoản của bạn? Hành động này không thể hoàn tác.","apLLSU":"Bạn có chắc chắn muốn đăng xuất?","6foA8n":"Bạn chắc chưa?","X2pgJW":"Hỏi AI bất kỳ gì...","kfcRb0":"Ảnh đại diện","fsBGk0":"Số dư","IGsZpB":"Ngân sách","HjGOT5":"Theo ngày","kYFORZ":"Theo tháng","OTL6lf":"Theo tuần","HjYcC9":"Quyền truy cập camera không được cấp","dEgA5A":"Huỷ","dZYaqU":"Không thể xử lý dữ liệu giao dịch","NUrY9o":"Danh mục","i+de8A":"Tên danh mục","h4wXn9":"Chọn chủ đề giao diện cho 6pm","AUYALh":"Sắp xong","xGVfLh":"Tiếp tục","RvVi9c":"Tiếp tục với Email","eGKI3t":"Đã sao chép số phiên bản","PxMcud":"Số dư hiện tại","AJToWu":"Trạng thái","7cFjHo":"Nhắc nhở hàng ngày","Zz6Cxn":"Vùng nguy hiểm","pvnfJD":"Tối","o5ooMr":"Nợ","WRwm0h":"Đơn vị mặc định","cnGeoo":"Xóa","chkudi":"Xóa tài khoản 6pm","VbtMs5":"Xóa tài khoản ví sẽ cũng xóa tất cả các giao dịch liên quan!","pfa8F0":"Tên hiển thị","rrOW2A":"Chỉnh sửa tài khoản","j1Jl7s":"Chỉnh sửa danh mục","O3oNi5":"Email","QOINDn":"trống","ak+zF8":"Bật Thông Báo Đẩy","/AHxlh":"Nhận thông báo chi tiêu","lYGfRP":"Tiếng Anh","EmV+r3":"Nhập mã xác nhận gửi đến email của bạn","xRPn3U":"Nhập địa chỉ email của bạn","/o/2Tm":"Chi tiêu","aSBbnl":"Chi tiêu","AL8ocL":"Ngân sách gia đình","xRJSOj":"Từ ngày","Weq9zb":"Chung","h52e9T":"Nâng Cấp 6pm Pro","EVORi1":"Bắt đầu bằng cách đặt ngân sách hàng tháng của bạn.","M1w7jC":"Cấp quyền truy cập camera","Uq/imr":"Nếu không chắc chắn, hãy nhập số tiền bạn thường chi tiêu hàng tháng.","xxsw3W":"Thu nhập","Z2b5qm":"Thu nhập","13aTWr":"Đầu tư","AhuqH6":"Theo dõi kịp tình hình chi tiêu và ngân sách.","vXIe7J":"Ngôn ngữ","brkKQW":"Còn lại mỗi ngày","PRzhQh":"Còn lại tháng này","1njn7W":"Sáng","UC3YIm":"Đăng nhập bằng FaceID","lkAlEG":"Hộp thư ma thuật","+8Nek/":"Hàng tháng","iBONBd":"Ngân sách tháng","6YtxFj":"Tên","xYG/fs":"Âm","XejmNR":"Âm nếu số dư tài khoản dưới 0","6WSYbN":["Tạo mới ",["0"]],"Kcr9Fr":"Tạo tài khoản mới","5OdwzH":"Tạo ngân sách","tl5vsv":"Tạo danh mục mới","ApQ2nt":"Chọn ngân sách","xc4rPs":"Không có giao dịch","8bNIKG":"Không tìm thấy giao dịch","NuKR0h":"Khác","198luN":"mỗi ngày","NtQvjo":"Period","66fYpz":"Ngày kết thúc","QTWhG5":"Ngày bắt đầu","FHx6kz":"Dương","ScJ9fj":"Chính sách bảo mật","LcET2C":"Chính sách bảo mật","Z8pOEI":"Đang xử lý giao dịch...","vERlcd":"Hồ sơ","kUlL8W":"Cập nhật hồ sơ thành công","++8ZXz":"Mã nguồn mở","SZJG6+":"Thông báo đẩy","r7QRqI":"Thông báo đẩy bị vô hiệu hóa","LI1qx1":"Thông báo đẩy đã được bật","3yhyIW":"Thông báo đẩy chưa được bật","kCxe8K":"Hàng quý","j75BA9":"Đánh giá 6pm trên App Store","GkHlI/":"Doanh thu tháng này","8lh/OF":"Doanh thu tuần này","tfDRzk":"Lưu","y3aU20":"Lưu thay đổi","uF9ruK":"Đang lưu","WDgJiV":"Quét hoá đơn","P9vd26":"Tìm kiếm đơn vị...","UA6v4Z":"Tạo giao dịch mẫu","+O3PfQ":"Chọn tài khoản","HfaFKV":"Chọn trạng thái số dư","PtoMco":"Chọn loại ngân sách","5dfUzo":"Chọn loại chu kỳ","RoafuO":"Gửi phản hồi","wCqgpu":"Lưu Ngân Sách","oyi6Xa":"Đặt Ngân Sách Tháng","dY304N":"Đặt mục tiêu chi tiêu hàng tháng","Tz0i8g":"Cài đặt","RDprz0":"Chia sẻ với bạn bè","5lWFkC":"Đăng nhập","+EnZBU":"Tiếp tục với Apple","dbWo0h":"Tiếp tục với Google","fcWrnU":"Đăng xuất","e+RpCP":"Đăng ký","TOm5Xo":"Ngày cụ thể","Q14cFX":"Chi tiêu","FlGoyI":"Chi tiêu tháng này","Ozoj7N":"Chi tiêu tuần này","w5QjWi":"Vuốt lên để quét giao dịch","J8R0ve":"Vuốt lên để quét giao dịch","D+NlUC":"Hệ thống","IL5Ibf":"Chụp ảnh giao dịch của bạn","Yrrg+y":"Mục tiêu","KWUgwY":"Điều khoản sử dụng","Emv+V7":"Điều khoản sử dụng","OR1t9P":"Hành động này sẽ xóa giao dịch. Bạn có chắc chắn muốn tiếp tục không?","sH0pkc":"Đến giờ nhập chi tiêu hôm nay!","w4eKlT":"Đến ngày","ecUA8p":"Hôm nay","BRMXj0":"Ngày mai","38Gho6":"Giao dịch đã được tạo","6D8usS":"ghi chú giao dịch","+zy2Nq":"Loại","b2vAoQ":"Chưa phân loại","Ef7StM":"Không xác định","29VNqC":"Lỗi không xác định","VAOn4r":"Mở khóa","QQX2/q":"Mở khóa sức mạnh AI và các tính năng khác!","wPTug2":"Tải lên ảnh mới","KALubG":"ver.","AdWhjZ":"Mã xác nhận","fROFIL":"Tiếng Việt","q19YJ1":"Tên tài khoản ví","rUcnTU":"Quản lý tài khoản ví","mdad9N":"Các tài khoản","4XSc4l":"Hàng tuần","I+fC9+":"Chào mừng đến 6pm!","zkWmBh":"Hàng năm","y/0uwd":"Hôm qua","kDrMSv":"Tên hiển thị của bạn"}', ) diff --git a/apps/mobile/stores/transaction/hooks.tsx b/apps/mobile/stores/transaction/hooks.tsx index a3fe21af..fe633175 100644 --- a/apps/mobile/stores/transaction/hooks.tsx +++ b/apps/mobile/stores/transaction/hooks.tsx @@ -61,14 +61,14 @@ export function useTransactionList({ const transactionDict = keyBy(transactions, 'id') const totalIncome = transactions.reduce((acc, t) => { - if (t.amount > 0) { - return acc + t.amount + if (t.amountInVnd > 0) { + return acc + t.amountInVnd } return acc }, 0) const totalExpense = transactions.reduce((acc, t) => { - if (t.amount < 0) { - return acc + t.amount + if (t.amountInVnd < 0) { + return acc + t.amountInVnd } return acc }, 0)