Skip to content

Commit

Permalink
feat(mobile): add update category
Browse files Browse the repository at this point in the history
  • Loading branch information
duongdev committed Jul 8, 2024
1 parent 4f2a0d0 commit cf82d5b
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 12 deletions.
2 changes: 1 addition & 1 deletion apps/mobile/app/(app)/(tabs)/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export default function SettingsScreen() {
}
/>
</Link>
<Link href="/categories" asChild>
<Link href="/category" asChild>
<MenuItem
label={t(i18n)`Categories`}
icon={ShapesIcon}
Expand Down
13 changes: 10 additions & 3 deletions apps/mobile/app/(app)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ export default function AuthenticatedLayout() {
}}
/>
<Stack.Screen
name="categories/index"
name="category/index"
options={{
headerTitle: t(i18n)`Categories`,
headerRight: () => (
<Link href="/categories/new-category" asChild>
<Link href="/category/new-category" asChild>
<Button size="icon" variant="ghost">
<PlusIcon className="size-6 text-primary" />
</Button>
Expand All @@ -107,12 +107,19 @@ export default function AuthenticatedLayout() {
}}
/>
<Stack.Screen
name="categories/new-category"
name="category/new-category"
options={{
presentation: 'modal',
headerTitle: t(i18n)`New category`,
}}
/>
<Stack.Screen
name="category/[categoryId]"
options={{
// presentation: 'modal',
headerTitle: t(i18n)`Edit category`,
}}
/>
</Stack>
)
}
54 changes: 54 additions & 0 deletions apps/mobile/app/(app)/category/[categoryId].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { CategoryForm } from '@/components/category/category-form'
import { Text } from '@/components/ui/text'
import { updateCategory } from '@/mutations/category'
import { categoryQueries, useCategories } from '@/queries/category'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useLocalSearchParams, useNavigation, useRouter } from 'expo-router'
import { Alert, ScrollView, View } from 'react-native'

export default function EditCategoryScreen() {
const { categoryId } = useLocalSearchParams<{ categoryId: string }>()
const { data: categories = [] } = useCategories()
const queryClient = useQueryClient()
const router = useRouter()
const navigation = useNavigation()

const { mutateAsync: mutateUpdate } = useMutation({
mutationFn: updateCategory,
onError(error) {
Alert.alert(error.message)
},
onSuccess() {
router.back()
},
async onSettled() {
await queryClient.invalidateQueries({
queryKey: categoryQueries.list._def,
})
},
throwOnError: true,
})

const category = categories.find((category) => category.id === categoryId)

if (!category) {
return (
<View className="flex-1 bg-card items-center justify-center">
<Text className="text-muted-foreground">Category not found</Text>
</View>
)
}

return (
<ScrollView className="bg-card px-6 py-3">
<CategoryForm
onSubmit={() => {}}
defaultValues={{
name: category?.name,
icon: category?.icon!,
type: category?.type,
}}
/>
</ScrollView>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function CategoriesScreen() {
label={t(i18n)`New ${section.key.toLowerCase()}`}
onPress={() =>
router.push({
pathname: '/categories/new-category',
pathname: '/category/new-category',
params: { type: section.key },
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { Alert, View } from 'react-native'

export default function CreateCategoryScreen() {
const router = useRouter()
const { type } = useLocalSearchParams<{ type?: CategoryTypeType }>()
const { type = 'EXPENSE' } = useLocalSearchParams<{
type?: CategoryTypeType
}>()
const queryClient = useQueryClient()
const { mutateAsync } = useMutation({
mutationFn: createCategory,
Expand Down
14 changes: 11 additions & 3 deletions apps/mobile/components/category/category-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ export const CategoryForm = ({
resolver: zodResolver(zCategoryFormValues),
defaultValues: {
name: '',
type: 'EXPENSE',
icon: 'CreditCard',
...defaultValues,
type: defaultValues?.type || 'EXPENSE',
},
})

Expand All @@ -45,8 +45,10 @@ export const CategoryForm = ({
autoCapitalize="none"
autoFocus={!defaultValues}
className="!pl-[62px]"
disabled={categoryForm.formState.isLoading}
leftSection={
<SelectCategoryIconField
disabled={categoryForm.formState.isLoading}
onSelect={() => nameInputRef.current?.focus()}
/>
}
Expand All @@ -63,10 +65,16 @@ export const CategoryForm = ({
onValueChange={field.onChange}
>
<TabsList>
<TabsTrigger value="EXPENSE">
<TabsTrigger
disabled={categoryForm.formState.isLoading}
value="EXPENSE"
>
<Text>{t(i18n)`Expense`}</Text>
</TabsTrigger>
<TabsTrigger value="INCOME">
<TabsTrigger
disabled={categoryForm.formState.isLoading}
value="INCOME"
>
<Text>{t(i18n)`Income`}</Text>
</TabsTrigger>
</TabsList>
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/components/category/category-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const CategoryItem: FC<CategoryItemProps> = ({ category }) => {
asChild
push
href={{
pathname: '/categories/[categoryId]',
pathname: '/category/[categoryId]',
params: { categoryId: category.id },
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { Button } from '../ui/button'

export function SelectCategoryIconField({
onSelect,
disabled,
}: {
onSelect?: (currency: string) => void
disabled?: boolean
}) {
const sheetRef = useRef<BottomSheetModal>(null)
const {
Expand All @@ -23,6 +25,7 @@ export function SelectCategoryIconField({
<>
<Button
variant="ghost"
disabled={disabled}
onPress={() => {
Keyboard.dismiss()
sheetRef.current?.present()
Expand Down
7 changes: 5 additions & 2 deletions apps/mobile/components/form-fields/input-field.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { cn } from '@/lib/utils'
import { forwardRef } from 'react'
import { useController } from 'react-hook-form'
import { Text, type TextInputProps, View, type TextInput } from 'react-native'
import { Text, type TextInput, type TextInputProps, View } from 'react-native'
import { Input } from '../ui/input'
import { Label } from '../ui/label'
import { forwardRef } from 'react'

type InputFieldProps = TextInputProps & {
name: string
label?: string
leftSection?: React.ReactNode
rightSection?: React.ReactNode
disabled?: boolean
}

export const InputField = forwardRef(
Expand All @@ -20,6 +21,7 @@ export const InputField = forwardRef(
leftSection,
rightSection,
className,
disabled,
...props
}: InputFieldProps,
ref: React.Ref<TextInput>,
Expand Down Expand Up @@ -47,6 +49,7 @@ export const InputField = forwardRef(
leftSection && 'pl-10',
rightSection && 'pr-10',
)}
editable={!disabled}
{...props}
/>
{rightSection && (
Expand Down
28 changes: 28 additions & 0 deletions apps/mobile/mutations/category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,31 @@ export async function createCategory(data: CategoryFormValues) {

return result
}

export async function updateCategory({
id,
data,
}: {
id: string
data: CategoryFormValues
}) {
const hc = await getHonoClient()
const result = await hc.v1.categories[':categoryId'].$put({
param: { categoryId: id },
json: data,
})

if (result.ok) {
const category = CategorySchema.parse(await result.json())
return category
}

return result
}

export async function deleteCategory(id: string) {
const hc = await getHonoClient()
await hc.v1.categories[':categoryId'].$delete({
param: { categoryId: id },
})
}

0 comments on commit cf82d5b

Please sign in to comment.