aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/expense-form.tsx
diff options
context:
space:
mode:
authorMert Demir <mertd@users.noreply.github.com>2024-02-05 02:23:11 +0900
committerGitHub <noreply@github.com>2024-02-04 12:23:11 -0500
commitfb49fb596a56955ca70eac9da47d2826299469e1 (patch)
tree71dd092faf01d37b35a8015e3cfda494ddc7b99e /src/components/expense-form.tsx
parent10fd69404a69b15d5c0888d9382663f324455ec0 (diff)
Automatic category from expense title (#80)
* environment variable * random category draft * get category from ai * input limit and documentation * use watch * use field.name * prettier * presigned upload, readme warning, category to string util * prettier * check whether feature is enabled * use process.env * improved prompt to return id only * remove console.debug * show loader * share class name * prettier * use template literals * rename format util * prettier
Diffstat (limited to 'src/components/expense-form.tsx')
-rw-r--r--src/components/expense-form.tsx19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/components/expense-form.tsx b/src/components/expense-form.tsx
index 3d6c2da..431afc0 100644
--- a/src/components/expense-form.tsx
+++ b/src/components/expense-form.tsx
@@ -40,8 +40,10 @@ import { cn } from '@/lib/utils'
import { zodResolver } from '@hookform/resolvers/zod'
import { Save, Trash2 } from 'lucide-react'
import { useSearchParams } from 'next/navigation'
+import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { match } from 'ts-pattern'
+import { extractCategoryFromTitle } from './expense-form-actions'
export type Props = {
group: NonNullable<Awaited<ReturnType<typeof getGroup>>>
@@ -133,6 +135,7 @@ export function ExpenseForm({
: [],
},
})
+ const [isCategoryLoading, setCategoryLoading] = useState(false)
return (
<Form {...form}>
@@ -155,6 +158,17 @@ export function ExpenseForm({
placeholder="Monday evening restaurant"
className="text-base"
{...field}
+ onBlur={async () => {
+ field.onBlur() // avoid skipping other blur event listeners since we overwrite `field`
+ if (process.env.NEXT_PUBLIC_ENABLE_CATEGORY_EXTRACT) {
+ setCategoryLoading(true)
+ const { categoryId } = await extractCategoryFromTitle(
+ field.value,
+ )
+ form.setValue('category', categoryId)
+ setCategoryLoading(false)
+ }
+ }}
/>
</FormControl>
<FormDescription>
@@ -239,8 +253,11 @@ export function ExpenseForm({
<FormLabel>Category</FormLabel>
<CategorySelector
categories={categories}
- defaultValue={field.value}
+ defaultValue={
+ form.watch(field.name) // may be overwritten externally
+ }
onValueChange={field.onChange}
+ isLoading={isCategoryLoading}
/>
<FormDescription>
Select the expense category.