diff --git a/src/layouts/demo2/header/HeaderLogo.tsx b/src/layouts/demo2/header/HeaderLogo.tsx index 443be9e..03fb815 100644 --- a/src/layouts/demo2/header/HeaderLogo.tsx +++ b/src/layouts/demo2/header/HeaderLogo.tsx @@ -19,6 +19,16 @@ const HeaderLogo = () => { const { pathname } = useLocation(); const { isRTL } = useLanguage(); const [selectedMenuItem, setSelectedMenuItem] = useState(MENU_ROOT[0]); + const [isSticky, setIsSticky] = useState(false); + + useEffect(() => { + const handleScroll = () => { + setIsSticky(window.scrollY > 100); + }; + + window.addEventListener('scroll', handleScroll); + return () => window.removeEventListener('scroll', handleScroll); + }, []); useEffect(() => { MENU_ROOT.forEach((item) => { @@ -55,7 +65,9 @@ const HeaderLogo = () => {
-

TPAY Dashboard Portal

+
); diff --git a/src/pages/master/aldeias/blocks/AddDialog.tsx b/src/pages/master/aldeias/blocks/AddDialog.tsx index a1c566c..7d33c9b 100644 --- a/src/pages/master/aldeias/blocks/AddDialog.tsx +++ b/src/pages/master/aldeias/blocks/AddDialog.tsx @@ -27,8 +27,8 @@ import { import { doSaveLogActivity } from '@/actions/GlobalActions'; interface SucosProps { - sucos_id: number; - sucos_name: string; + id: number; + name: string; } const API_URL = apiConfig.service_master_data; @@ -181,7 +181,7 @@ const AddDialog = () => { className="input col-span-5 text-left" style={{ color: 'inherit' }} > - {sucos.find((suco) => suco.sucos_id === formField.sucosId)?.sucos_name || + {sucos.find((suco) => suco.id === formField.sucosId)?.name || 'Select Sucos'} @@ -196,17 +196,17 @@ const AddDialog = () => { {sucos.map((suco) => ( { setFormField({ ...formField, - sucosId: suco.sucos_id + sucosId: suco.id }); setOpen(false); }} > - {suco.sucos_name} + {suco.name} ))} diff --git a/src/pages/master/aldeias/blocks/DeleteDialog.tsx b/src/pages/master/aldeias/blocks/DeleteDialog.tsx index 44f0a81..e98df8c 100644 --- a/src/pages/master/aldeias/blocks/DeleteDialog.tsx +++ b/src/pages/master/aldeias/blocks/DeleteDialog.tsx @@ -4,7 +4,14 @@ import { Alert, useDataGrid } from '@/components'; import { useCallApi } from '@/hooks'; import { useCallback, useState } from 'react'; import { toast } from 'sonner'; -import { Dialog, DialogContent, DialogFooter, DialogHeader } from '@/components/ui/dialog'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { doSaveLogActivity } from '@/actions/GlobalActions'; @@ -52,6 +59,8 @@ const DeleteDialog = () => { handleDeleteDialog(open, null)}> + +

Are you sure?

You will delete this data! diff --git a/src/pages/master/aldeias/blocks/EditDialog.tsx b/src/pages/master/aldeias/blocks/EditDialog.tsx index 0eec124..a7bcb66 100644 --- a/src/pages/master/aldeias/blocks/EditDialog.tsx +++ b/src/pages/master/aldeias/blocks/EditDialog.tsx @@ -27,8 +27,8 @@ import { import { doSaveLogActivity } from '@/actions/GlobalActions'; interface SucosProps { - sucos_id: number; - sucos_name: string; + id: number; + name: string; } const API_URL = apiConfig.service_master_data; @@ -40,6 +40,7 @@ const EditDialog = () => { const parsedUser = getAuth()?.user; const [sucos, setSucos] = useState([]); const [open, setOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); const [alert, setAlert] = useState({ show: false, message: '' @@ -96,8 +97,8 @@ const EditDialog = () => { order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' }); - // console.log('SUCOS', response?.data); setSucos(response?.data.list); + // console.log(sucos); } catch (error) { console.error('Error fetching Sucos', error); setAlert({ show: true, message: 'Failed to get Sucos. Please try again.' }); @@ -105,7 +106,11 @@ const EditDialog = () => { }; const doFetchData = useCallback(async (id: string) => { - const response = await GetData(`${API_URL}/aldeias/getdata/${id}`, { id }); + setIsLoading(true); + + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/aldeias/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); if (response?.status) { setFormField((prev) => ({ @@ -120,6 +125,7 @@ const EditDialog = () => { sucosId: 0 })); } + setIsLoading(false); }, []); const handleUpdate = (e: React.FormEvent) => { @@ -176,72 +182,87 @@ const EditDialog = () => {
)} -
-
-
-
- - setFormField({ ...formField, name: e.target.value })} - /> + {isLoading ? ( +
+
+
+
+
+
+
+
- -
-
- - - - - - - - - - No Sucos found. - - {sucos.map((suco) => ( - { - setFormField({ - ...formField, - sucosId: suco.sucos_id - }); - setOpen(false); - }} - > - {suco.sucos_name} - - ))} - - - - - -
-
- -
- -
+

Loading Aldeia Details...

- + ) : ( +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + /> +
+
+ +
+
+ + + + + + + + + + No Sucos found. + + {sucos.map((suco) => ( + { + setFormField({ + ...formField, + sucosId: suco.id + }); + setOpen(false); + }} + > + {suco.name} + + ))} + + + + + +
+
+ +
+ +
+
+
+ )}
diff --git a/src/pages/master/aldeias/blocks/ListToolbar.tsx b/src/pages/master/aldeias/blocks/ListToolbar.tsx index c5c77ab..26401b0 100644 --- a/src/pages/master/aldeias/blocks/ListToolbar.tsx +++ b/src/pages/master/aldeias/blocks/ListToolbar.tsx @@ -1,12 +1,14 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; import { useManageAldeiasContext } from '../hooks/useManageAldeiasContext'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; const ListToolbar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog, handleSearchDialog } = useManageAldeiasContext(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { @@ -19,6 +21,15 @@ const ListToolbar = () => { table.setPageIndex(0); }; + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -28,17 +39,11 @@ const ListToolbar = () => { setSearchValue(event.target.value)} - onKeyDown={handleKeyDown} /> - - - {/* + +
-
- - -
-
- + + )}
diff --git a/src/pages/master/currency/blocks/EditDialog.tsx b/src/pages/master/currency/blocks/EditDialog.tsx index 57a4c07..e0dffd8 100644 --- a/src/pages/master/currency/blocks/EditDialog.tsx +++ b/src/pages/master/currency/blocks/EditDialog.tsx @@ -49,6 +49,7 @@ const EditDialog = () => { const parsedUser = getAuth()?.user; const [currencies, setCurrencies] = useState([]); const [open, setOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); const [alert, setAlert] = useState({ show: false, message: '' @@ -98,8 +99,12 @@ const EditDialog = () => { [formField] ); - const doGetCurrencyById = useCallback(async (id: string) => { - const response = await GetData(`${API_URL}/dashboard/currency/${id}`, { id }); + const doFetchData = useCallback(async (id: string) => { + setIsLoading(true); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/dashboard/currency/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); + // console.log('Transaction Type: ', response?.data); if (response?.status) { setFormField((prev) => ({ @@ -110,12 +115,13 @@ const EditDialog = () => { prefix: response.data.prefix })); } + setIsLoading(false); // console.log('form fieldd Transaction Type: ', formField); }, []); useEffect(() => { if (selectedCurrency) { - doGetCurrencyById(selectedCurrency); + doFetchData(selectedCurrency); } }, [selectedCurrency]); @@ -150,74 +156,93 @@ const EditDialog = () => { )} -
-
-
- - setFormField((prev) => ({ ...prev, code: e.target.value }))} - /> -
-
- - setFormField((prev) => ({ ...prev, name: e.target.value }))} - /> -
- -
- - setFormField((prev) => ({ ...prev, prefix: e.target.value }))} - /> -
- -
- - - -
- -
- - + {isLoading ? ( +
+
+
+
+
+
+
+
+
+

Loading Currency Details...

- + ) : ( +
+
+
+ + setFormField((prev) => ({ ...prev, code: e.target.value }))} + /> +
+
+ + setFormField((prev) => ({ ...prev, name: e.target.value }))} + /> +
+ +
+ + + setFormField((prev) => ({ ...prev, prefix: e.target.value })) + } + /> +
+ +
+ + + +
+ +
+ + +
+
+
+ )}
diff --git a/src/pages/master/municipios/Municipios.tsx b/src/pages/master/municipios/Municipios.tsx index 253ff86..9d548e6 100644 --- a/src/pages/master/municipios/Municipios.tsx +++ b/src/pages/master/municipios/Municipios.tsx @@ -1,7 +1,6 @@ import { Container, DataGridInner } from '@/components'; import { ManageMunicipiosProvider } from './hooks/ManageMunicipiosContext'; import AddDialog from './blocks/AddDialog'; -import SearchDialog from './blocks/SearchDialog'; import EditDialog from './blocks/EditDialog'; import DeleteDialog from './blocks/DeleteDialog'; import { Breadcrumbs, Link } from '@mui/material'; @@ -35,7 +34,6 @@ const Municipios = () => { - diff --git a/src/pages/master/municipios/blocks/EditDialog.tsx b/src/pages/master/municipios/blocks/EditDialog.tsx index 6b6724a..ef7b3d3 100644 --- a/src/pages/master/municipios/blocks/EditDialog.tsx +++ b/src/pages/master/municipios/blocks/EditDialog.tsx @@ -26,6 +26,7 @@ const EditDialog = () => { const { reload } = useDataGrid(); const { PutData, GetData } = useCallApi(); const parsedUser = getAuth()?.user; + const [isLoading, setIsLoading] = useState(false); const [alert, setAlert] = useState({ show: false, message: '' @@ -75,7 +76,10 @@ const EditDialog = () => { ); const doFetchData = useCallback(async (id: string) => { - const response = await GetData(`${API_URL}/municipios/getdata/${id}`, { id }); + setIsLoading(true); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/municipios/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); if (response?.status) { setFormField((prev) => ({ @@ -88,6 +92,7 @@ const EditDialog = () => { name: '' })); } + setIsLoading(false); }, []); const handleUpdate = (e: React.FormEvent) => { @@ -141,27 +146,42 @@ const EditDialog = () => { )} -
-
-
-
- - setFormField({ ...formField, name: e.target.value })} - /> + {isLoading ? ( +
+
+
+
+
+
+
+
- -
- -
+

Loading Municipio Details...

- + ) : ( +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + /> +
+
+ +
+ +
+
+
+ )}
diff --git a/src/pages/master/municipios/blocks/ListToolbar.tsx b/src/pages/master/municipios/blocks/ListToolbar.tsx index 140850c..62092ea 100644 --- a/src/pages/master/municipios/blocks/ListToolbar.tsx +++ b/src/pages/master/municipios/blocks/ListToolbar.tsx @@ -1,7 +1,7 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManageMunicipiosContext } from '../hooks/useManageMunicipiosContext'; import { Button } from '@/components/ui/button'; -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { toast } from 'sonner'; const ListToolbar = () => { @@ -9,48 +9,33 @@ const ListToolbar = () => { const { handleAddDialog, handleSearchDialog } = useManageMunicipiosContext(); const [searchName, setSearchName] = useState(''); const [isLoading, setIsLoading] = useState(false); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); - const handleFilterData = useCallback(() => { - try { - table.getColumn('name')?.setFilterValue(searchName); - } catch (error) { - toast.error('Error applying filter'); - console.error('Error applying filter:', error); - } - }, [searchName, table]); + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); - const handleKeyDown = (event: React.KeyboardEvent) => { - if (event.key === 'Enter') { - handleSearch(); - } - }; - - const handleSearch = () => { - table.getColumn('name')?.setFilterValue(searchValue); - table.setPageIndex(0); - }; + return () => clearTimeout(timer); + }, [searchValue, table]); return (
-
-
- -
- - -
- ); -}; - -export default SearchDialog; diff --git a/src/pages/master/municipios/hooks/ManageMunicipiosContext.tsx b/src/pages/master/municipios/hooks/ManageMunicipiosContext.tsx index 3fcb85e..9946333 100644 --- a/src/pages/master/municipios/hooks/ManageMunicipiosContext.tsx +++ b/src/pages/master/municipios/hooks/ManageMunicipiosContext.tsx @@ -132,7 +132,7 @@ const ManageMunicipiosProvider = ({ children }: { children: React.ReactNode }) = ); }, meta: { - headerClassName: 'w-[100px]', + headerClassName: 'w-[100px] text-center', cellClassName: 'text-center' } } diff --git a/src/pages/master/postoadms/PostoAdmsMaster.tsx b/src/pages/master/postoadms/PostoAdmsMaster.tsx index 90823ab..275760a 100644 --- a/src/pages/master/postoadms/PostoAdmsMaster.tsx +++ b/src/pages/master/postoadms/PostoAdmsMaster.tsx @@ -1,7 +1,6 @@ import AddDialog from './blocks/AddDialog'; import DeleteDialog from './blocks/DeleteDialog'; import EditDialog from './blocks/EditDialog'; -import SearchDialog from './blocks/SearchDialog'; import { ManagePostoAdmsContextProvider } from './hooks/ManagePostoAdmsContext'; import { Container, DataGridInner } from '@/components'; import { Breadcrumbs, Link } from '@mui/material'; @@ -37,7 +36,6 @@ const PostoAdmsMaster = () => { - diff --git a/src/pages/master/postoadms/blocks/EditDialog.tsx b/src/pages/master/postoadms/blocks/EditDialog.tsx index fd68b10..d33d318 100644 --- a/src/pages/master/postoadms/blocks/EditDialog.tsx +++ b/src/pages/master/postoadms/blocks/EditDialog.tsx @@ -41,6 +41,7 @@ const EditDialog = () => { const { PutData, GetData } = useCallApi(); const parsedUser = getAuth()?.user; const [open, setOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); const [municipios, setMunicipios] = useState([]); const [alert, setAlert] = useState({ @@ -112,7 +113,10 @@ const EditDialog = () => { }, []); const doFetchData = useCallback(async (id: string) => { - const response = await GetData(`${API_URL}/postoadms/getdata/${id}`, { id }); + setIsLoading(true); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = await GetData(`${API_URL}/postoadms/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); if (response?.status) { setFormField((prev) => ({ @@ -126,6 +130,7 @@ const EditDialog = () => { name: '' })); } + setIsLoading(false); }, []); const handleUpdate = (e: React.FormEvent) => { @@ -184,71 +189,86 @@ const EditDialog = () => { )} -
-
-
-
- - setFormField({ ...formField, name: e.target.value })} - /> + {isLoading ? ( +
+
+
+
+
+
+
+
- -
-
- - - - - - - - - - No Municipio found. - - {municipios.map((municipio) => ( - { - setFormField({ - ...formField, - municipio_id: municipio.id - }); - setOpen(false); - }} - > - {municipio.name} - - ))} - - - - - -
-
- -
- - -
+

Loading Postu Administrativo Details...

- + ) : ( +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + /> +
+
+ +
+
+ + + + + + + + + + No Municipio found. + + {municipios.map((municipio) => ( + { + setFormField({ + ...formField, + municipio_id: municipio.id + }); + setOpen(false); + }} + > + {municipio.name} + + ))} + + + + + +
+
+ +
+ + +
+
+
+ )}
diff --git a/src/pages/master/postoadms/blocks/ListToolbar.tsx b/src/pages/master/postoadms/blocks/ListToolbar.tsx index 6d2e7ca..e181848 100644 --- a/src/pages/master/postoadms/blocks/ListToolbar.tsx +++ b/src/pages/master/postoadms/blocks/ListToolbar.tsx @@ -2,12 +2,14 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; import { useManagePostoAdmsContext } from '../hooks/useManagePostoAdmsContext'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; const ListToolbar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog, handleSearchDialog } = useManagePostoAdmsContext(); - const [searchPosto, setSearchPosto] = useState(''); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { @@ -16,10 +18,19 @@ const ListToolbar = () => { }; const handleSearch = () => { - table.getColumn('name')?.setFilterValue(searchPosto); + table.getColumn('name')?.setFilterValue(searchValue); table.setPageIndex(0); }; + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -30,34 +41,15 @@ const ListToolbar = () => { setSearchPosto(event.target.value)} - onKeyDown={handleKeyDown} + value={searchValue} + onChange={(event) => setSearchValue(event.target.value)} /> - + {/* - - {/* - */} - {/* */}
- - - - - - No PostoAdms found. - - {postoAdms.map((postoAdm) => ( - { - setFormField({ - id: postoAdm.PostoAdms_id, - name: postoAdm.PostoAdms_name - }); - setOpen(false); - }} - > - {postoAdm.PostoAdms_name} - - ))} - - - - - -
- - {isFound && sucos.length > 0 && ( -
-

Sucos:

-
- - {sucos.map((suco) => suco.name).join(', ')} - -
-
- )} - -
- - -
- - - - - ); -}; - -export default SearchDialog; diff --git a/src/pages/master/postoadms/hooks/ManagePostoAdmsContext.tsx b/src/pages/master/postoadms/hooks/ManagePostoAdmsContext.tsx index 06a76c4..4fd1416 100644 --- a/src/pages/master/postoadms/hooks/ManagePostoAdmsContext.tsx +++ b/src/pages/master/postoadms/hooks/ManagePostoAdmsContext.tsx @@ -131,7 +131,7 @@ const ManagePostoAdmsContextProvider = ({ children }: { children: React.ReactNod ); }, meta: { - headerClassName: 'w-[100px]', + headerClassName: 'w-[100px] text-center', cellClassName: 'text-center' } } diff --git a/src/pages/master/products/blocks/EditDialog.tsx b/src/pages/master/products/blocks/EditDialog.tsx index 493489d..f82dbc0 100644 --- a/src/pages/master/products/blocks/EditDialog.tsx +++ b/src/pages/master/products/blocks/EditDialog.tsx @@ -36,6 +36,7 @@ const EditDialog = () => { const { reload } = useDataGrid(); const { PutData, GetData } = useCallApi(); const parsedUser = getAuth()?.user; + const [isLoading, setIsLoading] = useState(false); const created_time = new Date(); const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' '); const [alert, setAlert] = useState({ @@ -123,7 +124,12 @@ const EditDialog = () => { }, []); const doFetchData = useCallback(async (id: string) => { - const response = await GetData(`${API_URL}/product/getdata/${id}`, { id }); + setIsLoading(true); + + const minDelay = new Promise((resolve) => setTimeout(resolve, 500)); + const fetchData = GetData(`${API_URL}/product/getdata/${id}`, { id }); + + const [response] = await Promise.all([fetchData, minDelay]); // console.log(response); if (response?.status) { @@ -144,6 +150,7 @@ const EditDialog = () => { } else { setFormField(initialState); } + setIsLoading(false); }, []); const handleUpdate = (e: React.FormEvent) => { @@ -214,225 +221,242 @@ const EditDialog = () => { )} -
-
-
-
- - setFormField({ ...formField, name: e.target.value })} - /> + {isLoading ? ( +
+
+
+
+
+
+
+
- -
-
- - setFormField({ ...formField, type: e.target.value })} - /> -
-
- -
-
- - setFormField({ ...formField, code: e.target.value })} - /> -
-
- -
-
- - setFormField({ ...formField, description: e.target.value })} - /> -
-
- -
-
- - { - setFormField((prev) => ({ - ...prev, - price_point: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Price Point" - /> -
-
- -
-
- - { - setFormField((prev) => ({ - ...prev, - price_cash: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Price Cash" - /> -
-
- -
-
- - { - setFormField((prev) => ({ - ...prev, - cashback_point: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Cashback Point" - /> -
-
- -
-
- - { - setFormField((prev) => ({ - ...prev, - cashback_cash: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Cashback Cash" - /> -
-
- -
-
- - -
-
- -
-
- - -
-
- -
-
- - -
-
- -
- - -
+

Loading Products Details...

- + ) : ( +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + /> +
+
+ +
+
+ + setFormField({ ...formField, type: e.target.value })} + /> +
+
+ +
+
+ + setFormField({ ...formField, code: e.target.value })} + /> +
+
+ +
+
+ + + setFormField({ ...formField, description: e.target.value }) + } + /> +
+
+ +
+
+ + { + setFormField((prev) => ({ + ...prev, + price_point: values.floatValue !== undefined ? values.floatValue : '' + })); + }} + placeholder="Enter Price Point" + /> +
+
+ +
+
+ + { + setFormField((prev) => ({ + ...prev, + price_cash: values.floatValue !== undefined ? values.floatValue : '' + })); + }} + placeholder="Enter Price Cash" + /> +
+
+ +
+
+ + { + setFormField((prev) => ({ + ...prev, + cashback_point: values.floatValue !== undefined ? values.floatValue : '' + })); + }} + placeholder="Enter Cashback Point" + /> +
+
+ +
+
+ + { + setFormField((prev) => ({ + ...prev, + cashback_cash: values.floatValue !== undefined ? values.floatValue : '' + })); + }} + placeholder="Enter Cashback Cash" + /> +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+ + +
+
+
+ )}
diff --git a/src/pages/master/products/blocks/ListToolbar.tsx b/src/pages/master/products/blocks/ListToolbar.tsx index 92bd362..c8620f6 100644 --- a/src/pages/master/products/blocks/ListToolbar.tsx +++ b/src/pages/master/products/blocks/ListToolbar.tsx @@ -1,10 +1,23 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManageProductsContext } from '../hooks/useManageProductsContext'; import { Button } from '@/components/ui/button'; +import { useEffect, useState } from 'react'; const ListToolbar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog } = useManageProductsContext(); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); + + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); return (
@@ -15,22 +28,11 @@ const ListToolbar = () => { table.getColumn('name')?.setFilterValue(event.target.value)} + placeholder="Search" + value={searchValue} + onChange={(event) => setSearchValue(event.target.value)} /> - {/* - - */}
-
+

Loading Profession Details...

- + ) : ( +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + /> +
+
+ +
+ +
+
+
+ )}
diff --git a/src/pages/master/profession/blocks/ListToolbar.tsx b/src/pages/master/profession/blocks/ListToolbar.tsx index 9c04194..4d5e55c 100644 --- a/src/pages/master/profession/blocks/ListToolbar.tsx +++ b/src/pages/master/profession/blocks/ListToolbar.tsx @@ -1,10 +1,24 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManageProfessionContext } from '../hooks/useManageProfessionContext'; import { Button } from '@/components/ui/button'; +import { useEffect, useState } from 'react'; +import { set } from 'date-fns'; const ListToolbar = () => { const { reload, table } = useDataGrid(); const { handleAddDialog } = useManageProfessionContext(); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); + + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); return (
@@ -15,24 +29,11 @@ const ListToolbar = () => { - table.getColumn('name')?.setFilterValue(event.target.value) - } + placeholder="Search" + value={searchValue} + onChange={(event) => setSearchValue(event.target.value)} /> - {/* - - */}
- - - - - { - e.currentTarget.scrollTop += e.deltaY; - }} - > - No Agent found. - - {customers.map((customer) => ( - { - setFormField({ - ...formField, - agent: customer.id - }); - setOpen(false); - }} - > - {customer.username} - - ))} - - - - - + {isLoading ? ( +
+
+
+
+
+
+
- ) : ( -
-
- - -
-
- )} - -
-
+

Loading Provider Details...

- + ) : ( +
+
+
+
+ + + setFormField((prev) => ({ ...prev, name: target.value })) + } + /> +
+
+ +
+
+ + + setFormField({ ...formField, description: e.target.value }) + } + /> +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ + {formField.type === 'agent' ? ( +
+
+ + + + + + + + + { + e.currentTarget.scrollTop += e.deltaY; + }} + > + No Agent found. + + {customers.map((customer) => ( + { + setFormField({ + ...formField, + agent: customer.id + }); + setOpen(false); + }} + > + {customer.username} + + ))} + + + + + +
+
+ ) : ( +
+
+ + +
+
+ )} + +
+ +
+
+
+ )}
diff --git a/src/pages/master/provider/blocks/ListToolbar.tsx b/src/pages/master/provider/blocks/ListToolbar.tsx index 6915202..7960b83 100644 --- a/src/pages/master/provider/blocks/ListToolbar.tsx +++ b/src/pages/master/provider/blocks/ListToolbar.tsx @@ -1,10 +1,23 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManageProviderContext } from '../hooks/useManageProviderContext'; import { Button } from '@/components/ui/button'; +import { useEffect, useState } from 'react'; const ListToolbar = () => { const { reload, table } = useDataGrid(); const { handleAddDialog } = useManageProviderContext(); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); + + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); return (
@@ -15,24 +28,11 @@ const ListToolbar = () => { - table.getColumn('name')?.setFilterValue(event.target.value) - } + placeholder="Search" + value={searchValue} + onChange={(event) => setSearchValue(event.target.value)} /> - {/* - - */}
- -
+

Loading Reward Details...

- + ) : ( +
+
+
+ + + setFormField((prev) => ({ ...prev, name: e.target.value }))} + /> +
+
+ + +
+ +
+
+
+ + + { + setFormField((prev) => ({ + ...prev, + amount: values.floatValue || 0 + })); + }} + placeholder="Enter Amount" + /> +
+
+ + +
+ +
+
+
+ + +
+
+
+ )}
diff --git a/src/pages/master/reward/blocks/ListToolbar.tsx b/src/pages/master/reward/blocks/ListToolbar.tsx index 5c85468..665245f 100644 --- a/src/pages/master/reward/blocks/ListToolbar.tsx +++ b/src/pages/master/reward/blocks/ListToolbar.tsx @@ -1,10 +1,23 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; import { useManageRewardContext } from '../hooks/useManageRewardContext'; +import { useEffect, useState } from 'react'; const ListToolbar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog } = useManageRewardContext(); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); + + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); return (
@@ -15,9 +28,9 @@ const ListToolbar = () => { table.getColumn('name')?.setFilterValue(event.target.value)} + placeholder="Search" + value={searchValue} + onChange={(event) => setSearchValue(event.target.value)} />
diff --git a/src/pages/master/reward/hooks/ManageRewardContext.tsx b/src/pages/master/reward/hooks/ManageRewardContext.tsx index 32b8116..1d4d2f3 100644 --- a/src/pages/master/reward/hooks/ManageRewardContext.tsx +++ b/src/pages/master/reward/hooks/ManageRewardContext.tsx @@ -110,7 +110,8 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode } ); }, meta: { - headerClassName: 'w-[250px]' + headerClassName: 'w-[250px] text-center', + cellClassName: 'text-center' } }, { @@ -138,7 +139,7 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode } ); }, meta: { - heaaderClassName: 'w-[100px]', + headerClassName: 'w-[100px] text-center', cellClassName: 'text-center' } } diff --git a/src/pages/master/sucos/SucosMaster.tsx b/src/pages/master/sucos/SucosMaster.tsx index 46c3215..77f0815 100644 --- a/src/pages/master/sucos/SucosMaster.tsx +++ b/src/pages/master/sucos/SucosMaster.tsx @@ -3,7 +3,6 @@ import { ManageSucosContextProvider } from './hooks/ManageSucosContext'; import AddDialog from './blocks/AddDialog'; import EditDialog from './blocks/EditDialog'; import DeleteDialog from './blocks/DeleteDialog'; -import SearchDialog from './blocks/SearchDialog'; import { Breadcrumbs, Link } from '@mui/material'; import { Helmet } from 'react-helmet'; @@ -37,7 +36,6 @@ const SucosMaster = () => { - diff --git a/src/pages/master/sucos/blocks/EditDialog.tsx b/src/pages/master/sucos/blocks/EditDialog.tsx index 4dbd307..d6d6933 100644 --- a/src/pages/master/sucos/blocks/EditDialog.tsx +++ b/src/pages/master/sucos/blocks/EditDialog.tsx @@ -34,12 +34,12 @@ interface PostoAdmsProps { const API_URL = apiConfig.service_master_data; const EditDialog = () => { - const parentRef = useRef(null); const { showEditDialog, handleEditDialog, selectedSucos, sucos } = useManageSucosContext(); const { reload } = useDataGrid(); const { PutData, GetData } = useCallApi(); const parsedUser = getAuth()?.user; const [open, setOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); const [postoadms, setPostoadms] = useState([]); const [alert, setAlert] = useState({ @@ -112,7 +112,10 @@ const EditDialog = () => { }, []); const doFetchData = useCallback(async (id: string) => { - const response = await GetData(`${API_URL}/sucos/getdata/${id}`, { id }); + setIsLoading(true); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/sucos/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); // console.log('Data Sucos:', response?.data); if (response?.status) { @@ -127,6 +130,7 @@ const EditDialog = () => { name: '' })); } + setIsLoading(false); }, []); const handleUpdate = (e: React.FormEvent) => { @@ -183,72 +187,87 @@ const EditDialog = () => { )} -
-
-
-
- - setFormField({ ...formField, name: e.target.value })} - /> + {isLoading ? ( +
+
+
+
+
+
+
+
- -
-
- - - - - - - - - - No Postu Administrativo Found. - - {postoadms.map((posto) => ( - { - setFormField({ - ...formField, - postoId: posto.PostoAdms_id - }); - setOpen(false); - }} - > - {posto.PostoAdms_name} - - ))} - - - - - -
-
- -
- - -
+

Loading Sucos Details...

- + ) : ( +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + /> +
+
+ +
+
+ + + + + + + + + + No Postu Administrativo Found. + + {postoadms.map((posto) => ( + { + setFormField({ + ...formField, + postoId: posto.PostoAdms_id + }); + setOpen(false); + }} + > + {posto.PostoAdms_name} + + ))} + + + + + +
+
+ +
+ + +
+
+
+ )}
diff --git a/src/pages/master/sucos/blocks/ListToolbar.tsx b/src/pages/master/sucos/blocks/ListToolbar.tsx index 75e52e4..0ed4cab 100644 --- a/src/pages/master/sucos/blocks/ListToolbar.tsx +++ b/src/pages/master/sucos/blocks/ListToolbar.tsx @@ -1,12 +1,14 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; import { useManageSucosContext } from '../hooks/useManageSucosContext'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; const ListToolbar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog, handleSearchDialog } = useManageSucosContext(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState( + (table.getColumn('sucos_name')?.getFilterValue() as string) ?? '' + ); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { @@ -19,6 +21,15 @@ const ListToolbar = () => { table.setPageIndex(0); }; + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('sucos_name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -31,32 +42,13 @@ const ListToolbar = () => { placeholder="Search Sucos" value={searchValue} onChange={(event) => setSearchValue(event.target.value)} - onKeyDown={handleKeyDown} /> - + {/* - - {/* - */} - {/* */}
- - - - - - No PostoAdms found. - - {sucos.map((suco) => ( - { - setFormField({ - id: suco.sucos_id, - name: suco.sucos_name - }); - setOpen(false); - }} - > - {suco.sucos_name} - - ))} - - - - - -
- - {isFound && sucos.length > 0 && ( -
-

Aldeias:

-
- - {aldeia.map((aldeias) => aldeias.name).join(', ')} - -
-
- )} - -
- - -
- - - - - ); -}; - -export default SearchDialog; diff --git a/src/pages/master/sucos/hooks/ManageSucosContext.tsx b/src/pages/master/sucos/hooks/ManageSucosContext.tsx index c77539a..605a2a9 100644 --- a/src/pages/master/sucos/hooks/ManageSucosContext.tsx +++ b/src/pages/master/sucos/hooks/ManageSucosContext.tsx @@ -9,9 +9,12 @@ import { useNavigate } from 'react-router'; import axios from 'axios'; interface SucosProps { - sucos_id: number; - sucos_name: string; - posto_name: string; + id: string; + name: string; + posto: { + id: string; + name: string; + }; } interface ContextProps { @@ -106,7 +109,9 @@ const ManageSucosContextProvider = ({ children }: { children: React.ReactNode }) const value = row.getValue(columnId); return String(value).includes(String(filterValue)); }, - header: ({ column }) => , + header: ({ column }) => ( + + ), enableSorting: true, enableHiding: false, meta: { @@ -124,13 +129,13 @@ const ManageSucosContextProvider = ({ children }: { children: React.ReactNode }) <> @@ -138,7 +143,7 @@ const ManageSucosContextProvider = ({ children }: { children: React.ReactNode }) ); }, meta: { - headerClassName: 'w-[100px]', + headerClassName: 'w-[100px] text-center', cellClassName: 'text-center' } } @@ -158,7 +163,6 @@ const ManageSucosContextProvider = ({ children }: { children: React.ReactNode }) order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', filter: JSON.stringify(filter) }); - // console.log('Sucos List Response:', response?.data); setSucos(response?.data.list || []); return { data: response?.data.list, totalCount: response?.data.total_count }; } catch (error) { diff --git a/src/pages/master/wallet/blocks/EditDialog.tsx b/src/pages/master/wallet/blocks/EditDialog.tsx index d8ff501..ffcc1e5 100644 --- a/src/pages/master/wallet/blocks/EditDialog.tsx +++ b/src/pages/master/wallet/blocks/EditDialog.tsx @@ -45,6 +45,7 @@ const EditDialog = () => { const { showEditDialog, handleEditDialog, selectedWallet } = useManageWalletContext(); const { reload } = useDataGrid(); const { GetData, PutData } = useCallApi(); + const [isLoading, setIsLoading] = useState(false); const [alert, setAlert] = useState({ show: false, message: '' @@ -115,11 +116,13 @@ const EditDialog = () => { }; const doFetchData = useCallback(async (id: string) => { - const response = await GetData(`${API_URL_MASTER_DATA}/wallet/detail/${id}`, { + setIsLoading(true); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL_MASTER_DATA}/wallet/detail/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); - console.log(response); if (response?.status) { setFormField((prev) => ({ ...prev, @@ -132,6 +135,7 @@ const EditDialog = () => { : [] })); } + setIsLoading(false); }, []); const getCurrencyLists = async (sorting: any) => { @@ -213,91 +217,110 @@ const EditDialog = () => { )} -
-
-
-
- - setFormField({ ...formField, name: e.target.value })} - placeholder="Wallet Name" - /> -
-
- -
-
- - setFormField({ ...formField, description: e.target.value })} - placeholder="Description" - /> -
-
- -
-
- - -
-
- -
-
- -
- + {isLoading ? ( +
+
+
+
+
+
+
- -
-
- -
- -
-
-
- -
- -
+

Loading Wallet Details...

- + ) : ( +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + placeholder="Wallet Name" + /> +
+
+ +
+
+ + + setFormField({ ...formField, description: e.target.value }) + } + placeholder="Description" + /> +
+
+ +
+
+ + +
+
+ +
+
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ )}
diff --git a/src/pages/master/wallet/blocks/ListToolbar.tsx b/src/pages/master/wallet/blocks/ListToolbar.tsx index 1e38aa5..ee39e30 100644 --- a/src/pages/master/wallet/blocks/ListToolbar.tsx +++ b/src/pages/master/wallet/blocks/ListToolbar.tsx @@ -1,12 +1,14 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; import { useManageWalletContext } from '../hooks/useManageWalletContext'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; const ListToolbar = () => { const { reload, table } = useDataGrid(); const { handleAddDialog } = useManageWalletContext(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState( + (table.getColumn('wallets.name')?.getFilterValue() as string) ?? '' + ); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { @@ -19,6 +21,15 @@ const ListToolbar = () => { table.setPageIndex(0); }; + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('wallets.name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -31,24 +42,12 @@ const ListToolbar = () => { placeholder="Search Wallet" value={searchValue} onChange={(event) => setSearchValue(event.target.value)} - onKeyDown={handleKeyDown} /> - + {/* - - {/* - */}
diff --git a/src/pages/menu/manage-menu/blocks/ListToolbar.tsx b/src/pages/menu/manage-menu/blocks/ListToolbar.tsx index 0820e05..91425b8 100644 --- a/src/pages/menu/manage-menu/blocks/ListToolbar.tsx +++ b/src/pages/menu/manage-menu/blocks/ListToolbar.tsx @@ -1,12 +1,14 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManageMenusContext } from '../hooks/useManageMenusContext'; import { Button } from '@/components/ui/button'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; const ListToolbar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog } = useManageMenusContext(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { @@ -18,6 +20,15 @@ const ListToolbar = () => { table.getColumn('name')?.setFilterValue(searchValue); }; + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -30,25 +41,12 @@ const ListToolbar = () => { placeholder="Search Menu" value={searchValue} onChange={(event) => setSearchValue(event.target.value)} - onKeyDown={handleKeyDown} /> - + {/* - - {/* - */}
diff --git a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx index 779e189..8968cd2 100644 --- a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx @@ -17,7 +17,6 @@ import { SelectTrigger, SelectValue, } from '@/components/ui/select'; -import { Alert, useDataGrid } from '@/components'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { toast } from 'sonner'; import { Input } from '@/components/ui/input'; @@ -59,15 +58,24 @@ const ApprovalDialog = () => { toast.error('Please select a status.'); return; } + const response = await PostData(`${API_URL}/transaction/set-approval`, { id_transaction: transactionDetails.id, status: formField.status, notes: formField.notes, }); + if (response?.status === false) { + setAlert({ + show: true, + message: response?.message?.error?.message || 'Approval failed', + }); + return; + } + if (response?.status) { setAlert({ show: false, message: '' }); - toast.success('Success Update Position'); + toast.success('Success Update Approval'); const createActivity = { module: 'Approval Transaction', description: `Change status approve for transaction => ${transactionDetails.code}`, @@ -84,13 +92,13 @@ const ApprovalDialog = () => { useEffect(() => { if (showApprovalDialog) { - // Reset form fields when dialog opens setFormField({ transaction_code: '', status: '', notes: '', }); - setTransactionDetails(null); // Optional reset + setTransactionDetails(null); + setAlert({ show: false, message: '' }); } }, [showApprovalDialog]); @@ -116,7 +124,6 @@ const ApprovalDialog = () => { } }, [showApprovalDialog, selectedTransactionIdForApproval, GetData]); - // Set formField.transaction_code once details are fetched useEffect(() => { if (transactionDetails) { setFormField((prev) => ({ @@ -138,7 +145,6 @@ const ApprovalDialog = () => {
-