pull/1/head
Aji Kamaludin 3 years ago
parent df2b345aeb
commit 3bba7db7db
No known key found for this signature in database
GPG Key ID: 1DA43CE768971389

@ -10,14 +10,14 @@ class CategoryController extends Controller
public function index()
{
return inertia('Category', [
'categories' => Category::orderBy('created_at', 'desc')->paginate(10)
'categories' => Category::orderBy('created_at', 'asc')->paginate(10)
]);
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'name' => 'required|string|unique:categories,name|max:255',
'description' => 'required|string|max:255',
'amount' => 'required|numeric|max:999999999|min:1'
]);
@ -32,6 +32,7 @@ class CategoryController extends Controller
'budget' => $request->amount,
'start_date' => now()->toDateString(),
'end_date' => null,
'remain' => $request->amount
]);
return redirect()->route('categories');
@ -48,7 +49,7 @@ class CategoryController extends Controller
$category->update([
'name' => $request->name,
'description' => $request->description,
'default_budget' => $request->amount
'default_budget' => $request->amount,
]);
$budget = $category->budgets()->where('end_date', null);

@ -33,12 +33,10 @@ class ExpenseController extends Controller
if ($request->is_income == 0) {
$budget = $transaction->category->budgets()->where('end_date', null)->first();
if ($request->income_type == 0) {
$budget->update(['total_used' => $budget->total_used + $request->amount]);
}
if ($request->income_type == 1) {
$budget->update(['remain' => $budget->remain + $request->amount]);
}
$budget->update([
'total_used' => $budget->total_used + $request->amount,
'remain' => ($budget->budget + $budget->rollover) - ($budget->total_used + $request->amount)
]);
}
DB::commit();
@ -61,12 +59,10 @@ class ExpenseController extends Controller
// return when it create
if ($transaction->is_income == 0) { // pasti ada
$budget = $transaction->category->budgets()->where('end_date', null)->first();
if ($request->income_type == 0) {
$budget->update(['total_used' => $budget->total_used - $request->amount]);
}
if ($request->income_type == 1) {
$budget->update(['remain' => $budget->remain - $request->amount]);
}
$budget->update([
'total_used' => $budget->total_used - $transaction->amount,
'remain' => ($budget->budget + $budget->rollover) + ($budget->total_used - $transaction->amount)
]);
}
$transaction->update($request->input());
@ -74,12 +70,10 @@ class ExpenseController extends Controller
// add new
if ($transaction->is_income == 0) {
$budget = $transaction->category->budgets()->where('end_date', null)->first();
if ($request->income_type == 0) {
$budget->update(['total_used' => $budget->total_used + $request->amount]);
}
if ($request->income_type == 1) {
$budget->update(['remain' => $budget->remain + $request->amount]);
}
$budget->update([
'total_used' => $budget->total_used + $request->amount,
'remain' => ($budget->budget + $budget->rollover) - ($budget->total_used + $request->amount)
]);
}
DB::commit();
@ -92,12 +86,10 @@ class ExpenseController extends Controller
// return when it create
if ($transaction->is_income == 0 && $transaction->category->deleted_at == null) { // pasti ada
$budget = $transaction->category->budgets()->where('end_date', null)->first();
if ($transaction->income_type == 0) {
$budget->update(['total_used' => $budget->total_used - $transaction->amount]);
}
if ($transaction->income_type == 1) {
$budget->update(['remain' => $budget->remain - $transaction->amount]);
}
$budget->update([
'total_used' => $budget->total_used - $transaction->amount,
'remain' => ($budget->budget + $budget->rollover) + ($budget->total_used - $transaction->amount)
]);
}
$transaction->delete();

@ -22,9 +22,7 @@ class SummaryController extends Controller
public function close(Request $request)
{
$content = (new SummaryExport)->download('summary.csv', \Maatwebsite\Excel\Excel::CSV, [
'Content-Type' => 'text/csv',
]);
$content = (new SummaryExport)->download('summary.xlsx', \Maatwebsite\Excel\Excel::XLSX);
DB::beginTransaction();
@ -33,12 +31,13 @@ class SummaryController extends Controller
if ($request->is_rolling == 1) {
foreach ($budgets as $budget) {
$rollover = ($budget->budget + $budget->rollover) - ($budget->total_used + $budget->remain);
$rollover = ($budget->budget + $budget->rollover) - ($budget->total_used);
$rollover = $rollover > 0 ? $rollover : 0;
Budget::create([
'category_id' => $budget->category_id,
'budget' => $budget->budget,
'rollover' => $rollover,
'remain' => $budget->budget + $rollover,
'start_date' => now()->toDateString(),
'end_date' => null,
]);
@ -48,6 +47,7 @@ class SummaryController extends Controller
Budget::create([
'category_id' => $budget->category_id,
'budget' => $budget->budget,
'remain' => $budget->budget,
'start_date' => now()->toDateString(),
'end_date' => null,
]);

Binary file not shown.

30
package-lock.json generated

@ -4458,8 +4458,7 @@
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"jsesc": {
"version": "2.5.2",
@ -4669,7 +4668,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"dev": true,
"requires": {
"js-tokens": "^3.0.0 || ^4.0.0"
}
@ -5088,8 +5086,7 @@
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-hash": {
"version": "2.2.0",
@ -5821,6 +5818,16 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"prop-types": {
"version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"requires": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.8.1"
}
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -5986,6 +5993,19 @@
"scheduler": "^0.20.2"
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-number-format": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-4.8.0.tgz",
"integrity": "sha512-oGGiQpqzvKTR5PD2/AJbyUsci8jyupaoKxpuSPevjpWHMhFkUtmo390t+EIpJOgnuAHZogLu6PHiXgb/OXETKA==",
"requires": {
"prop-types": "^15.7.2"
}
},
"react-toastify": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.1.0.tgz",

@ -30,6 +30,7 @@
"classnames": "^2.3.1",
"daisyui": "^1.16.4",
"moment": "^2.29.1",
"react-number-format": "^4.8.0",
"react-toastify": "^8.1.0"
}
}

97
public/css/app.css vendored

@ -2084,6 +2084,13 @@ html {
--tw-text-opacity: 1;
color: hsla(var(--s)/var(--tw-text-opacity,1));
}
.btn-outline.btn-accent .badge-outline {
background-color: transparent;
--tw-border-opacity: 1;
border-color: hsla(var(--a)/var(--tw-border-opacity,1));
--tw-text-opacity: 1;
color: hsla(var(--a)/var(--tw-text-opacity,1));
}
.btn-outline:hover .badge {
--tw-bg-opacity: 1;
background-color: hsla(var(--b2)/var(--tw-bg-opacity,1));
@ -2235,6 +2242,20 @@ html {
.btn.glass:focus-visible {
box-shadow: 0 0 0 2px currentColor;
}
.btn-outline {
background-color: transparent;
border-color: currentColor;
--tw-text-opacity: 1;
color: hsla(var(--bc)/var(--tw-text-opacity,1));
}
.btn-outline:hover {
--tw-bg-opacity: 1;
background-color: hsla(var(--bc)/var(--tw-bg-opacity,1));
--tw-border-opacity: 1;
border-color: hsla(var(--bc)/var(--tw-border-opacity,1));
--tw-text-opacity: 1;
color: hsla(var(--b1)/var(--tw-text-opacity,1));
}
.btn-outline.btn-primary {
--tw-text-opacity: 1;
color: hsla(var(--p)/var(--tw-text-opacity,1));
@ -2259,6 +2280,42 @@ html {
--tw-text-opacity: 1;
color: hsla(var(--sc)/var(--tw-text-opacity,1));
}
.btn-outline.btn-accent {
--tw-text-opacity: 1;
color: hsla(var(--a)/var(--tw-text-opacity,1));
}
.btn-outline.btn-accent:hover {
--tw-bg-opacity: 1;
background-color: hsla(var(--af)/var(--tw-bg-opacity,1));
--tw-border-opacity: 1;
border-color: hsla(var(--af)/var(--tw-border-opacity,1));
--tw-text-opacity: 1;
color: hsla(var(--ac)/var(--tw-text-opacity,1));
}
.btn-outline.btn-success {
--tw-text-opacity: 1;
color: hsla(var(--su)/var(--tw-text-opacity,1));
}
.btn-outline.btn-success:hover {
--tw-bg-opacity: 1;
background-color: hsla(var(--su)/var(--tw-bg-opacity,1));
--tw-border-opacity: 1;
border-color: hsla(var(--su)/var(--tw-border-opacity,1));
--tw-text-opacity: 1;
color: hsla(var(--nc)/var(--tw-text-opacity,1));
}
.btn-outline.btn-info {
--tw-text-opacity: 1;
color: hsla(var(--in)/var(--tw-text-opacity,1));
}
.btn-outline.btn-info:hover {
--tw-bg-opacity: 1;
background-color: hsla(var(--in)/var(--tw-bg-opacity,1));
--tw-border-opacity: 1;
border-color: hsla(var(--in)/var(--tw-border-opacity,1));
--tw-text-opacity: 1;
color: hsla(var(--nc)/var(--tw-text-opacity,1));
}
.btn-outline.btn-warning {
--tw-text-opacity: 1;
color: hsla(var(--wa)/var(--tw-text-opacity,1));
@ -2817,6 +2874,9 @@ html {
--tw-text-opacity: 1;
color: hsla(var(--a)/var(--tw-text-opacity,1));
}
.visible {
visibility: visible;
}
.fixed {
position: fixed;
}
@ -2858,6 +2918,10 @@ html {
margin-left: 0.25rem;
margin-right: 0.25rem;
}
.my-2 {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.ml-3 {
margin-left: 0.75rem;
}
@ -2975,6 +3039,27 @@ html {
.w-20 {
width: 5rem;
}
.w-80 {
width: 20rem;
}
.w-56 {
width: 14rem;
}
.w-52 {
width: 13rem;
}
.w-32 {
width: 8rem;
}
.w-36 {
width: 9rem;
}
.w-60 {
width: 15rem;
}
.w-72 {
width: 18rem;
}
.max-w-xl {
max-width: 36rem;
}
@ -2984,8 +3069,10 @@ html {
.max-w-7xl {
max-width: 80rem;
}
.max-w-xs {
max-width: 20rem;
.max-w-min {
max-width: -webkit-min-content;
max-width: -moz-min-content;
max-width: min-content;
}
.flex-1 {
flex: 1 1 0%;
@ -3433,6 +3520,11 @@ html {
.ease-in {
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
.table td, .table th {
padding: 1rem;
vertical-align: middle;
white-space: normal;
}
.hover\:border-gray-300:hover {
--tw-border-opacity: 1;
border-color: rgba(209, 213, 219, var(--tw-border-opacity));
@ -3681,4 +3773,3 @@ html {
padding-right: 2rem;
}
}

2016
public/js/app.js vendored

File diff suppressed because it is too large Load Diff

@ -1,3 +1,9 @@
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
.table td, .table th {
padding: 1rem;
vertical-align: middle;
white-space: normal;
}

@ -21,12 +21,12 @@ export default function Authenticated({ header, children }) {
</div>
<div className="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
<NavLink href={route('transactions')} active={route().current('transactions')}>
Transaction
</NavLink>
<NavLink href={route('categories')} active={route().current('categories')}>
Category
</NavLink>
<NavLink href={route('transactions')} active={route().current('transactions')}>
Transaction
</NavLink>
<NavLink href={route('summary')} active={route().current('summary')}>
Summary
</NavLink>
@ -62,10 +62,10 @@ export default function Authenticated({ header, children }) {
<div className={(showingNavigationDropdown ? 'block' : 'hidden') + ' sm:hidden'}>
<div className="pt-2 pb-3 space-y-1">
<ResponsiveNavLink href={route('transactions')} active={route().current('transactions')}>
Transaction
Category
</ResponsiveNavLink>
<ResponsiveNavLink href={route('transactions')} active={route().current('transactions')}>
Category
Transaction
</ResponsiveNavLink>
<ResponsiveNavLink href={route('summary')} active={route().current('summary')}>
Summary

@ -3,6 +3,7 @@ import Pagination from '@/Components/Pagination'
import Authenticated from '@/Layouts/Authenticated';
import { toast } from 'react-toastify';
import { Head, useForm } from '@inertiajs/inertia-react';
import NumberFormat from 'react-number-format';
import { formatIDR } from '@/utils';
export default function Category(props) {
@ -80,7 +81,7 @@ export default function Category(props) {
<div className="card-body">
<div className="form-control">
<label className="label">
<span className="label-text">Name</span>
<span className="label-text">Category Name</span>
</label>
<input
type="text"
@ -117,14 +118,14 @@ export default function Category(props) {
<div className="form-control">
<label className="label">
<span className="label-text">Amount</span>
</label>
<input
type="number"
placeholder="Amount"
className={`input input-bordered ${errors.amount ? 'input-error' : ''}`}
id="amount"
value={data.amount}
onChange={handleChange}
</label>
<NumberFormat
thousandSeparator={true}
className={`input input-bordered ${errors.amount ? 'input-error' : ''}`}
value={data.amount}
thousandSeparator="."
decimalSeparator=","
onValueChange={({value}) => setData('amount', value)}
/>
<label className="label">
<span className="label-text-alt">
@ -148,10 +149,10 @@ export default function Category(props) {
<thead>
<tr>
<th></th>
<th>Name</th>
<th className="w-36">Category Name</th>
<th>Description</th>
<th>Amount</th>
<th></th>
<th className="w-52"></th>
</tr>
</thead>
<tbody className={processing ? "opacity-70" : ""}>

@ -1,6 +1,7 @@
import React, { useState } from 'react'
import { Link, useForm } from '@inertiajs/inertia-react';
import { toast } from 'react-toastify';
import { Inertia } from '@inertiajs/inertia'
export default function ModalClosing() {
const {data, setData} = useForm({
@ -16,10 +17,7 @@ export default function ModalClosing() {
}
setLoading(true)
fetch(`${route('close')}?is_rolling=${data.is_rolling}`, {
method: 'GET',
headers: {
'Content-Type': 'text/csv',
},
method: 'GET'
})
.then((response) => response.blob())
.then((blob) => {
@ -28,18 +26,24 @@ export default function ModalClosing() {
);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `summary.csv`);
link.setAttribute('download', `summary.xlsx`);
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
})
.finally(() => setLoading(false));
.finally(() => {
toast.success('berhasil mendownload, silahkan klik close')
setLoading(false)
setTimeout(() => {
Inertia.visit(route('summary'))
}, 3000)
});
}
return (
<div id="my-modal" className="modal">
<div className="modal-box">
<h1 className="font-bold text-2xl pb-8">Form Closing</h1>
<h1 className="font-bold text-2xl pb-8">Monthly Closing</h1>
<div className="form-control py-4 px-6">
<label className="cursor-pointer label">
<span className="label-text">Roll forward Budget per Category</span>

@ -33,7 +33,7 @@ export default function Summary(props) {
</div>
<div className="card bg-white w-full md:w-1/4">
<div className="card-body">
<a href="#my-modal"className="btn btn-primary">Form Closing</a>
<a href="#my-modal"className="btn btn-primary">monthly closing</a>
</div>
</div>
</div>
@ -56,9 +56,9 @@ export default function Summary(props) {
</tr>
</thead>
<tbody>
{budgets?.map(budget => (
{budgets?.map((budget, index) => (
<tr key={budget.id}>
<th>{budget.id}</th>
<th>{index+1}</th>
<td>{budget?.category?.name}</td>
<td>{budget?.category?.description}</td>
<td>{formatIDR(budget.budget)}</td>

@ -4,11 +4,13 @@ import Authenticated from '@/Layouts/Authenticated';
import { Head, useForm } from '@inertiajs/inertia-react';
import { toast } from 'react-toastify';
import moment from 'moment';
import NumberFormat from 'react-number-format';
import { formatIDR } from '@/utils';
export default function Transaction(props) {
const { categories, transactions } = props
const [transaction, setTransaction] = useState(null)
const [showForm, setShowForm] = useState(false)
const { data, setData, errors, post, put, processing, delete: destroy } = useForm({
category_id: '',
description: '',
@ -18,6 +20,15 @@ export default function Transaction(props) {
income_type: 0
})
const toggleForm = (transaction = null) => {
setShowForm(!showForm)
if(transaction !== null) {
handleEdit(transaction)
}else{
handleReset()
}
}
const toggleCashType = () => {
setData('income_type', data.income_type === 0 ? 1 : 0)
}
@ -26,7 +37,9 @@ export default function Transaction(props) {
setData({
...data,
category_id: '',
is_income: data.is_income === 0 ? 1 : 0
description: '',
is_income: data.is_income === 0 ? 1 : 0,
income_type: 1,
})
}
@ -84,6 +97,7 @@ export default function Transaction(props) {
if(transaction !== null) {
put(route('transactions.update', transaction), {
onSuccess: () => Promise.all([
toggleForm(),
handleReset(),
toast.success('The Data has been changed')
])})
@ -91,6 +105,7 @@ export default function Transaction(props) {
}
post(route('transactions.store'), {
onSuccess: () => Promise.all([
toggleForm(),
handleReset(),
toast.success('Data has been saved')
])
@ -104,120 +119,22 @@ export default function Transaction(props) {
>
<Head title="Transaction" />
<div className="flex flex-col space-y-2 md:space-y-0 md:flex-row py-12">
<div className="w-full md:w-1/3 px-6 md:pl-8">
<div className="card bg-white">
<div className="card-body">
<div className="form-control">
<label className="label">
<span className="label-text">Date</span>
</label>
<input
type="date"
className={`input input-bordered ${errors.date ? 'input-error' : ''}`}
id="date"
value={data.date}
onChange={handleChange}
/>
<label className="label">
<span className="label-text-alt">
{errors.date}
</span>
</label>
</div>
<div className="form-control">
<label className="cursor-pointer label">
<input type="checkbox" checked={data.is_income === 1 ? true : false} onChange={toggleIncome} className="checkbox checkbox-primary"/>
<span className="label-text font-bold">Income</span>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Category</span>
</label>
<select
className={`select select-bordered w-full max-w-xs ${errors.category_id && 'select-error'}`}
id="category_id"
onChange={handleSelectedcategory}
disabled={data.is_income === 1}
value={data.category_id}
>
<option disabled="disabled" selected={'' === data.category_id} value=''>Choose your category</option>
{categories.map(category => (
<option key={category.id} value={category.id} selected={category.id === data.category_id}>{category.name}</option>
)
)}
</select>
<label className="label">
<span className="label-text-alt">
{errors.category_id}
</span>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Description</span>
</label>
<input
type="text"
placeholder="Description"
className={`input input-bordered ${errors.description ? 'input-error' : ''}`}
id="description"
value={data.description}
onChange={handleChange}
/>
<label className="label">
<span className="label-text-alt">
{errors.description}
</span>
</label>
</div>
<div className="form-control">
<label className="cursor-pointer label">
<span className="label-text font-bold">{data.income_type === 0 ? 'Cash Out' : 'Cash In'}</span>
<input type="checkbox" checked={data.income_type === 0 ? true : false} className="toggle" onChange={toggleCashType}/>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Amount</span>
</label>
<input
type="number"
placeholder="Amount"
className={`input input-bordered ${errors.amount ? 'input-error' : ''}`}
id="amount"
value={data.amount}
onChange={handleChange}
/>
<label className="label">
<span className="label-text-alt">
{errors.amount}
</span>
</label>
</div>
<div className="card-actions">
<button className={`btn btn-primary ${processing && 'animate-spin'}`} onClick={handleSubmit} disabled={processing}>Add</button>
<button className="btn btn-secondary" onClick={handleReset} disabled={processing}>Clear</button>
</div>
</div>
</div>
</div>
<div className="w-full md:w-2/3 px-6 md:pr-8">
<div className="flex flex-col space-y-2 py-12">
<div className="w-full px-6 md:pr-8">
<div className="card bg-white">
<div className="card-body">
<div className="btn btn-outline max-w-min my-2" onClick={() => toggleForm()}>Tambah</div>
<div className="overflow-x-auto">
<table className="table w-full table-zebra">
<thead>
<tr>
<th>Date</th>
<th>Income</th>
<th>Category</th>
<th>Cash In/Out</th>
<th>Type</th>
<th>Category Name</th>
<th className="w-32">Cash In/Out</th>
<th>Description</th>
<th>Amount</th>
<th></th>
<th className="w-52"></th>
</tr>
</thead>
<tbody className={processing ? "opacity-70" : ""}>
@ -242,7 +159,7 @@ export default function Transaction(props) {
<td>{transaction.description}</td>
<td>{formatIDR(transaction.amount)}</td>
<td>
<div className="btn btn-warning mx-1" onClick={() => handleEdit(transaction)}>Edit</div>
<div className="btn btn-warning mx-1" onClick={() => toggleForm(transaction)}>Edit</div>
<div className="btn btn-error mx-1" onClick={() => handleDelete(transaction)}>Delete</div>
</td>
</tr>
@ -254,7 +171,103 @@ export default function Transaction(props) {
</div>
</div>
</div>
</div>
<div id="create-modal" className="modal" style={showForm ? {opacity: 1, pointerEvents: 'auto', visibility: 'visible'} : {}}>
<div className="modal-box">
<div className="form-control">
<label className="label">
<span className="label-text">Date</span>
</label>
<input
type="date"
className={`input input-bordered ${errors.date ? 'input-error' : ''}`}
id="date"
value={data.date}
onChange={handleChange}
/>
<label className="label">
<span className="label-text-alt">
{errors.date}
</span>
</label>
</div>
<div className="form-control">
<label className="cursor-pointer label">
<input type="checkbox" checked={data.is_income === 1 ? true : false} onChange={toggleIncome} className="checkbox checkbox-primary"/>
<span className="label-text font-bold">Income</span>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Category</span>
</label>
<select
className={`select select-bordered w-full ${errors.category_id && 'select-error'}`}
id="category_id"
onChange={handleSelectedcategory}
disabled={data.is_income === 1}
value={data.category_id}
>
<option disabled="disabled" selected={'' === data.category_id} value=''>Choose your category</option>
{categories.map(category => (
<option key={category.id} value={category.id} selected={category.id === data.category_id}>{category.name}</option>
)
)}
</select>
<label className="label">
<span className="label-text-alt">
{errors.category_id}
</span>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Description</span>
</label>
<input
type="text"
placeholder="Description"
className={`input input-bordered ${errors.description ? 'input-error' : ''}`}
id="description"
value={data.description}
onChange={handleChange}
/>
<label className="label">
<span className="label-text-alt">
{errors.description}
</span>
</label>
</div>
<div className="form-control">
<label className="cursor-pointer label">
<span className="label-text font-bold">{data.income_type === 0 ? 'Cash Out' : 'Cash In'}</span>
<input type="checkbox" checked={data.income_type === 0 ? true : false} disabled={data.is_income === 1} className="toggle" onChange={toggleCashType}/>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Amount</span>
</label>
<NumberFormat
thousandSeparator={true}
className={`input input-bordered ${errors.amount ? 'input-error' : ''}`}
value={data.amount}
thousandSeparator="."
decimalSeparator=","
onValueChange={({value}) => setData('amount', value)}
/>
<label className="label">
<span className="label-text-alt">
{errors.amount}
</span>
</label>
</div>
<div className="modal-action">
<button className={`btn btn-primary ${processing && 'animate-spin'}`} onClick={handleSubmit} disabled={processing}>Add</button>
<button className="btn btn-secondary" onClick={handleReset} disabled={processing}>Clear</button>
<button className="btn btn-outline btn-secondary" onClick={() => toggleForm()} disabled={processing}>Close</button>
</div>
</div>
</div>
</Authenticated>
);

Loading…
Cancel
Save