Skip to content

Commit

Permalink
feat(mobile): [Transaction] filter by account (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkdev98 committed Jul 23, 2024
1 parent fb19cda commit f6486e3
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 26 deletions.
9 changes: 7 additions & 2 deletions apps/mobile/app/(app)/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { t } from '@lingui/macro'
import { useLingui } from '@lingui/react'
import { format } from 'date-fns/format'
import { LinearGradient } from 'expo-linear-gradient'
import { useMemo } from 'react'
import { useMemo, useState } from 'react'
import { SectionList, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'

Expand All @@ -23,6 +23,7 @@ const TRANSACTIONS_PER_PAGE = 15
export default function HomeScreen() {
const { i18n } = useLingui()
const { top, bottom } = useSafeAreaInsets()
const [walletAccountId, setWalletAccountId] = useState<string | undefined>()
const {
data,
isLoading,
Expand All @@ -33,6 +34,7 @@ export default function HomeScreen() {
isFetchingNextPage,
} = useTransactions({
last: TRANSACTIONS_PER_PAGE,
walletAccountId,
})
const { colorScheme } = useColorScheme()

Expand Down Expand Up @@ -64,7 +66,10 @@ export default function HomeScreen() {

return (
<View className="flex-1 bg-card" style={{ paddingTop: top }}>
<HomeHeader />
<HomeHeader
walletAccountId={walletAccountId}
onWalletAccountChange={setWalletAccountId}
/>
<SectionList
ListHeaderComponent={
<View className="p-6">
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/components/budget/select-budget-type-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function SelectBudgetTypeField({
portalHost="budget-form"
className="w-full"
>
<SelectGroup>
<SelectGroup className="px-1">
{options.map((option) => (
<SelectItem
key={option.value}
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/components/budget/select-period-type-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function SelectPeriodTypeField({
portalHost="budget-form"
className="w-full"
>
<SelectGroup>
<SelectGroup className="px-1">
{options.map((option) => (
<SelectItem
key={option.value}
Expand Down
31 changes: 16 additions & 15 deletions apps/mobile/components/home/header.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { useUser } from '@clerk/clerk-expo'
import { t } from '@lingui/macro'
import { useLingui } from '@lingui/react'
import { ArrowDownUp, Bell } from 'lucide-react-native'
import { Text, TouchableOpacity, View } from 'react-native'
import { Bell } from 'lucide-react-native'
import { Text, View } from 'react-native'
import { UserAvatar } from '../common/user-avatar'
import { Button } from '../ui/button'
import { SelectWalletAccount } from './select-wallet-account'

export function HomeHeader() {
type HomeHeaderProps = {
walletAccountId?: string
onWalletAccountChange?: (walletAccountId?: string) => void
}

export function HomeHeader({
walletAccountId,
onWalletAccountChange,
}: HomeHeaderProps) {
const { user } = useUser()
const { i18n } = useLingui()

return (
<View className="flex bg-card px-6 pb-3 flex-row items-center justify-between">
Expand All @@ -18,15 +24,10 @@ export function HomeHeader() {
<Text className="font-medium text-muted-foreground text-sm font-sans">
{user?.fullName ?? user?.primaryEmailAddress?.emailAddress}
</Text>
<TouchableOpacity
activeOpacity={0.8}
className="gap-2 items-center flex-row"
>
<Text className="text-primary font-sans font-medium">
{t(i18n)`All Accounts`}
</Text>
<ArrowDownUp className="w-4 h-4 text-muted-foreground" />
</TouchableOpacity>
<SelectWalletAccount
value={walletAccountId}
onSelect={onWalletAccountChange}
/>
</View>
</View>
<Button variant="secondary" size="icon">
Expand Down
87 changes: 87 additions & 0 deletions apps/mobile/components/home/select-wallet-account.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useWallets } from '@/queries/wallet'
import { t } from '@lingui/macro'
import { useLingui } from '@lingui/react'
import { ArrowDownUp } from 'lucide-react-native'
import { useMemo } from 'react'
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '../ui/select'

export function SelectWalletAccount({
value,
onSelect,
disabled,
}: {
value?: string
onSelect?: (type?: string) => void
disabled?: boolean
}) {
const { i18n } = useLingui()
const { data: walletAccounts } = useWallets()

const defaultValue = useMemo(
() => ({
value: 'ALL',
label: t(i18n)`All accounts`,
}),
[i18n],
)

const options = useMemo(
() => [
defaultValue,
...(walletAccounts?.map((walletAccount) => ({
value: walletAccount.id,
label: walletAccount.name,
})) || []),
],
[walletAccounts, defaultValue],
)

return (
<Select
defaultValue={defaultValue}
value={options.find((option) => option.value === value) ?? defaultValue}
onValueChange={(selected) => {
if (selected?.value === 'ALL') {
onSelect?.(undefined)
return
}
onSelect?.(selected?.value)
}}
>
<SelectTrigger
disabled={disabled}
hideArrow
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
className="gap-2 items-center flex-row !border-none !border-transparent px-0 !py-0 !h-6"
>
<SelectValue
className="text-primary font-sans font-medium"
placeholder={t(i18n)`All Accounts`}
>
{value}
</SelectValue>
<ArrowDownUp className="w-4 h-4 text-muted-foreground" />
</SelectTrigger>
<SelectContent sideOffset={6}>
<SelectGroup className="px-1">
{options.map((option) => (
<SelectItem
key={option.value}
value={option.value}
label={option.label}
>
{option.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
)
}
18 changes: 11 additions & 7 deletions apps/mobile/components/ui/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ const SelectValue = SelectPrimitive.Value

const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {
hideArrow?: boolean
}
>(({ className, children, hideArrow, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
Expand All @@ -32,11 +34,13 @@ const SelectTrigger = React.forwardRef<
>
{/* biome-ignore lint/complexity/noUselessFragments: <explanation> */}
<>{children}</>
<ChevronDown
size={16}
aria-hidden={true}
className="text-foreground opacity-50"
/>
{!hideArrow && (
<ChevronDown
size={16}
aria-hidden={true}
className="text-foreground opacity-50"
/>
)}
</SelectPrimitive.Trigger>
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
Expand Down
1 change: 1 addition & 0 deletions packages/validation/src/transaction.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type TransactionFormValues = z.infer<typeof zTransactionFormValues>
export const TransactionPopulatedSchema = TransactionSchema.extend({
category: CategorySchema.nullable().optional(),
amount: z.number({ coerce: true }),
amountInVnd: z.number({ coerce: true }),
})

export type TransactionPopulated = z.infer<typeof TransactionPopulatedSchema>

0 comments on commit f6486e3

Please sign in to comment.