mirror of
https://github.com/spliit-app/spliit.git
synced 2026-03-05 04:06:13 +01:00
Improve receipt scanning
This commit is contained in:
105
package-lock.json
generated
105
package-lock.json
generated
@@ -1278,6 +1278,111 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { useToast } from '@/components/ui/use-toast'
|
|||||||
import { useMediaQuery } from '@/lib/hooks'
|
import { useMediaQuery } from '@/lib/hooks'
|
||||||
import { formatExpenseDate } from '@/lib/utils'
|
import { formatExpenseDate } from '@/lib/utils'
|
||||||
import { Category } from '@prisma/client'
|
import { Category } from '@prisma/client'
|
||||||
import { ChevronRight, Loader2, Receipt } from 'lucide-react'
|
import { ChevronRight, FileQuestion, Loader2, Receipt } from 'lucide-react'
|
||||||
import { getImageData, useS3Upload } from 'next-s3-upload'
|
import { getImageData, useS3Upload } from 'next-s3-upload'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
@@ -154,21 +154,27 @@ export function CreateFromReceiptButton({
|
|||||||
</Button>
|
</Button>
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<strong>Title:</strong>
|
<strong>Title:</strong>
|
||||||
<div>{receiptInfo?.title ?? '…'}</div>
|
<div>{receiptInfo ? receiptInfo.title ?? <Unknown /> : '…'}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<strong>Category:</strong>
|
<strong>Category:</strong>
|
||||||
<div>
|
<div>
|
||||||
{receiptInfoCategory ? (
|
{receiptInfo ? (
|
||||||
<div className="flex items-center">
|
receiptInfoCategory ? (
|
||||||
<CategoryIcon
|
<div className="flex items-center">
|
||||||
category={receiptInfoCategory}
|
<CategoryIcon
|
||||||
className="inline w-4 h-4 mr-2"
|
category={receiptInfoCategory}
|
||||||
/>
|
className="inline w-4 h-4 mr-2"
|
||||||
<span className="mr-1">{receiptInfoCategory.grouping}</span>
|
/>
|
||||||
<ChevronRight className="inline w-3 h-3 mr-1" />
|
<span className="mr-1">
|
||||||
<span>{receiptInfoCategory.name}</span>
|
{receiptInfoCategory.grouping}
|
||||||
</div>
|
</span>
|
||||||
|
<ChevronRight className="inline w-3 h-3 mr-1" />
|
||||||
|
<span>{receiptInfoCategory.name}</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<Unknown />
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
'' || '…'
|
'' || '…'
|
||||||
)}
|
)}
|
||||||
@@ -177,10 +183,14 @@ export function CreateFromReceiptButton({
|
|||||||
<div>
|
<div>
|
||||||
<strong>Amount:</strong>
|
<strong>Amount:</strong>
|
||||||
<div>
|
<div>
|
||||||
{receiptInfo?.amount ? (
|
{receiptInfo ? (
|
||||||
<>
|
receiptInfo.amount ? (
|
||||||
{groupCurrency} {receiptInfo.amount.toFixed(2)}
|
<>
|
||||||
</>
|
{groupCurrency} {receiptInfo.amount.toFixed(2)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Unknown />
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
'…'
|
'…'
|
||||||
)}
|
)}
|
||||||
@@ -189,16 +199,22 @@ export function CreateFromReceiptButton({
|
|||||||
<div>
|
<div>
|
||||||
<strong>Date:</strong>
|
<strong>Date:</strong>
|
||||||
<div>
|
<div>
|
||||||
{receiptInfo?.date
|
{receiptInfo ? (
|
||||||
? formatExpenseDate(
|
receiptInfo.date ? (
|
||||||
|
formatExpenseDate(
|
||||||
new Date(`${receiptInfo?.date}T12:00:00.000Z`),
|
new Date(`${receiptInfo?.date}T12:00:00.000Z`),
|
||||||
)
|
)
|
||||||
: '…'}
|
) : (
|
||||||
|
<Unknown />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
'…'
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>You’ll be able to edit the expense information after creating it.</p>
|
<p>You’ll be able to edit the expense information next.</p>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<Button
|
<Button
|
||||||
disabled={pending || !receiptInfo}
|
disabled={pending || !receiptInfo}
|
||||||
@@ -217,7 +233,7 @@ export function CreateFromReceiptButton({
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Create expense
|
Continue
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -225,6 +241,15 @@ export function CreateFromReceiptButton({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Unknown() {
|
||||||
|
return (
|
||||||
|
<div className="flex gap-1 items-center text-muted-foreground">
|
||||||
|
<FileQuestion className="w-4 h-4" />
|
||||||
|
<em>Unknown</em>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function CreateFromReceiptDialog({
|
function CreateFromReceiptDialog({
|
||||||
trigger,
|
trigger,
|
||||||
title,
|
title,
|
||||||
|
|||||||
Reference in New Issue
Block a user