Form transfertype + transactionFee
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,6 +6,8 @@ yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
yarn.lock
|
||||
|
||||
|
||||
node_modules
|
||||
dist
|
||||
|
||||
@ -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>
|
||||
|
||||
281
src/pages/transfer/blocks/TransactionFeeDialog.tsx
Normal file
281
src/pages/transfer/blocks/TransactionFeeDialog.tsx
Normal 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;
|
||||
Reference in New Issue
Block a user