Form transfertype + transactionFee

This commit is contained in:
bagusajisaputroo
2025-03-04 16:16:10 +07:00
parent fa4be57a8b
commit 03e670ef09
3 changed files with 395 additions and 8 deletions

2
.gitignore vendored
View File

@ -6,6 +6,8 @@ yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
yarn.lock
node_modules
dist

View File

@ -1,5 +1,5 @@
import { apiConfig } from '@/config/api.config';
import { useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useManageTransferTypeContext } from '../hooks/useManageTransferTypeContext';
import { Alert, KeenIcon, useDataGrid } from '@/components';
import { useCallApi } from '@/hooks';
@ -20,6 +20,10 @@ import {
SelectValue
} from '@/components/ui/select';
import { Button } from '@/components/ui/button';
import TransactionFeeDialog from './TransactionFeeDialog';
import { toast } from 'sonner';
import { doSaveLogActivity } from '@/actions/GlobalActions';
import { getAuth } from '@/auth';
interface CreateTransferTypeParams {
transfer_type_name: string;
@ -30,6 +34,9 @@ interface CreateTransferTypeParams {
maximum_amount: number;
otp_threshold: number;
maximum_transaction_perDay: number;
status: string;
created_by: string;
created_at: string;
}
const API_URL = apiConfig.service_dashboard;
@ -52,14 +59,21 @@ const AddDialog = () => {
minimal_amount: 0,
maximum_amount: 0,
otp_threshold: 0,
maximum_transaction_perDay: 0
maximum_transaction_perDay: 0,
status: '',
created_by: '',
created_at: ''
};
const [formField, setFormField] = useState(initialState);
const resetForm = () => {
setFormField(initialState);
};
const [isSubmitting, setIsSubmitting] = useState(false);
const [showTransactionFeeDialog, setShowTransactionFeeDialog] = useState(false);
const parsedUser = getAuth()?.user;
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
@ -76,16 +90,72 @@ const AddDialog = () => {
};
console.log(payload);
};
useEffect(() => {
const created_time = new Date();
const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' ');
if (showAddDialog) {
setFormField({
...formField,
created_by: parsedUser?.username,
created_at: formattedTime
});
}
}, [showAddDialog]);
const doCreateTransferType = useCallback(
async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log(formField);
for (const key in formField) {
if (
formField[key as keyof typeof formField] === '' ||
formField[key as keyof typeof formField] === 0
) {
setAlert({ show: true, message: 'All fields must be filled out' });
return;
}
}
setAlert({ show: false, message: '' });
const response = await PostData(`${API_URL}/transactiontype/create`, formField);
if (response?.status) {
setAlert({ show: false, message: '' });
handleAddDialog(false);
toast.success('Success Create Transfer Type');
reload();
resetForm();
const createActivity = {
module: 'Manage Transfer Type',
description: `Create New Transfer Type => ${formField.transfer_type_name}`,
action: 'C'
};
doSaveLogActivity(createActivity);
} else {
setAlert({ show: true, message: response?.message || 'Failed to create transfer type' });
}
handleAddDialog(false);
},
[formField]
);
const handleTransactionFeeSubmit = (data: any) => {
// console.log('Transaction Fee Data Submitted:', data);
setShowTransactionFeeDialog(false);
};
return (
<Dialog open={showAddDialog} onOpenChange={(open) => handleAddDialog(open)}>
<DialogContent className="container-fixed max-w-[768px] flex flex-col p-5 overflow-hidden [&>button]:hidden">
<DialogHeader className="p-5 border-0">
<DialogTitle></DialogTitle>
<DialogDescription></DialogDescription>
<div className="flex items-center justify-between flex-wrap grow">
<div className="flex flex-col justify-center">
<h1 className="text-xl font-semibold leading-none text-gray-900">
Create Transfer Type
</h1>
<h1 className="text-xl font-semibold leading-none text-gray-900">Transfer Type</h1>
<div className="flex items-center gap-2 text-sm font-normal text-gray-700"></div>
</div>
<div
@ -106,7 +176,7 @@ const AddDialog = () => {
<h3>{alert.message}</h3>
</Alert>
)}
<form action="" onSubmit={handleSubmit}>
<form action="" onSubmit={doCreateTransferType}>
<div className="card-body grid gap-5 p-0">
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
@ -273,17 +343,51 @@ const AddDialog = () => {
/>
</div>
</div>
<div className="w-full">
<div className="flex items-center flex-wrap gap-2.5">
<label className="form-label max-w-56">Status</label>
<div className="grow">
<Select
value={formField.status}
onValueChange={(value) =>
setFormField((prev) => ({ ...prev, status: value }))
}
>
<SelectTrigger>
<SelectValue placeholder="Select" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Y</SelectItem>
<SelectItem value="N">N</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
<div className="flex justify-end pt-2.5 gap-5">
<Button
type="button"
variant="outline"
onClick={() => setShowTransactionFeeDialog(true)}
>
Transaction Fee Form
</Button>
<Button variant={'outline'} type="reset">
Reset
</Button>
<Button variant={'default'} type="submit">
Save Changes
<Button variant={'default'} type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Saving...' : 'Save Changes'}
</Button>
</div>
</div>
</form>
<TransactionFeeDialog
open={showTransactionFeeDialog}
onClose={() => setShowTransactionFeeDialog(false)}
onSubmit={handleTransactionFeeSubmit}
/>
</div>
</DialogBody>
</DialogContent>

View File

@ -0,0 +1,281 @@
import { useState, useCallback, useEffect } from 'react';
import {
Dialog,
DialogBody,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import Typography from '@mui/material/Typography';
import { toast } from 'sonner';
import { apiConfig } from '@/config/api.config';
import { useCallApi } from '@/hooks';
import { useManageTransferTypeContext } from '../hooks/useManageTransferTypeContext';
import { get } from 'http';
import { getAuth } from '@/auth';
import { useDataGrid } from '@/components';
import { set } from 'date-fns';
import { doSaveLogActivity } from '@/actions/GlobalActions';
import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem
} from '@/components/ui/select';
interface TransactionFeeDialogProps {
open: boolean;
onClose: () => void;
onSubmit: (data: TransactionFeeForm) => void;
}
interface TransactionFeeForm {
name: string;
description: string;
minimum_amount: number;
maximum_amount: number;
period_start: string;
period_end: string;
deduct_amount: number;
deduct_percentage: number;
priority: string;
status: string;
transactionTypeId: string;
created_by: string;
created_at: string;
}
const API_URL = apiConfig.service_dashboard;
const TransactionFeeDialog: React.FC<TransactionFeeDialogProps> = ({ open, onClose, onSubmit }) => {
const { showAddDialog, handleAddDialog } = useManageTransferTypeContext();
const parsedUser = getAuth()?.user;
const [formField, setFormField] = useState<TransactionFeeForm>({
name: '',
description: '',
minimum_amount: 0,
maximum_amount: 0,
period_start: '',
period_end: '',
deduct_amount: 0,
deduct_percentage: 0,
priority: '',
status: '',
transactionTypeId: '',
created_by: '',
created_at: ''
});
const { PostData, PutData } = useCallApi();
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormField((prev) => ({
...prev,
[name]: value
}));
};
const [isSubmitting, setIsSubmitting] = useState(false);
const { reload } = useDataGrid();
const resetForm = () => {
setFormField(formField);
};
const [alert, setAlert] = useState({
show: false,
message: ''
});
useEffect(() => {
const created_time = new Date();
const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' ');
if (showAddDialog) {
setFormField({
...formField,
created_by: parsedUser?.username,
created_at: formattedTime
});
}
}, [showAddDialog]);
const doCreateTransactionFee = useCallback(
async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log(formField);
const response = await PostData(`${API_URL}/transactionfees/create`, formField);
if (response?.status) {
setAlert({ show: false, message: '' });
handleAddDialog(false);
toast.success('Success Create Transfer Type');
reload();
resetForm();
const createActivity = {
module: 'Manage Transfer Fee',
description: `Create New Transfer Fee => ${formField.name}`,
action: 'C'
};
doSaveLogActivity(createActivity);
} else {
setAlert({ show: true, message: response?.message || 'Failed to create transfer fee' });
}
onSubmit(formField);
},
[formField]
);
return (
<Dialog open={open} onOpenChange={onClose}>
<DialogContent className="max-w-lg p-5">
<DialogHeader>
<DialogTitle>Transaction Fee</DialogTitle>
<DialogDescription></DialogDescription>
</DialogHeader>
<DialogBody>
<form onSubmit={doCreateTransactionFee}>
<div className="grid gap-4">
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Name</label>
<Input name="name" value={formField.name} onChange={handleChange} required />
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Description</label>
<Input
name="description"
value={formField.description}
onChange={handleChange}
required
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Minimum Amount</label>
<Input
name="minimum_amount"
type="number"
value={formField.minimum_amount}
onChange={handleChange}
required
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Maximum Amount</label>
<Input
name="maximum_amount"
type="number"
value={formField.maximum_amount}
onChange={handleChange}
required
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Start</label>
<Input
name="period_start"
type="date"
value={formField.period_start}
onChange={handleChange}
required
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">End</label>
<Input
name="period_end"
type="date"
value={formField.period_end}
onChange={handleChange}
required
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Deduct Amount</label>
<Input
name="deduct_amount"
type="number"
value={formField.deduct_amount}
onChange={handleChange}
required
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Deduct Percentage</label>
<Input
name="deduct_percentage"
type="number"
value={formField.deduct_percentage}
onChange={handleChange}
required
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Status</label>
<Select
value={formField.status}
onValueChange={(value) => setFormField((prev) => ({ ...prev, status: value }))}
required
>
<SelectTrigger className="border border-gray-300 rounded-md p-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
<SelectValue placeholder="Select" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Y</SelectItem>
<SelectItem value="N">N</SelectItem>
</SelectContent>
</Select>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Priority</label>
<Input
name="priority"
value={formField.priority}
onChange={(e) => {
const value = e.target.value;
if (/^\d*$/.test(value)) {
handleChange(e);
}
}}
required
type="text"
inputMode="numeric"
placeholder="Masukkan angka"
/>
</div>
<div className="w-full flex flex-col gap-2">
<label className="text-sm font-medium text-gray-700">Transaction Type ID</label>
<Input
name="transactionTypeId"
value={formField.transactionTypeId}
onChange={handleChange}
required
/>
</div>
<div className="flex justify-end mt-4 gap-3">
<Button variant="outline" type="button" onClick={onClose}>
Cancel
</Button>
<Button variant="default" type="submit">
Submit
</Button>
</div>
</div>
</form>
</DialogBody>
</DialogContent>
</Dialog>
);
};
export default TransactionFeeDialog;