253 lines
9.8 KiB
TypeScript
253 lines
9.8 KiB
TypeScript
import { Alert, useDataGrid } from '@/components';
|
|
import { useManageMenusContext } from '../hooks/useManageMenusContext';
|
|
import { useCallApi } from '@/hooks';
|
|
import { apiConfig } from '@/config/api.config';
|
|
import React, { useCallback, useState, useEffect } from 'react';
|
|
import { toast } from 'sonner';
|
|
import {
|
|
Dialog,
|
|
DialogBody,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle
|
|
} from '@/components/ui/dialog';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue
|
|
} from '@/components/ui/select';
|
|
import { doSaveLogActivity } from '@/actions/GlobalActions';
|
|
import { initialStateMenu, validateFormsMenu } from './Types';
|
|
import { NumericFormat } from 'react-number-format';
|
|
|
|
const API_URL = apiConfig.service_dashboard;
|
|
|
|
const EditDialog = () => {
|
|
const { showEditDialog, handleEditDialog, selectedMenu, setSelectedMenu, parents }: any =
|
|
useManageMenusContext();
|
|
const { reload } = useDataGrid();
|
|
const { PutData } = useCallApi();
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [errors, setErrors] = useState<Record<string, string>>({});
|
|
|
|
const handleUpdate = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setIsSubmitting(true);
|
|
|
|
if (!validateFormsMenu(selectedMenu, setErrors)) {
|
|
setIsSubmitting(false);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const updateMenu = selectedMenu;
|
|
if (updateMenu.id_parent === null) updateMenu.id_parent = '';
|
|
delete updateMenu.parentName;
|
|
const response = await PutData(`${API_URL}/menus/update/${selectedMenu.id}`, selectedMenu);
|
|
if (response?.status) {
|
|
handleEditDialog(false, null);
|
|
resetForm();
|
|
toast.success('Success Update Menu');
|
|
const createActivity = {
|
|
module: 'Manage Menu',
|
|
description: `Update Menu => ${selectedMenu.name}`,
|
|
action: 'U'
|
|
};
|
|
|
|
doSaveLogActivity(createActivity);
|
|
reload();
|
|
} else {
|
|
toast.error(response?.message);
|
|
}
|
|
} catch (error) {
|
|
toast.error('Something went wrong, please trt again.');
|
|
} finally {
|
|
setIsSubmitting(false);
|
|
setErrors({});
|
|
}
|
|
};
|
|
|
|
const resetForm = () => {
|
|
setSelectedMenu(initialStateMenu);
|
|
setErrors({});
|
|
};
|
|
|
|
return (
|
|
<Dialog open={showEditDialog} onOpenChange={(open) => handleEditDialog(open, null)}>
|
|
<DialogContent className="container-fixed max-w-[768px] flex flex-col p-5 overflow-hidden">
|
|
<DialogHeader>
|
|
<DialogTitle>Menu - Update</DialogTitle>
|
|
<DialogDescription></DialogDescription>
|
|
</DialogHeader>
|
|
<DialogBody className="scrollable">
|
|
<div className="flex flex-col">
|
|
<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">
|
|
Module<span className="text-red-500">*</span>
|
|
</label>
|
|
<Input
|
|
className={`input ${errors.module ? 'border-red-500' : ''}`}
|
|
type="text"
|
|
value={selectedMenu.module}
|
|
onChange={(e) => {
|
|
setSelectedMenu({ ...selectedMenu, module: e.target.value });
|
|
setErrors({ ...errors, module: '' });
|
|
}}
|
|
/>
|
|
{errors.module && (
|
|
<span className="text-red-500 text-xs mt-1">{errors.module}</span>
|
|
)}
|
|
{/* </div> */}
|
|
</div>
|
|
|
|
<div className="w-full">
|
|
<label className="form-label flex items-center gap-1 max-w-56">
|
|
Name<span className="text-red-500">*</span>
|
|
</label>
|
|
<Input
|
|
className={`input ${errors.name ? 'border-red-500' : ''}`}
|
|
type="text"
|
|
value={selectedMenu.name}
|
|
onChange={(e) => {
|
|
setSelectedMenu({ ...selectedMenu, name: e.target.value });
|
|
setErrors({ ...errors, name: '' });
|
|
}}
|
|
/>
|
|
{errors.name && <span className="text-red-500 text-xs mt-1">{errors.name}</span>}
|
|
</div>
|
|
|
|
<div className="w-full">
|
|
<label className="form-label flex items-center gap-1 max-w-56">
|
|
Link<span className="text-red-500">*</span>
|
|
</label>
|
|
<Input
|
|
className={`input ${errors.link ? 'border-red-500' : ''}`}
|
|
type="text"
|
|
value={selectedMenu.link}
|
|
onChange={(e) => setSelectedMenu({ ...selectedMenu, link: e.target.value })}
|
|
/>
|
|
{errors.link && <span className="text-red-500 text-xs mt-1">{errors.link}</span>}
|
|
</div>
|
|
|
|
<div className="w-full">
|
|
<label className="form-label flex items-center gap-1 max-w-56">Parent</label>
|
|
<Select
|
|
value={selectedMenu.id_parent || ''}
|
|
onValueChange={(value) => {
|
|
setSelectedMenu({
|
|
...selectedMenu,
|
|
id_parent: value === '' ? null : value
|
|
});
|
|
setErrors({ ...errors, id_parent: '' });
|
|
}}
|
|
>
|
|
<SelectTrigger className={errors.id_parent ? 'border-red-500' : ''}>
|
|
<SelectValue placeholder="Select As Parent" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{parents.map((parent: any) => (
|
|
<SelectItem key={parent.id} value={parent.id}>
|
|
{parent.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
{errors.id_parent && (
|
|
<span className="text-red-500 text-xs mt-1">{errors.id_parent}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="w-full">
|
|
<label className="form-label flex items-center gap-1 max-w-56">
|
|
Order Number
|
|
</label>
|
|
<NumericFormat
|
|
className={`input ${errors.order_number ? 'border-red-500' : ''}`}
|
|
value={selectedMenu.order_number}
|
|
allowNegative={false}
|
|
onValueChange={(e) =>
|
|
setSelectedMenu({ ...selectedMenu, order_number: e.floatValue ?? null })
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
<div className="w-full">
|
|
<label className="form-label flex items-center gap-1 max-w-56">Icon</label>
|
|
<Input
|
|
className="input"
|
|
type="text"
|
|
value={selectedMenu.icon}
|
|
onChange={(e) => setSelectedMenu({ ...selectedMenu, icon: e.target.value })}
|
|
/>
|
|
</div>
|
|
|
|
<div className="w-full">
|
|
<label className="form-label flex items-center gap-1 max-w-56">
|
|
Status<span className="text-red-500">*</span>
|
|
</label>
|
|
<Select
|
|
value={selectedMenu.status}
|
|
onValueChange={(value) => {
|
|
setSelectedMenu({ ...selectedMenu, status: value });
|
|
setErrors({ ...errors, status: '' });
|
|
}}
|
|
>
|
|
<SelectTrigger className={errors.status ? 'border-red-500' : ''}>
|
|
<SelectValue placeholder="Select Status" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="Y">Active</SelectItem>
|
|
<SelectItem value="N">Inactive</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
{errors.status && (
|
|
<span className="text-red-500 text-xs mt-1">{errors.status}</span>
|
|
)}
|
|
</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>
|
|
<FormControl fullWidth margin="dense">
|
|
<NativeSelect
|
|
defaultValue={30}
|
|
value={selectedMenu.status}
|
|
onChange={(e) => setSelectedMenu({ ...selectedMenu, status: e.target.value })}
|
|
inputProps={{
|
|
name: 'status',
|
|
id: 'uncontrolled-native',
|
|
}}
|
|
>
|
|
<option value={"Y"}>Active</option>
|
|
<option value={"N"}>Inactive</option>
|
|
</NativeSelect>
|
|
</FormControl>
|
|
</div>
|
|
</div> */}
|
|
|
|
<div className="flex justify-end pt-2.5">
|
|
<Button className="btn btn-primary" type="submit" disabled={isSubmitting}>
|
|
{isSubmitting ? 'Saving...' : 'Save Changes'}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</DialogBody>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
};
|
|
|
|
export default EditDialog;
|