fix: respect field.name for standard fields

This commit is contained in:
Vasily Zubarev
2025-04-08 22:55:22 +02:00
parent 88ee3724b2
commit 707a030a0a
3 changed files with 57 additions and 43 deletions

View File

@@ -12,7 +12,7 @@ import { Category, Currency, Field, Project, Transaction } from "@prisma/client"
import { format } from "date-fns" import { format } from "date-fns"
import { Loader2 } from "lucide-react" import { Loader2 } from "lucide-react"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import { startTransition, useActionState, useEffect, useState } from "react" import { startTransition, useActionState, useEffect, useMemo, useState } from "react"
export default function TransactionEditForm({ export default function TransactionEditForm({
transaction, transaction,
@@ -56,6 +56,16 @@ export default function TransactionEditForm({
), ),
}) })
const fieldMap = useMemo(() => {
return fields.reduce(
(acc, field) => {
acc[field.code] = field
return acc
},
{} as Record<string, Field>
)
}, [fields])
const handleDelete = async () => { const handleDelete = async () => {
if (confirm("Are you sure? This will delete the transaction with all the files permanently")) { if (confirm("Are you sure? This will delete the transaction with all the files permanently")) {
startTransition(async () => { startTransition(async () => {
@@ -75,15 +85,15 @@ export default function TransactionEditForm({
<form action={saveAction} className="space-y-4"> <form action={saveAction} className="space-y-4">
<input type="hidden" name="transactionId" value={transaction.id} /> <input type="hidden" name="transactionId" value={transaction.id} />
<FormInput title="Name" name="name" defaultValue={formData.name} /> <FormInput title={fieldMap.name.name} name="name" defaultValue={formData.name} />
<FormInput title="Merchant" name="merchant" defaultValue={formData.merchant} /> <FormInput title={fieldMap.merchant.name} name="merchant" defaultValue={formData.merchant} />
<FormInput title="Description" name="description" defaultValue={formData.description} /> <FormInput title={fieldMap.description.name} name="description" defaultValue={formData.description} />
<div className="flex flex-row gap-4"> <div className="flex flex-row gap-4">
<FormInput <FormInput
title="Total" title={fieldMap.total.name}
type="number" type="number"
step="0.01" step="0.01"
name="total" name="total"
@@ -92,7 +102,7 @@ export default function TransactionEditForm({
/> />
<FormSelectCurrency <FormSelectCurrency
title="Currency" title={fieldMap.currencyCode.name}
name="currencyCode" name="currencyCode"
value={formData.currencyCode} value={formData.currencyCode}
onValueChange={(value) => { onValueChange={(value) => {
@@ -101,7 +111,7 @@ export default function TransactionEditForm({
currencies={currencies} currencies={currencies}
/> />
<FormSelectType title="Type" name="type" defaultValue={formData.type} /> <FormSelectType title={fieldMap.type.name} name="type" defaultValue={formData.type} />
</div> </div>
{formData.currencyCode !== settings.default_currency || formData.convertedTotal !== 0 ? ( {formData.currencyCode !== settings.default_currency || formData.convertedTotal !== 0 ? (
@@ -127,21 +137,26 @@ export default function TransactionEditForm({
)} )}
<div className="flex flex-row flex-grow gap-4"> <div className="flex flex-row flex-grow gap-4">
<FormInput title="Issued At" type="date" name="issuedAt" defaultValue={formData.issuedAt} /> <FormInput title={fieldMap.issuedAt.name} type="date" name="issuedAt" defaultValue={formData.issuedAt} />
</div> </div>
<div className="flex flex-row gap-4"> <div className="flex flex-row gap-4">
<FormSelectCategory <FormSelectCategory
title="Category" title={fieldMap.categoryCode.name}
categories={categories} categories={categories}
name="categoryCode" name="categoryCode"
defaultValue={formData.categoryCode} defaultValue={formData.categoryCode}
/> />
<FormSelectProject title="Project" projects={projects} name="projectCode" defaultValue={formData.projectCode} /> <FormSelectProject
title={fieldMap.projectCode.name}
projects={projects}
name="projectCode"
defaultValue={formData.projectCode}
/>
</div> </div>
<FormTextarea title="Note" name="note" defaultValue={formData.note} className="h-24" /> <FormTextarea title={fieldMap.note.name} name="note" defaultValue={formData.note} className="h-24" />
{extraFields.map((field) => ( {extraFields.map((field) => (
<FormInput <FormInput
key={field.code} key={field.code}

View File

@@ -247,7 +247,7 @@ export function TransactionList({ transactions, fields = [] }: { transactions: T
)} )}
onClick={() => field.renderer.sortable && handleSort(field.code)} onClick={() => field.renderer.sortable && handleSort(field.code)}
> >
{field.renderer.name} {field.name || field.renderer.name}
{field.renderer.sortable && getSortIcon(field.code)} {field.renderer.sortable && getSortIcon(field.code)}
</TableHead> </TableHead>
))} ))}

View File

@@ -37,17 +37,16 @@ export default function AnalyzeForm({
const [isSaving, setIsSaving] = useState(false) const [isSaving, setIsSaving] = useState(false)
const [saveError, setSaveError] = useState("") const [saveError, setSaveError] = useState("")
const fieldsMap = useMemo( const fieldMap = useMemo(() => {
() => return fields.reduce(
fields.reduce( (acc, field) => {
(acc, field) => { acc[field.code] = field
acc[field.code] = field return acc
return acc },
}, {} as Record<string, Field>
{} as Record<string, Field> )
), }, [fields])
[fields]
)
const extraFields = useMemo(() => fields.filter((field) => field.isExtra), [fields]) const extraFields = useMemo(() => fields.filter((field) => field.isExtra), [fields])
const initialFormState = useMemo( const initialFormState = useMemo(
() => ({ () => ({
@@ -141,7 +140,7 @@ export default function AnalyzeForm({
<form className="space-y-4" action={saveAsTransaction}> <form className="space-y-4" action={saveAsTransaction}>
<input type="hidden" name="fileId" value={file.id} /> <input type="hidden" name="fileId" value={file.id} />
<FormInput <FormInput
title="Name" title={fieldMap.name.name}
name="name" name="name"
value={formData.name} value={formData.name}
onChange={(e) => setFormData((prev) => ({ ...prev, name: e.target.value }))} onChange={(e) => setFormData((prev) => ({ ...prev, name: e.target.value }))}
@@ -149,24 +148,24 @@ export default function AnalyzeForm({
/> />
<FormInput <FormInput
title="Merchant" title={fieldMap.merchant.name}
name="merchant" name="merchant"
value={formData.merchant} value={formData.merchant}
onChange={(e) => setFormData((prev) => ({ ...prev, merchant: e.target.value }))} onChange={(e) => setFormData((prev) => ({ ...prev, merchant: e.target.value }))}
hideIfEmpty={!fieldsMap["merchant"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.merchant.isVisibleInAnalysis}
/> />
<FormInput <FormInput
title="Description" title={fieldMap.description.name}
name="description" name="description"
value={formData.description} value={formData.description}
onChange={(e) => setFormData((prev) => ({ ...prev, description: e.target.value }))} onChange={(e) => setFormData((prev) => ({ ...prev, description: e.target.value }))}
hideIfEmpty={!fieldsMap["description"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.description.isVisibleInAnalysis}
/> />
<div className="flex flex-wrap gap-4"> <div className="flex flex-wrap gap-4">
<FormInput <FormInput
title="Total" title={fieldMap.total.name}
name="total" name="total"
type="number" type="number"
step="0.01" step="0.01"
@@ -180,20 +179,20 @@ export default function AnalyzeForm({
/> />
<FormSelectCurrency <FormSelectCurrency
title="Currency" title={fieldMap.currencyCode.name}
currencies={currencies} currencies={currencies}
name="currencyCode" name="currencyCode"
value={formData.currencyCode} value={formData.currencyCode}
onValueChange={(value) => setFormData((prev) => ({ ...prev, currencyCode: value }))} onValueChange={(value) => setFormData((prev) => ({ ...prev, currencyCode: value }))}
hideIfEmpty={!fieldsMap["currencyCode"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.currencyCode.isVisibleInAnalysis}
/> />
<FormSelectType <FormSelectType
title="Type" title={fieldMap.type.name}
name="type" name="type"
value={formData.type} value={formData.type}
onValueChange={(value) => setFormData((prev) => ({ ...prev, type: value }))} onValueChange={(value) => setFormData((prev) => ({ ...prev, type: value }))}
hideIfEmpty={!fieldsMap["type"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.type.isVisibleInAnalysis}
/> />
</div> </div>
@@ -212,45 +211,45 @@ export default function AnalyzeForm({
<div className="flex flex-row gap-4"> <div className="flex flex-row gap-4">
<FormInput <FormInput
title="Issued At" title={fieldMap.issuedAt.name}
type="date" type="date"
name="issuedAt" name="issuedAt"
value={formData.issuedAt} value={formData.issuedAt}
onChange={(e) => setFormData((prev) => ({ ...prev, issuedAt: e.target.value }))} onChange={(e) => setFormData((prev) => ({ ...prev, issuedAt: e.target.value }))}
hideIfEmpty={!fieldsMap["issuedAt"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.issuedAt.isVisibleInAnalysis}
/> />
</div> </div>
<div className="flex flex-row gap-4"> <div className="flex flex-row gap-4">
<FormSelectCategory <FormSelectCategory
title="Category" title={fieldMap.categoryCode.name}
categories={categories} categories={categories}
name="categoryCode" name="categoryCode"
value={formData.categoryCode} value={formData.categoryCode}
onValueChange={(value) => setFormData((prev) => ({ ...prev, categoryCode: value }))} onValueChange={(value) => setFormData((prev) => ({ ...prev, categoryCode: value }))}
placeholder="Select Category" placeholder="Select Category"
hideIfEmpty={!fieldsMap["categoryCode"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.categoryCode.isVisibleInAnalysis}
/> />
{projects.length > 0 && ( {projects.length > 0 && (
<FormSelectProject <FormSelectProject
title="Project" title={fieldMap.projectCode.name}
projects={projects} projects={projects}
name="projectCode" name="projectCode"
value={formData.projectCode} value={formData.projectCode}
onValueChange={(value) => setFormData((prev) => ({ ...prev, projectCode: value }))} onValueChange={(value) => setFormData((prev) => ({ ...prev, projectCode: value }))}
placeholder="Select Project" placeholder="Select Project"
hideIfEmpty={!fieldsMap["projectCode"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.projectCode.isVisibleInAnalysis}
/> />
)} )}
</div> </div>
<FormInput <FormInput
title="Note" title={fieldMap.note.name}
name="note" name="note"
value={formData.note} value={formData.note}
onChange={(e) => setFormData((prev) => ({ ...prev, note: e.target.value }))} onChange={(e) => setFormData((prev) => ({ ...prev, note: e.target.value }))}
hideIfEmpty={!fieldsMap["note"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.note.isVisibleInAnalysis}
/> />
{extraFields.map((field) => ( {extraFields.map((field) => (
@@ -267,11 +266,11 @@ export default function AnalyzeForm({
<div className="hidden"> <div className="hidden">
<FormTextarea <FormTextarea
title="Recognized Text" title={fieldMap.text.name}
name="text" name="text"
value={formData.text} value={formData.text}
onChange={(e) => setFormData((prev) => ({ ...prev, text: e.target.value }))} onChange={(e) => setFormData((prev) => ({ ...prev, text: e.target.value }))}
hideIfEmpty={!fieldsMap["text"]?.isVisibleInAnalysis} hideIfEmpty={!fieldMap.text.isVisibleInAnalysis}
/> />
</div> </div>