mirror of
https://codeberg.org/MarkusThielker/finances.git
synced 2025-04-12 05:08:43 +00:00
Release v1.0.1 (#28)
This commit is contained in:
commit
6ea3d90fbb
6 changed files with 118 additions and 61 deletions
|
@ -8,6 +8,9 @@ const nextConfig = {
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
output: 'standalone',
|
output: 'standalone',
|
||||||
|
env: {
|
||||||
|
appVersion: process.env.npm_package_version,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -1,12 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "next-finances",
|
"name": "next-finances",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "next-finances",
|
"name": "next-finances",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.3.4",
|
"@hookform/resolvers": "^3.3.4",
|
||||||
"@lucia-auth/adapter-prisma": "^4.0.0",
|
"@lucia-auth/adapter-prisma": "^4.0.0",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "next-finances",
|
"name": "next-finances",
|
||||||
"description": "A finances application to keep track of my personal spendings",
|
"description": "A finances application to keep track of my personal spendings",
|
||||||
"homepage": "https://github.com/MarkusThielker/next-finances",
|
"homepage": "https://github.com/MarkusThielker/next-finances",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Markus Thielker"
|
"name": "Markus Thielker"
|
||||||
|
|
|
@ -20,26 +20,25 @@ export default async function AccountPage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let paymentCount = 0;
|
let paymentCount = 0;
|
||||||
let entityCount = 0;
|
paymentCount = await prismaClient.payment.count({
|
||||||
let categoryCount = 0;
|
where: {
|
||||||
|
userId: user.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
let entityCount = 0;
|
||||||
paymentCount = await prismaClient.payment.count({
|
entityCount = await prismaClient.entity.count({
|
||||||
where: {
|
where: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
entityCount = await prismaClient.entity.count({
|
|
||||||
where: {
|
let categoryCount = 0;
|
||||||
userId: user.id,
|
categoryCount = await prismaClient.category.count({
|
||||||
},
|
where: {
|
||||||
});
|
userId: user.id,
|
||||||
categoryCount = await prismaClient.category.count({
|
},
|
||||||
where: {
|
});
|
||||||
userId: user.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
|
@ -91,6 +90,23 @@ export default async function AccountPage() {
|
||||||
<SignOutForm onSubmit={signOut}/>
|
<SignOutForm onSubmit={signOut}/>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
|
<div className="flex w-full items-center justify-between max-w-md mt-2 text-neutral-600">
|
||||||
|
<p>Version {process.env.appVersion}</p>
|
||||||
|
<div className="flex items-center justify-between space-x-4">
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
className="hover:text-neutral-500 duration-100"
|
||||||
|
href="https://github.com/MarkusThielker/next-finances">
|
||||||
|
Source Code
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
className="hover:text-neutral-500 duration-100"
|
||||||
|
href="https://github.com/MarkusThielker/next-finances/releases">
|
||||||
|
Changelog
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,15 @@ export const columns = (
|
||||||
header: 'Category',
|
header: 'Category',
|
||||||
cell: ({row}) => {
|
cell: ({row}) => {
|
||||||
const category = categories.find((category) => category.id === row.original.categoryId);
|
const category = categories.find((category) => category.id === row.original.categoryId);
|
||||||
return category?.name ?? '-';
|
return (
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
|
<svg className="h-5" fill={category?.color} viewBox="0 0 20 20"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle cx="10" cy="10" r="10"/>
|
||||||
|
</svg>
|
||||||
|
<p>{category?.name ?? '-'}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,8 +4,9 @@ import { ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, useReact
|
||||||
|
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';
|
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
|
|
||||||
interface DataTableProps<TData, TValue> {
|
interface DataTableProps<TData, TValue> {
|
||||||
columns: ColumnDef<TData, TValue>[];
|
columns: ColumnDef<TData, TValue>[];
|
||||||
|
@ -20,6 +21,7 @@ export function DataTable<TData, TValue>({
|
||||||
pagination,
|
pagination,
|
||||||
className,
|
className,
|
||||||
}: DataTableProps<TData, TValue>) {
|
}: DataTableProps<TData, TValue>) {
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data,
|
||||||
columns,
|
columns,
|
||||||
|
@ -27,6 +29,13 @@ export function DataTable<TData, TValue>({
|
||||||
getPaginationRowModel: pagination ? getPaginationRowModel() : undefined,
|
getPaginationRowModel: pagination ? getPaginationRowModel() : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [pageSize, setPageSize] = useState(50);
|
||||||
|
useEffect(() => {
|
||||||
|
if (pagination) {
|
||||||
|
table.setPageSize(pageSize);
|
||||||
|
}
|
||||||
|
}, [table, pagination, pageSize]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
<div className="rounded-md border">
|
<div className="rounded-md border">
|
||||||
|
@ -57,7 +66,8 @@ export function DataTable<TData, TValue>({
|
||||||
data-state={row.getIsSelected() && 'selected'}
|
data-state={row.getIsSelected() && 'selected'}
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<TableCell key={cell.id}>
|
<TableCell key={cell.id}
|
||||||
|
className={cell.id.endsWith('actions') ? 'w-[120px]' : ''}>
|
||||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
|
@ -75,43 +85,62 @@ export function DataTable<TData, TValue>({
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
pagination && (
|
pagination && (
|
||||||
<div className="flex items-center justify-end space-x-2 py-4">
|
<div className="flex items-center justify-between py-4">
|
||||||
<Button
|
<Select
|
||||||
variant="outline"
|
onValueChange={(value) => {
|
||||||
size="icon"
|
setPageSize(parseInt(value));
|
||||||
onClick={() => table.firstPage()}
|
}}
|
||||||
disabled={!table.getCanPreviousPage()}
|
value={pageSize.toString()}
|
||||||
>
|
>
|
||||||
<span className="sr-only">First page</span>
|
<SelectTrigger className="w-[150px]">
|
||||||
<ChevronsLeft/>
|
<SelectValue placeholder="Select a scope"/>
|
||||||
</Button>
|
</SelectTrigger>
|
||||||
<Button
|
<SelectContent>
|
||||||
variant="outline"
|
<SelectItem value={'25'} key={'25'}>25</SelectItem>
|
||||||
size="icon"
|
<SelectItem value={'50'} key={'50'}>50</SelectItem>
|
||||||
onClick={() => table.previousPage()}
|
<SelectItem value={'75'} key={'75'}>75</SelectItem>
|
||||||
disabled={!table.getCanPreviousPage()}
|
<SelectItem value={'100'} key={'100'}>100</SelectItem>
|
||||||
>
|
</SelectContent>
|
||||||
<span className="sr-only">Previous page</span>
|
</Select>
|
||||||
<ChevronLeft/>
|
|
||||||
</Button>
|
<div className="flex flex-row items-center space-x-2">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => table.nextPage()}
|
onClick={() => table.firstPage()}
|
||||||
disabled={!table.getCanNextPage()}
|
disabled={!table.getCanPreviousPage()}
|
||||||
>
|
>
|
||||||
<span className="sr-only">Next page</span>
|
<span className="sr-only">First page</span>
|
||||||
<ChevronRight/>
|
<ChevronsLeft/>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => table.lastPage()}
|
onClick={() => table.previousPage()}
|
||||||
disabled={!table.getCanNextPage()}
|
disabled={!table.getCanPreviousPage()}
|
||||||
>
|
>
|
||||||
<span className="sr-only">Last page</span>
|
<span className="sr-only">Previous page</span>
|
||||||
<ChevronsRight/>
|
<ChevronLeft/>
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.nextPage()}
|
||||||
|
disabled={!table.getCanNextPage()}
|
||||||
|
>
|
||||||
|
<span className="sr-only">Next page</span>
|
||||||
|
<ChevronRight/>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.lastPage()}
|
||||||
|
disabled={!table.getCanNextPage()}
|
||||||
|
>
|
||||||
|
<span className="sr-only">Last page</span>
|
||||||
|
<ChevronsRight/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue