add skeleton loading on dialog edit

This commit is contained in:
Wikzyy
2025-04-16 22:53:06 +07:00
parent 40ebdcc37f
commit 1d11c94175
6 changed files with 716 additions and 601 deletions

View File

@ -49,6 +49,7 @@ const EditDialog = () => {
const parsedUser = getAuth()?.user; const parsedUser = getAuth()?.user;
const [currencies, setCurrencies] = useState<CurrencyProps[]>([]); const [currencies, setCurrencies] = useState<CurrencyProps[]>([]);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [alert, setAlert] = useState({ const [alert, setAlert] = useState({
show: false, show: false,
message: '' message: ''
@ -74,8 +75,8 @@ const EditDialog = () => {
const doUpdateConversion = useCallback( const doUpdateConversion = useCallback(
async (e: React.FormEvent<HTMLFormElement>) => { async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); e.preventDefault();
if(!showEditDialog) return; if (!showEditDialog) return;
const response = await PutData(`${API_URL}/dashboard/conversion/${selectedConversion}`,{ const response = await PutData(`${API_URL}/dashboard/conversion/${selectedConversion}`, {
...formField ...formField
}); });
@ -83,13 +84,13 @@ const EditDialog = () => {
resetForm(); resetForm();
handleEditDialog(false, null); handleEditDialog(false, null);
toast.success('Success Update Conversion'); toast.success('Success Update Conversion');
const createActivity = { const createActivity = {
module: 'Manage Conversion', module: 'Manage Conversion',
description: `Update Conversion => ${selectedConversion}`, description: `Update Conversion => ${selectedConversion}`,
action: 'U' action: 'U'
}; };
doSaveLogActivity(createActivity); doSaveLogActivity(createActivity);
reload(); reload();
} else { } else {
toast.error('Error Create Conversion'); toast.error('Error Create Conversion');
@ -100,7 +101,7 @@ const EditDialog = () => {
); );
const doGetCurrency = async (sorting: any) => { const doGetCurrency = async (sorting: any) => {
if (!showEditDialog)return; if (!showEditDialog) return;
try { try {
sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting; sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting;
const response = await GetData(`${API_URL}/dashboard/currency/`, { const response = await GetData(`${API_URL}/dashboard/currency/`, {
@ -117,30 +118,29 @@ const EditDialog = () => {
} }
}; };
const doGetConversionById = useCallback(async (id: string) => { const doFetchData = useCallback(async (id: string) => {
const response = await GetData(`${API_URL}/dashboard/conversion/${id}`, { id }); setIsLoading(true);
console.log('Transaction Type: ', response?.data); const response = await GetData(`${API_URL}/dashboard/conversion/${id}`, { id });
if (response?.status) { console.log('Transaction Type: ', response?.data);
setFormField((prev) => ({ if (response?.status) {
...prev, setFormField((prev) => ({
status: response.data.status, ...prev,
id_currency_origin: response.data.id_currency_origin, status: response.data.status,
id_currency_destination: response.data.id_currency_destination, id_currency_origin: response.data.id_currency_origin,
buy: response.data.buy, id_currency_destination: response.data.id_currency_destination,
sell: response.data.sell, buy: response.data.buy,
})); sell: response.data.sell
} }));
// console.log('form fieldd Transaction Type: ', formField); }
}, []); // console.log('form fieldd Transaction Type: ', formField);
setIsLoading(false);
useEffect(() => { }, []);
if (selectedConversion) {
doGetConversionById(selectedConversion);
}
}, [selectedConversion]);
useEffect(() => {
if (selectedConversion) {
doFetchData(selectedConversion);
}
}, [selectedConversion]);
useEffect(() => { useEffect(() => {
if (showEditDialog) { if (showEditDialog) {
@ -158,7 +158,6 @@ const EditDialog = () => {
} }
}, [showEditDialog]); }, [showEditDialog]);
useEffect(() => { useEffect(() => {
if (showEditDialog === false) { if (showEditDialog === false) {
resetForm(); resetForm();
@ -166,7 +165,7 @@ const EditDialog = () => {
}, [showEditDialog]); }, [showEditDialog]);
return ( return (
<Dialog open={showEditDialog} onOpenChange={(open) => handleEditDialog(open,null)}> <Dialog open={showEditDialog} onOpenChange={(open) => handleEditDialog(open, null)}>
<DialogContent className="container-fixed max-w-[768px] flex flex-col p-5 overflow-hidden"> <DialogContent className="container-fixed max-w-[768px] flex flex-col p-5 overflow-hidden">
<DialogHeader> <DialogHeader>
<DialogTitle>Conversion - Update</DialogTitle> <DialogTitle>Conversion - Update</DialogTitle>
@ -180,96 +179,110 @@ const EditDialog = () => {
</Alert> </Alert>
)} )}
<form onSubmit={doUpdateConversion}> {isLoading ? (
<div className="card-body grid gap-5"> <div className="flex flex-col items-center justify-center p-8">
<div className="w-full"> <div className="animate-pulse flex space-x-4 w-full">
<label className="form-label"> <div className="flex-1 space-y-4 py-1">
Currency Origin <span className="text-red-500">*</span> <div className="h-4 bg-gray-200 rounded w-3/4"></div>
</label> <div className="space-y-2">
<Select <div className="h-4 bg-gray-200 rounded"></div>
value={formField.id_currency_origin} <div className="h-4 bg-gray-200 rounded w-5/6"></div>
onValueChange={(id_currency_origin) => </div>
setFormField((prev) => ({ ...prev, id_currency_origin })) </div>
}
>
<SelectTrigger>
<SelectValue placeholder="Select Currency" />
</SelectTrigger>
<SelectContent>
{currencies.map((currency, idx) => (
<SelectItem value={currency.ID} key={currency.ID}>
{currency.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div> </div>
<div className="w-full"> <p className="mt-4 text-gray-500">Loading Conversion Details...</p>
<label className="form-label"> </div>
Currency Destination <span className="text-red-500">*</span> ) : (
</label> <form onSubmit={doUpdateConversion}>
<Select <div className="card-body grid gap-5">
value={formField.id_currency_destination} <div className="w-full">
onValueChange={(id_currency_destination) => <label className="form-label">
setFormField((prev) => ({ ...prev, id_currency_destination })) Currency Origin <span className="text-red-500">*</span>
} </label>
> <Select
<SelectTrigger> value={formField.id_currency_origin}
<SelectValue placeholder="Select Currency" /> onValueChange={(id_currency_origin) =>
</SelectTrigger> setFormField((prev) => ({ ...prev, id_currency_origin }))
<SelectContent> }
{currencies.map((currency, idx) => ( >
<SelectItem value={currency.ID} key={currency.ID}> <SelectTrigger>
{currency.name} <SelectValue placeholder="Select Currency" />
</SelectItem> </SelectTrigger>
))} <SelectContent>
</SelectContent> {currencies.map((currency, idx) => (
</Select> <SelectItem value={currency.ID} key={currency.ID}>
</div> {currency.name}
<div className="w-full"> </SelectItem>
<label className="form-label"> ))}
Buy<span className="text-red-500">*</span> </SelectContent>
</label> </Select>
<NumericFormat </div>
className="input" <div className="w-full">
value={formField.buy} <label className="form-label">
thousandSeparator="." Currency Destination <span className="text-red-500">*</span>
decimalSeparator="," </label>
allowNegative={false} <Select
onValueChange={(values) => { value={formField.id_currency_destination}
setFormField((prev) => ({ onValueChange={(id_currency_destination) =>
...prev, setFormField((prev) => ({ ...prev, id_currency_destination }))
buy: values.floatValue || 0 }
})); >
}} <SelectTrigger>
placeholder="Enter Buy" <SelectValue placeholder="Select Currency" />
/> </SelectTrigger>
</div> <SelectContent>
<div className="w-full"> {currencies.map((currency, idx) => (
<label className="form-label"> <SelectItem value={currency.ID} key={currency.ID}>
Sell {currency.name}
<span className="text-red-500">*</span> </SelectItem>
</label> ))}
<NumericFormat </SelectContent>
className="input" </Select>
value={formField.sell} </div>
thousandSeparator="." <div className="w-full">
decimalSeparator="," <label className="form-label">
allowNegative={false} Buy<span className="text-red-500">*</span>
onValueChange={(values) => { </label>
setFormField((prev) => ({ <NumericFormat
...prev, className="input"
sell: values.floatValue || 0 value={formField.buy}
})); thousandSeparator="."
}} decimalSeparator=","
placeholder="Enter Sell" allowNegative={false}
/> onValueChange={(values) => {
</div> setFormField((prev) => ({
<div className="w-full"> ...prev,
buy: values.floatValue || 0
}));
}}
placeholder="Enter Buy"
/>
</div>
<div className="w-full">
<label className="form-label">
Sell
<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.sell}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
sell: values.floatValue || 0
}));
}}
placeholder="Enter Sell"
/>
</div>
<div className="w-full">
<label className="form-label"> <label className="form-label">
Status Status
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
</label> </label>
<div className="grow"> <div className="grow">
<Select <Select
@ -287,16 +300,16 @@ const EditDialog = () => {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
</div>
<div className="flex justify-end gap-5">
<Button type="button" variant="outline" onClick={resetForm}>
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div>
</div> </div>
<div className="flex justify-end gap-5"> </form>
<Button type="button" variant="outline" onClick={resetForm}> )}
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div>
</div>
</form>
</div> </div>
</DialogBody> </DialogBody>
</DialogContent> </DialogContent>

View File

@ -49,6 +49,7 @@ const EditDialog = () => {
const parsedUser = getAuth()?.user; const parsedUser = getAuth()?.user;
const [currencies, setCurrencies] = useState<CurrencyProps[]>([]); const [currencies, setCurrencies] = useState<CurrencyProps[]>([]);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [alert, setAlert] = useState({ const [alert, setAlert] = useState({
show: false, show: false,
message: '' message: ''
@ -98,7 +99,8 @@ const EditDialog = () => {
[formField] [formField]
); );
const doGetCurrencyById = useCallback(async (id: string) => { const doFetchData = useCallback(async (id: string) => {
setIsLoading(true);
const response = await GetData(`${API_URL}/dashboard/currency/${id}`, { id }); const response = await GetData(`${API_URL}/dashboard/currency/${id}`, { id });
// console.log('Transaction Type: ', response?.data); // console.log('Transaction Type: ', response?.data);
if (response?.status) { if (response?.status) {
@ -110,12 +112,13 @@ const EditDialog = () => {
prefix: response.data.prefix prefix: response.data.prefix
})); }));
} }
setIsLoading(false);
// console.log('form fieldd Transaction Type: ', formField); // console.log('form fieldd Transaction Type: ', formField);
}, []); }, []);
useEffect(() => { useEffect(() => {
if (selectedCurrency) { if (selectedCurrency) {
doGetCurrencyById(selectedCurrency); doFetchData(selectedCurrency);
} }
}, [selectedCurrency]); }, [selectedCurrency]);
@ -150,74 +153,93 @@ const EditDialog = () => {
</Alert> </Alert>
)} )}
<form onSubmit={doUpdateCurrency}> {isLoading ? (
<div className="card-body grid gap-5"> <div className="flex flex-col items-center justify-center p-8">
<div className="w-full"> <div className="animate-pulse flex space-x-4 w-full">
<label className="form-label"> <div className="flex-1 space-y-4 py-1">
Code <div className="h-4 bg-gray-200 rounded w-3/4"></div>
<span className="text-red-500">*</span> <div className="space-y-2">
</label> <div className="h-4 bg-gray-200 rounded"></div>
<Input <div className="h-4 bg-gray-200 rounded w-5/6"></div>
type="text" </div>
placeholder="Code" </div>
value={formField.code}
onChange={(e) => setFormField((prev) => ({ ...prev, code: e.target.value }))}
/>
</div>
<div className="w-full">
<label className="form-label">
Name
<span className="text-red-500">*</span>
</label>
<Input
type="text"
placeholder="Code"
value={formField.name}
onChange={(e) => setFormField((prev) => ({ ...prev, name: e.target.value }))}
/>
</div>
<div className="w-full">
<label className="form-label">
Prefix
<span className="text-red-500">*</span>
</label>
<Input
type="text"
placeholder="Code"
value={formField.prefix}
onChange={(e) => setFormField((prev) => ({ ...prev, prefix: e.target.value }))}
/>
</div>
<div className="w-full">
<label className="form-label">
Status
<span className="text-red-500">*</span>
</label>
<Select
value={formField.status}
onValueChange={(value) => setFormField((prev) => ({ ...prev, status: value }))}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select" defaultValue={formField.status} />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">Inactive</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex justify-end gap-5">
<Button type="button" variant="outline" onClick={resetForm}>
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div> </div>
<p className="mt-4 text-gray-500">Loading Currency Details...</p>
</div> </div>
</form> ) : (
<form onSubmit={doUpdateCurrency}>
<div className="card-body grid gap-5">
<div className="w-full">
<label className="form-label">
Code
<span className="text-red-500">*</span>
</label>
<Input
type="text"
placeholder="Code"
value={formField.code}
onChange={(e) => setFormField((prev) => ({ ...prev, code: e.target.value }))}
/>
</div>
<div className="w-full">
<label className="form-label">
Name
<span className="text-red-500">*</span>
</label>
<Input
type="text"
placeholder="Code"
value={formField.name}
onChange={(e) => setFormField((prev) => ({ ...prev, name: e.target.value }))}
/>
</div>
<div className="w-full">
<label className="form-label">
Prefix
<span className="text-red-500">*</span>
</label>
<Input
type="text"
placeholder="Code"
value={formField.prefix}
onChange={(e) =>
setFormField((prev) => ({ ...prev, prefix: e.target.value }))
}
/>
</div>
<div className="w-full">
<label className="form-label">
Status
<span className="text-red-500">*</span>
</label>
<Select
value={formField.status}
onValueChange={(value) =>
setFormField((prev) => ({ ...prev, status: value }))
}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select" defaultValue={formField.status} />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">Inactive</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex justify-end gap-5">
<Button type="button" variant="outline" onClick={resetForm}>
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div>
</div>
</form>
)}
</div> </div>
</DialogBody> </DialogBody>
</DialogContent> </DialogContent>

View File

@ -36,6 +36,7 @@ const EditDialog = () => {
const { reload } = useDataGrid(); const { reload } = useDataGrid();
const { PutData, GetData } = useCallApi(); const { PutData, GetData } = useCallApi();
const parsedUser = getAuth()?.user; const parsedUser = getAuth()?.user;
const [isLoading, setIsLoading] = useState(false);
const created_time = new Date(); const created_time = new Date();
const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' '); const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' ');
const [alert, setAlert] = useState({ const [alert, setAlert] = useState({
@ -123,6 +124,7 @@ const EditDialog = () => {
}, []); }, []);
const doFetchData = useCallback(async (id: string) => { const doFetchData = useCallback(async (id: string) => {
setIsLoading(true);
const response = await GetData(`${API_URL}/product/getdata/${id}`, { id }); const response = await GetData(`${API_URL}/product/getdata/${id}`, { id });
// console.log(response); // console.log(response);
@ -144,6 +146,7 @@ const EditDialog = () => {
} else { } else {
setFormField(initialState); setFormField(initialState);
} }
setIsLoading(false);
}, []); }, []);
const handleUpdate = (e: React.FormEvent<HTMLFormElement>) => { const handleUpdate = (e: React.FormEvent<HTMLFormElement>) => {
@ -214,225 +217,242 @@ const EditDialog = () => {
</Alert> </Alert>
)} )}
<form onSubmit={handleUpdate}> {isLoading ? (
<div className="card-body grid gap-5"> <div className="flex flex-col items-center justify-center p-8">
<div className="w-full"> <div className="animate-pulse flex space-x-4 w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5"> <div className="flex-1 space-y-4 py-1">
<label className="form-label flex items-center gap-1 max-w-56"> <div className="h-4 bg-gray-200 rounded w-3/4"></div>
Name<span className="text-red-500">*</span> <div className="space-y-2">
</label> <div className="h-4 bg-gray-200 rounded"></div>
<Input <div className="h-4 bg-gray-200 rounded w-5/6"></div>
className="input" </div>
type="text"
value={formField.name}
onChange={(e) => setFormField({ ...formField, name: e.target.value })}
/>
</div> </div>
</div> </div>
<p className="mt-4 text-gray-500">Loading Products Details...</p>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Type<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.type}
onChange={(e) => setFormField({ ...formField, type: e.target.value })}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Code<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.code}
onChange={(e) => setFormField({ ...formField, code: e.target.value })}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Description<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.description}
onChange={(e) => setFormField({ ...formField, description: e.target.value })}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Price Point<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.price_point ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
price_point: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Price Point"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Price Cash<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.price_cash ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
price_cash: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Price Cash"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Cashback Point<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.cashback_point ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
cashback_point: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Cashback Point"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Cashback Cash<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.cashback_cash ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
cashback_cash: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Cashback Cash"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Status<span className="text-red-500">*</span>
</label>
<Select
value={formField.status}
onValueChange={(e) => setFormField({ ...formField, status: e })}
>
<SelectTrigger>
<SelectValue placeholder="Select a Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">Inactive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Provider ID
</label>
<Select
value={formField.provider}
onValueChange={(e) => setFormField({ ...formField, provider: e })}
>
<SelectTrigger>
<SelectValue placeholder="Select a Provider" />
</SelectTrigger>
<SelectContent>
{providers.map((provider) => (
<SelectItem key={provider.provider_id} value={provider.provider_id}>
{provider.provider_name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Process on Third Party<span className="text-red-500">*</span>
</label>
<Select
value={formField.process_on_third_party}
onValueChange={(value) =>
setFormField({ ...formField, process_on_third_party: value })
}
>
<SelectTrigger>
<SelectValue placeholder="Select Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Yes</SelectItem>
<SelectItem value="N">No</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="flex justify-end gap-5">
<Button type="button" variant="outline" onClick={resetForm}>
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div>
</div> </div>
</form> ) : (
<form onSubmit={handleUpdate}>
<div className="card-body grid gap-5">
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Name<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.name}
onChange={(e) => setFormField({ ...formField, name: e.target.value })}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Type<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.type}
onChange={(e) => setFormField({ ...formField, type: e.target.value })}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Code<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.code}
onChange={(e) => setFormField({ ...formField, code: e.target.value })}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Description<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.description}
onChange={(e) =>
setFormField({ ...formField, description: e.target.value })
}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Price Point<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.price_point ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
price_point: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Price Point"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Price Cash<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.price_cash ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
price_cash: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Price Cash"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Cashback Point<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.cashback_point ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
cashback_point: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Cashback Point"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Cashback Cash<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input"
value={formField.cashback_cash ?? ''}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
cashback_cash: values.floatValue !== undefined ? values.floatValue : ''
}));
}}
placeholder="Enter Cashback Cash"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Status<span className="text-red-500">*</span>
</label>
<Select
value={formField.status}
onValueChange={(e) => setFormField({ ...formField, status: e })}
>
<SelectTrigger>
<SelectValue placeholder="Select a Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">Inactive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Provider ID
</label>
<Select
value={formField.provider}
onValueChange={(e) => setFormField({ ...formField, provider: e })}
>
<SelectTrigger>
<SelectValue placeholder="Select a Provider" />
</SelectTrigger>
<SelectContent>
{providers.map((provider) => (
<SelectItem key={provider.provider_id} value={provider.provider_id}>
{provider.provider_name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Process on Third Party<span className="text-red-500">*</span>
</label>
<Select
value={formField.process_on_third_party}
onValueChange={(value) =>
setFormField({ ...formField, process_on_third_party: value })
}
>
<SelectTrigger>
<SelectValue placeholder="Select Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Yes</SelectItem>
<SelectItem value="N">No</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="flex justify-end gap-5">
<Button type="button" variant="outline" onClick={resetForm}>
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div>
</div>
</form>
)}
</div> </div>
</DialogBody> </DialogBody>
</DialogContent> </DialogContent>

View File

@ -23,6 +23,7 @@ const EditDialog = () => {
const { reload } = useDataGrid(); const { reload } = useDataGrid();
const { PutData, GetData } = useCallApi(); const { PutData, GetData } = useCallApi();
const parsedUser = getAuth()?.user; const parsedUser = getAuth()?.user;
const [isLoading, setIsLoading] = useState(false);
const created_time = new Date(); const created_time = new Date();
const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' '); const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' ');
const [alert, setAlert] = useState({ const [alert, setAlert] = useState({
@ -72,6 +73,7 @@ const EditDialog = () => {
); );
const doFetchData = useCallback(async (id: string) => { const doFetchData = useCallback(async (id: string) => {
setIsLoading(true);
const response = await GetData(`${API_URL}/profession/getdata/${id}`, { id }); const response = await GetData(`${API_URL}/profession/getdata/${id}`, { id });
if (response?.status) { if (response?.status) {
@ -82,6 +84,7 @@ const EditDialog = () => {
} else { } else {
setFormField(initialState); setFormField(initialState);
} }
setIsLoading(false);
}, []); }, []);
const handleUpdate = (e: React.FormEvent<HTMLFormElement>) => { const handleUpdate = (e: React.FormEvent<HTMLFormElement>) => {
@ -134,27 +137,42 @@ const EditDialog = () => {
</Alert> </Alert>
)} )}
<form onSubmit={handleUpdate}> {isLoading ? (
<div className="card-body grid gap-5"> <div className="flex flex-col items-center justify-center p-8">
<div className="w-full"> <div className="animate-pulse flex space-x-4 w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5"> <div className="flex-1 space-y-4 py-1">
<label className="form-label flex items-center gap-1 max-w-56"> <div className="h-4 bg-gray-200 rounded w-3/4"></div>
Name<span className="text-red-500">*</span> <div className="space-y-2">
</label> <div className="h-4 bg-gray-200 rounded"></div>
<Input <div className="h-4 bg-gray-200 rounded w-5/6"></div>
className="input" </div>
type="text"
value={formField.name}
onChange={(e) => setFormField({ ...formField, name: e.target.value })}
/>
</div> </div>
</div> </div>
<p className="mt-4 text-gray-500">Loading Profession Details...</p>
<div className="flex justify-end">
<Button className="btn btn-primary">Save Changes</Button>
</div>
</div> </div>
</form> ) : (
<form onSubmit={handleUpdate}>
<div className="card-body grid gap-5">
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Name<span className="text-red-500">*</span>
</label>
<Input
className="input"
type="text"
value={formField.name}
onChange={(e) => setFormField({ ...formField, name: e.target.value })}
/>
</div>
</div>
<div className="flex justify-end">
<Button className="btn btn-primary">Save Changes</Button>
</div>
</div>
</form>
)}
</div> </div>
</DialogBody> </DialogBody>
</DialogContent> </DialogContent>

View File

@ -33,6 +33,7 @@ const EditDialog = () => {
const { reload } = useDataGrid(); const { reload } = useDataGrid();
const { PutData, GetData } = useCallApi(); const { PutData, GetData } = useCallApi();
const parsedUser = getAuth()?.user; const parsedUser = getAuth()?.user;
const [isLoading, setIsLoading] = useState(false);
const [alert, setAlert] = useState({ const [alert, setAlert] = useState({
show: false, show: false,
message: '' message: ''
@ -93,6 +94,7 @@ const EditDialog = () => {
); );
const doFetchData = useCallback(async (id: string) => { const doFetchData = useCallback(async (id: string) => {
setIsLoading(true);
// console.log('Ini datanya:', id); // console.log('Ini datanya:', id);
const response = await GetData(`${API_URL}/reward/getdata/${id}`, { id }); const response = await GetData(`${API_URL}/reward/getdata/${id}`, { id });
// console.log('API Response:', response); // console.log('API Response:', response);
@ -106,6 +108,7 @@ const EditDialog = () => {
status: response.data.status status: response.data.status
})); }));
} }
setIsLoading(false);
}, []); }, []);
// const handleUpdate = (e: React.FormEvent<HTMLFormElement>) => { // const handleUpdate = (e: React.FormEvent<HTMLFormElement>) => {
@ -159,95 +162,112 @@ const EditDialog = () => {
<div className="flex flex-col"> <div className="flex flex-col">
{alert.show && <Alert variant="danger">{alert.message}</Alert>} {alert.show && <Alert variant="danger">{alert.message}</Alert>}
<form onSubmit={doUpdateReward}> {isLoading ? (
<div className="card-body grid gap-5"> <div className="flex flex-col items-center justify-center p-8">
<div className="grid grid-cols-8 gap-2 w-full items-center"> <div className="animate-pulse flex space-x-4 w-full">
<label className="form-label flex items-center gap-1 col-span-2"> <div className="flex-1 space-y-4 py-1">
Name<span className="text-red-500">*</span> <div className="h-4 bg-gray-200 rounded w-3/4"></div>
</label> <div className="space-y-2">
<div className="h-4 bg-gray-200 rounded"></div>
<Input <div className="h-4 bg-gray-200 rounded w-5/6"></div>
className="input col-span-6" </div>
type="text"
value={formField.name}
onChange={(e) => setFormField((prev) => ({ ...prev, name: e.target.value }))}
/>
</div>
<div className="grid grid-cols-8 gap-2 w-full items-center">
<label className="form-label flex items-center gap-1 col-span-2">
Type<span className="text-red-500">*</span>
</label>
<div className="col-span-6">
<Select
value={formField.type}
onValueChange={(value) => setFormField((prev) => ({ ...prev, type: value }))}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select Type" />
</SelectTrigger>
<SelectContent>
{Object.entries(RewardType).map(
([label, value]: [string, RewardTypeValue]) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
)
)}
</SelectContent>
</Select>
</div> </div>
</div> </div>
<div className="grid grid-cols-8 gap-2 w-full items-center"> <p className="mt-4 text-gray-500">Loading Reward Details...</p>
<label className="form-label flex items-center gap-1 col-span-2">
Amount<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input col-span-6"
value={formField.amount}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
amount: values.floatValue || 0
}));
}}
placeholder="Enter Amount"
/>
</div>
<div className="grid grid-cols-8 gap-2 w-full items-center">
<label className="form-label flex items-center gap-1 col-span-2">
Status<span className="text-red-500">*</span>
</label>
<div className="col-span-6">
<Select
value={formField.status}
onValueChange={(value) =>
setFormField((prev) => ({ ...prev, status: value }))
}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select" defaultValue={formField.status} />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">InActive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="flex justify-end gap-5">
<Button type="button" variant="outline" onClick={resetForm}>
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div>
</div> </div>
</form> ) : (
<form onSubmit={doUpdateReward}>
<div className="card-body grid gap-5">
<div className="grid grid-cols-8 gap-2 w-full items-center">
<label className="form-label flex items-center gap-1 col-span-2">
Name<span className="text-red-500">*</span>
</label>
<Input
className="input col-span-6"
type="text"
value={formField.name}
onChange={(e) => setFormField((prev) => ({ ...prev, name: e.target.value }))}
/>
</div>
<div className="grid grid-cols-8 gap-2 w-full items-center">
<label className="form-label flex items-center gap-1 col-span-2">
Type<span className="text-red-500">*</span>
</label>
<div className="col-span-6">
<Select
value={formField.type}
onValueChange={(value) =>
setFormField((prev) => ({ ...prev, type: value }))
}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select Type" />
</SelectTrigger>
<SelectContent>
{Object.entries(RewardType).map(
([label, value]: [string, RewardTypeValue]) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
)
)}
</SelectContent>
</Select>
</div>
</div>
<div className="grid grid-cols-8 gap-2 w-full items-center">
<label className="form-label flex items-center gap-1 col-span-2">
Amount<span className="text-red-500">*</span>
</label>
<NumericFormat
className="input col-span-6"
value={formField.amount}
thousandSeparator="."
decimalSeparator=","
allowNegative={false}
onValueChange={(values) => {
setFormField((prev) => ({
...prev,
amount: values.floatValue || 0
}));
}}
placeholder="Enter Amount"
/>
</div>
<div className="grid grid-cols-8 gap-2 w-full items-center">
<label className="form-label flex items-center gap-1 col-span-2">
Status<span className="text-red-500">*</span>
</label>
<div className="col-span-6">
<Select
value={formField.status}
onValueChange={(value) =>
setFormField((prev) => ({ ...prev, status: value }))
}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select" defaultValue={formField.status} />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">InActive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="flex justify-end gap-5">
<Button type="button" variant="outline" onClick={resetForm}>
Reset
</Button>
<Button variant="default">Save Changes</Button>
</div>
</div>
</form>
)}
</div> </div>
</DialogBody> </DialogBody>
</DialogContent> </DialogContent>

View File

@ -45,6 +45,7 @@ const EditDialog = () => {
const { showEditDialog, handleEditDialog, selectedWallet } = useManageWalletContext(); const { showEditDialog, handleEditDialog, selectedWallet } = useManageWalletContext();
const { reload } = useDataGrid(); const { reload } = useDataGrid();
const { GetData, PutData } = useCallApi(); const { GetData, PutData } = useCallApi();
const [isLoading, setIsLoading] = useState(false);
const [alert, setAlert] = useState({ const [alert, setAlert] = useState({
show: false, show: false,
message: '' message: ''
@ -115,6 +116,7 @@ const EditDialog = () => {
}; };
const doFetchData = useCallback(async (id: string) => { const doFetchData = useCallback(async (id: string) => {
setIsLoading(true);
const response = await GetData(`${API_URL_MASTER_DATA}/wallet/detail/${id}`, { const response = await GetData(`${API_URL_MASTER_DATA}/wallet/detail/${id}`, {
id id
}); });
@ -132,6 +134,7 @@ const EditDialog = () => {
: [] : []
})); }));
} }
setIsLoading(false);
}, []); }, []);
const getCurrencyLists = async (sorting: any) => { const getCurrencyLists = async (sorting: any) => {
@ -213,91 +216,110 @@ const EditDialog = () => {
</Alert> </Alert>
)} )}
<form onSubmit={handleSubmit}> {isLoading ? (
<div className="card-body grid gap-5"> <div className="flex flex-col items-center justify-center p-8">
<div className="w-full"> <div className="animate-pulse flex space-x-4 w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5"> <div className="flex-1 space-y-4 py-1">
<label className="form-label flex items-center gap-1 max-w-56"> <div className="h-4 bg-gray-200 rounded w-3/4"></div>
Wallet Name <div className="space-y-2">
</label> <div className="h-4 bg-gray-200 rounded"></div>
<Input <div className="h-4 bg-gray-200 rounded w-5/6"></div>
type="text"
value={formField.name}
onChange={(e) => setFormField({ ...formField, name: e.target.value })}
placeholder="Wallet Name"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Description
</label>
<Input
type="text"
value={formField.description}
onChange={(e) => setFormField({ ...formField, description: e.target.value })}
placeholder="Description"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Status</label>
<Select
value={formField.status}
onValueChange={(value) => setFormField({ ...formField, status: value })}
>
<SelectTrigger>
<SelectValue placeholder="Select Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">Inactive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Currency</label>
<div className="relative w-full">
<Input
type="text"
placeholder="Empty"
value={selectedCurrency?.name}
readOnly
className="bg-gray-100 border border-dashed border-gray-400 text-gray-600 cursor-not-allowed"
/>
</div> </div>
</div> </div>
</div> </div>
<p className="mt-4 text-gray-500">Loading Wallet Details...</p>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Groups</label>
<div className="relative w-full">
<Input
type="text"
placeholder="Empty"
value={selectedGroupNames}
readOnly
className="bg-gray-100 border border-dashed border-gray-400 text-gray-600 cursor-not-allowed"
/>
</div>
</div>
</div>
<div className="flex justify-end gap-5">
<Button variant="default" type="submit">
Update
</Button>
</div>
</div> </div>
</form> ) : (
<form onSubmit={handleSubmit}>
<div className="card-body grid gap-5">
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Wallet Name
</label>
<Input
type="text"
value={formField.name}
onChange={(e) => setFormField({ ...formField, name: e.target.value })}
placeholder="Wallet Name"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Description
</label>
<Input
type="text"
value={formField.description}
onChange={(e) =>
setFormField({ ...formField, description: e.target.value })
}
placeholder="Description"
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Status</label>
<Select
value={formField.status}
onValueChange={(value) => setFormField({ ...formField, status: value })}
>
<SelectTrigger>
<SelectValue placeholder="Select Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Y">Active</SelectItem>
<SelectItem value="N">Inactive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">
Currency
</label>
<div className="relative w-full">
<Input
type="text"
placeholder="Empty"
value={selectedCurrency?.name}
readOnly
className="bg-gray-100 border border-dashed border-gray-400 text-gray-600 cursor-not-allowed"
/>
</div>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Groups</label>
<div className="relative w-full">
<Input
type="text"
placeholder="Empty"
value={selectedGroupNames}
readOnly
className="bg-gray-100 border border-dashed border-gray-400 text-gray-600 cursor-not-allowed"
/>
</div>
</div>
</div>
<div className="flex justify-end gap-5">
<Button variant="default" type="submit">
Update
</Button>
</div>
</div>
</form>
)}
</div> </div>
</DialogBody> </DialogBody>
</DialogContent> </DialogContent>