wedding-planner-frontend/app/ui/components/expense-form-dialog.tsx
Manuel Bustillo 501bb3a81a
All checks were successful
Playwright Tests / test (pull_request) Has been skipped
Check usage of free licenses / build-static-assets (pull_request) Successful in 1m12s
Add copyright notice / copyright_notice (pull_request) Successful in 1m32s
Build Nginx-based docker image / build-static-assets (push) Successful in 6m2s
Update copyright assignment to cover 2025 and include all contributors
2025-01-13 21:36:52 +01:00

83 lines
2.8 KiB
TypeScript

/* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
'use client';
import { AbstractApi } from '@/app/api/abstract-api';
import { Expense, ExpenseSerializer, PricingType, pricingTypes } from '@/app/lib/expense';
import { capitalize } from '@/app/lib/utils';
import { classNames } from '@/app/ui/components/button';
import { Dialog } from 'primereact/dialog';
import { Dropdown } from 'primereact/dropdown';
import { FloatLabel } from 'primereact/floatlabel';
import { InputText } from 'primereact/inputtext';
import { useState } from 'react';
export default function ExpenseFormDialog({ onCreate, onHide, expense, visible }: {
onCreate?: () => void,
onHide: () => void,
expense?: Expense,
visible: boolean,
}) {
const [name, setName] = useState<string>(expense?.name || '');
const [amount, setAmount] = useState<number>(expense?.amount || 0);
const [pricingType, setPricingType] = useState<PricingType>(expense?.pricingType || 'fixed');
const api = new AbstractApi<Expense>();
const serializer = new ExpenseSerializer();
function resetForm() {
setName('');
setAmount(0);
setPricingType('fixed');
}
function submitGroup() {
if (expense?.id !== undefined) {
expense.name = name;
expense.amount = amount;
expense.pricingType = pricingType;
api.update(serializer, expense, () => {
resetForm();
onCreate && onCreate();
});
} else {
api.create(serializer, new Expense(undefined, name, amount, pricingType), () => {
resetForm();
onCreate && onCreate();
});
}
}
return (
<>
<Dialog header="Add/edit expense" visible={visible} style={{ width: '60vw' }} onHide={onHide}>
<div className="card flex justify-evenly py-5">
<FloatLabel>
<InputText id="name" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} />
<label htmlFor="name">Name</label>
</FloatLabel>
<FloatLabel>
<InputText id="amount" className='rounded-sm' value={amount.toString()} onChange={(e) => setAmount(parseFloat(e.target.value))} />
<label htmlFor="amount">Amount</label>
</FloatLabel>
<FloatLabel>
<Dropdown id="pricingType" className='rounded-sm min-w-32' value={pricingType} onChange={(e) => setPricingType(e.target.value)} options={
pricingTypes.map((type) => {
return { label: capitalize(type), value: type };
})
} />
<label htmlFor="pricingType">Pricing type</label>
</FloatLabel>
<button className={classNames('primary')} onClick={submitGroup} disabled={!(name.length > 0)}>
{expense?.id !== undefined ? 'Update' : 'Create'}
</button>
</div>
</Dialog>
</>
);
}