First steps towards reusing the abstract API for expenses
This commit is contained in:
parent
0cdfccb0ca
commit
b15b90b494
@ -1,40 +1,40 @@
|
|||||||
/* Copyright (C) 2024 Manuel Bustillo*/
|
// /* Copyright (C) 2024 Manuel Bustillo*/
|
||||||
|
|
||||||
import { Expense } from '@/app/lib/definitions';
|
// import { Expense } from '@/app/lib/definitions';
|
||||||
import { getCsrfToken, getSlug } from '@/app/lib/utils';
|
// import { getCsrfToken, getSlug } from '@/app/lib/utils';
|
||||||
|
|
||||||
export function loadExpenses(onLoad?: (expenses: Expense[]) => void) {
|
// export function loadExpenses(onLoad?: (expenses: Expense[]) => void) {
|
||||||
fetch(`/api/${getSlug()}/expenses`)
|
// fetch(`/api/${getSlug()}/expenses`)
|
||||||
.then((response) => response.json())
|
// .then((response) => response.json())
|
||||||
.then((data) => {
|
// .then((data) => {
|
||||||
onLoad && onLoad(data.map((record: any) => {
|
// onLoad && onLoad(data.map((record: any) => {
|
||||||
return ({
|
// return ({
|
||||||
id: record.id,
|
// id: record.id,
|
||||||
name: record.name,
|
// name: record.name,
|
||||||
amount: record.amount,
|
// amount: record.amount,
|
||||||
pricingType: record.pricing_type
|
// pricingType: record.pricing_type
|
||||||
});
|
// });
|
||||||
}));
|
// }));
|
||||||
}, (error) => {
|
// }, (error) => {
|
||||||
return [];
|
// return [];
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function updateExpense(expense: Expense) {
|
// export function updateExpense(expense: Expense) {
|
||||||
fetch(`/api/${getSlug()}/expenses/${expense.id}`,
|
// fetch(`/api/${getSlug()}/expenses/${expense.id}`,
|
||||||
{
|
// {
|
||||||
method: 'PUT',
|
// method: 'PUT',
|
||||||
body: JSON.stringify({
|
// body: JSON.stringify({
|
||||||
expense: {
|
// expense: {
|
||||||
name: expense.name,
|
// name: expense.name,
|
||||||
amount: expense.amount,
|
// amount: expense.amount,
|
||||||
pricing_type: expense.pricingType,
|
// pricing_type: expense.pricingType,
|
||||||
}
|
// }
|
||||||
}),
|
// }),
|
||||||
headers: {
|
// headers: {
|
||||||
'Content-Type': 'application/json',
|
// 'Content-Type': 'application/json',
|
||||||
'X-CSRF-TOKEN': getCsrfToken(),
|
// 'X-CSRF-TOKEN': getCsrfToken(),
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
.catch((error) => console.error(error));
|
// .catch((error) => console.error(error));
|
||||||
}
|
// }
|
@ -6,12 +6,12 @@ export interface Entity {
|
|||||||
id?: string;
|
id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Expense = {
|
// export type Expense = {
|
||||||
id: string;
|
// id: string;
|
||||||
name: string;
|
// name: string;
|
||||||
amount: number;
|
// amount: number;
|
||||||
pricingType: 'fixed' | 'per person';
|
// pricingType: 'fixed' | 'per person';
|
||||||
};
|
// };
|
||||||
|
|
||||||
export type TableArrangement = {
|
export type TableArrangement = {
|
||||||
id: string;
|
id: string;
|
||||||
|
39
app/lib/expense.tsx
Normal file
39
app/lib/expense.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Serializable } from "../api/abstract-api";
|
||||||
|
import { Entity } from "./definitions";
|
||||||
|
|
||||||
|
export const pricingTypes = ['fixed', 'per person'] as const;
|
||||||
|
export type PricingType = typeof pricingTypes[number];
|
||||||
|
|
||||||
|
export class Expense implements Entity {
|
||||||
|
id?: string;
|
||||||
|
name: string;
|
||||||
|
amount: number;
|
||||||
|
pricingType: PricingType;
|
||||||
|
|
||||||
|
constructor(id?: string, name?: string, amount?: number, pricingType?: PricingType) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name || '';
|
||||||
|
this.amount = amount || 0;
|
||||||
|
this.pricingType = pricingType || 'fixed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExpenseSerializer implements Serializable<Expense>{
|
||||||
|
fromJson(data: any): Expense {
|
||||||
|
return new Expense(data.id, data.name, data.amount, data.pricing_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
toJson(expense: Expense): string {
|
||||||
|
return JSON.stringify({
|
||||||
|
expense: {
|
||||||
|
name: expense.name,
|
||||||
|
amount: expense.amount,
|
||||||
|
pricing_type: expense.pricingType
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apiPath(): string {
|
||||||
|
return 'expenses';
|
||||||
|
}
|
||||||
|
}
|
@ -2,18 +2,19 @@
|
|||||||
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { loadExpenses, updateExpense } from '@/app/api/expenses';
|
|
||||||
import { Expense } from '@/app/lib/definitions';
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import InlineTextField from "../components/form/inlineTextField";
|
import InlineTextField from "../components/form/inlineTextField";
|
||||||
import TableOfContents from "../components/table-of-contents";
|
import TableOfContents from "../components/table-of-contents";
|
||||||
|
import { AbstractApi } from '@/app/api/abstract-api';
|
||||||
|
import { Expense, ExpenseSerializer } from '@/app/lib/expense';
|
||||||
|
|
||||||
export default function ExpensesTable() {
|
export default function ExpensesTable() {
|
||||||
const [expenses, setExpenses] = useState<Array<Expense>>([]);
|
const [expenses, setExpenses] = useState<Array<Expense>>([]);
|
||||||
const [expensesLoaded, setExpensesLoaded] = useState(false);
|
const [expensesLoaded, setExpensesLoaded] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
function refreshExpenses() {
|
function refreshExpenses() {
|
||||||
loadExpenses((expenses) => {
|
new AbstractApi<Expense>().getAll(new ExpenseSerializer(), (expenses: Expense[]) => {
|
||||||
setExpenses(expenses);
|
setExpenses(expenses);
|
||||||
setExpensesLoaded(true);
|
setExpensesLoaded(true);
|
||||||
});
|
});
|
||||||
@ -21,6 +22,9 @@ export default function ExpensesTable() {
|
|||||||
|
|
||||||
!expensesLoaded && refreshExpenses();
|
!expensesLoaded && refreshExpenses();
|
||||||
|
|
||||||
|
const api = new AbstractApi<Expense>();
|
||||||
|
const serializer = new ExpenseSerializer();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableOfContents
|
<TableOfContents
|
||||||
headers={['Name', 'Amount (€)', 'Pricing Type']}
|
headers={['Name', 'Amount (€)', 'Pricing Type']}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user