(squash) init

feat: filters, settings, backups

fix: ts compile errors

feat: new dashboard, webp previews and settings

feat: use webp for pdfs

feat: use webp

fix: analyze resets old data

fix: switch to corsproxy

fix: switch to free cors

fix: max upload limit

fix: currency conversion

feat: transaction export

fix: currency conversion

feat: refactor settings actions

feat: new loader

feat: README + LICENSE

doc: update readme

doc: update readme

doc: update readme

doc: update screenshots

ci: bump prisma
This commit is contained in:
Vasily Zubarev
2025-03-13 00:30:47 +01:00
commit 0b98a2c307
153 changed files with 17271 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
import { getTransactionById } from "@/data/transactions"
import { notFound } from "next/navigation"
export default async function TransactionLayout({
children,
params,
}: {
children: React.ReactNode
params: Promise<{ transactionId: string }>
}) {
const { transactionId } = await params
const transaction = await getTransactionById(transactionId)
if (!transaction) {
notFound()
}
return (
<>
<header className="flex items-center justify-between">
<h2 className="text-3xl font-bold tracking-tight">Transaction Details</h2>
</header>
<main>
<div className="flex flex-1 flex-col gap-4 pt-0">{children}</div>
</main>
</>
)
}

View File

@@ -0,0 +1,7 @@
import { Skeleton } from "@/components/ui/skeleton"
export default function Loading() {
return (
<Skeleton className="flex flex-row flex-wrap md:flex-nowrap justify-center items-start gap-10 p-5 bg-accent max-w-[1200px] min-h-[800px]" />
)
}

View File

@@ -0,0 +1,62 @@
import { FormTextarea } from "@/components/forms/simple"
import TransactionEditForm from "@/components/transactions/edit"
import TransactionFiles from "@/components/transactions/transaction-files"
import { Card } from "@/components/ui/card"
import { getCategories } from "@/data/categories"
import { getCurrencies } from "@/data/currencies"
import { getFields } from "@/data/fields"
import { getFilesByTransactionId } from "@/data/files"
import { getProjects } from "@/data/projects"
import { getSettings } from "@/data/settings"
import { getTransactionById } from "@/data/transactions"
import { notFound } from "next/navigation"
export default async function TransactionPage({ params }: { params: Promise<{ transactionId: string }> }) {
const { transactionId } = await params
const transaction = await getTransactionById(transactionId)
if (!transaction) {
notFound()
}
const files = await getFilesByTransactionId(transactionId)
const categories = await getCategories()
const currencies = await getCurrencies()
const settings = await getSettings()
const fields = await getFields()
const projects = await getProjects()
return (
<>
<Card className="flex flex-col md:flex-row flex-wrap justify-center items-start gap-10 p-5 bg-accent max-w-6xl">
<div className="flex-1">
<TransactionEditForm
transaction={transaction}
categories={categories}
currencies={currencies}
settings={settings}
fields={fields}
projects={projects}
/>
</div>
<div className="max-w-[320px] space-y-4">
<TransactionFiles transaction={transaction} files={files} />
</div>
</Card>
{transaction.text && (
<Card className="flex items-stretch p-5 mt-10 max-w-6xl">
<div className="flex-1">
<FormTextarea
title="Recognized Text"
name="text"
defaultValue={transaction.text || ""}
hideIfEmpty={true}
className="w-full h-[400px]"
/>
</div>
</Card>
)}
</>
)
}