diff --git a/src/pages/master/sucos/SucosMaster.tsx b/src/pages/master/sucos/SucosMaster.tsx
index 6feede3..62911a4 100644
--- a/src/pages/master/sucos/SucosMaster.tsx
+++ b/src/pages/master/sucos/SucosMaster.tsx
@@ -1,10 +1,20 @@
+import { Container, DataGridInner } from '@/components';
+import { ManageSucosContextProvider } from './hooks/ManageSucosContext';
+import AddDialog from './blocks/AddDialog';
+import EditDialog from './blocks/EditDialog';
+
const SucosMaster = () => {
return (
-
-
-
Sucos Master Data
-
-
+
+
+ Sucos
+
+
+
+
+
+
+
);
};
diff --git a/src/pages/master/sucos/blocks/AddDialog.tsx b/src/pages/master/sucos/blocks/AddDialog.tsx
new file mode 100644
index 0000000..eed5cd9
--- /dev/null
+++ b/src/pages/master/sucos/blocks/AddDialog.tsx
@@ -0,0 +1,148 @@
+import React, { useCallback, useEffect, useRef, useState } from 'react';
+import { useManageSucosContext } from '../hooks/useManageSucosContext';
+import { Alert, useDataGrid } from '@/components';
+import { useCallApi } from '@/hooks';
+import { getAuth } from '@/auth';
+import { apiConfig } from '@/config/api.config';
+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';
+
+const API_URL = apiConfig.service_master_data;
+
+const AddDialog = () => {
+ const parentRef = useRef(null);
+ const { showAddDialog, handleAddDialog } = useManageSucosContext();
+ const { reload } = useDataGrid();
+ const { PostData } = useCallApi();
+ const parsedUser = getAuth()?.user;
+ const [alert, setAlert] = useState({
+ show: false,
+ message: ''
+ });
+ const initialState = {
+ name: '',
+ posto_adm_id: 0,
+ created_by: '',
+ created_at: ''
+ };
+ const [formField, setFormField] = useState(initialState);
+
+ const resetForm = () => {
+ setFormField(initialState);
+ setAlert({ show: false, message: '' });
+ };
+
+ const doCreateSucos = useCallback(async (e: React.FormEvent) => {
+ e.preventDefault();
+ const response = await PostData(`${API_URL}/sucos/create`, formField);
+
+ if (response?.status) {
+ resetForm();
+ handleAddDialog(false);
+ reload();
+ toast.success('Success Create Sucos');
+ } else {
+ toast.error('Failed Create Sucos');
+ setAlert({ show: true, message: response?.message });
+ }
+ }, []);
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+
+ if (formField.name === '' || formField.posto_adm_id === 0) {
+ setAlert({ show: true, message: 'Please fill in all required fields.' });
+ return;
+ }
+
+ // doCreateSucos(e);
+ console.log(formField);
+ setAlert({ show: false, message: '' });
+ };
+
+ useEffect(() => {
+ const created_time = new Date();
+ const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' ');
+ if (showAddDialog) {
+ setFormField({
+ ...formField,
+ created_by: parsedUser.username,
+ created_at: formattedTime
+ });
+ }
+ }, [showAddDialog]);
+
+ return (
+
+ );
+};
+
+export default AddDialog;
diff --git a/src/pages/master/sucos/blocks/DeleteDialog.tsx b/src/pages/master/sucos/blocks/DeleteDialog.tsx
new file mode 100644
index 0000000..d5aa4ce
--- /dev/null
+++ b/src/pages/master/sucos/blocks/DeleteDialog.tsx
@@ -0,0 +1,74 @@
+import { apiConfig } from '@/config/api.config';
+import { useManageSucosContext } from '../hooks/useManageSucosContext';
+import { ChangeEvent, useCallback, useState } from 'react';
+import { useCallApi } from '@/hooks';
+import { Alert, useDataGrid } from '@/components';
+import { toast } from 'sonner';
+import { Dialog, DialogContent, DialogFooter, DialogHeader } from '@/components/ui/dialog';
+import { EnforceSwitch } from '@/components/switch';
+import { Button } from '@/components/ui/button';
+
+const API_URL = apiConfig.service_master_data;
+
+const DeleteDialog = () => {
+ const { showDeleteDialog, handleDeleteDialog, selectedSucos } = useManageSucosContext();
+ const { reload } = useDataGrid();
+ const { DeleteData } = useCallApi();
+ const [enforce, setEnforce] = useState(false);
+ const [alert, setAlert] = useState({
+ show: false,
+ message: ''
+ });
+
+ const doDeleteSucos = useCallback(async () => {
+ const response = await DeleteData(`${API_URL}/sucos/delete/${selectedSucos}/${enforce}`, {
+ id: selectedSucos
+ });
+
+ if (response?.status) {
+ setAlert((prev) => ({ ...prev, show: false, message: '' }));
+ handleDeleteDialog(false, null);
+ toast.success('Success Delete Sucos');
+ reload();
+ } else {
+ setAlert((prev) => ({ ...prev, show: true, message: response?.message }));
+ }
+ }, [selectedSucos, enforce]);
+
+ return (
+
+ );
+};
+
+export default DeleteDialog;
diff --git a/src/pages/master/sucos/blocks/EditDialog.tsx b/src/pages/master/sucos/blocks/EditDialog.tsx
new file mode 100644
index 0000000..342c621
--- /dev/null
+++ b/src/pages/master/sucos/blocks/EditDialog.tsx
@@ -0,0 +1,152 @@
+import { Alert, useDataGrid } from '@/components';
+import { useManageSucosContext } from '../hooks/useManageSucosContext';
+import { useCallApi } from '@/hooks';
+import { getAuth } from '@/auth';
+import React, { useCallback, useEffect, useState } from 'react';
+import { apiConfig } from '@/config/api.config';
+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';
+
+const API_URL = apiConfig.service_master_data;
+
+const EditDialog = () => {
+ const { showEditDialog, handleEditDialog, selectedSucos } = useManageSucosContext();
+ const { reload } = useDataGrid();
+ const { PutData } = useCallApi();
+ const parsedUser = getAuth()?.user;
+ const [alert, setAlert] = useState({
+ show: false,
+ message: ''
+ });
+ const initialState = {
+ name: '',
+ posto_adm_id: 0,
+ updated_by: '',
+ updated_at: ''
+ };
+ const [formField, setFormField] = useState(initialState);
+
+ const resetForm = () => {
+ setFormField(initialState);
+ setAlert({
+ show: false,
+ message: ''
+ });
+ };
+
+ const doUpdateSucos = useCallback(
+ async (e: React.FormEvent) => {
+ e.preventDefault();
+
+ const response = await PutData(`${API_URL}/sucos/update/${selectedSucos}`, formField);
+
+ if (response?.status) {
+ resetForm();
+ handleEditDialog(false, null);
+ toast.success('Success Update Sucos');
+ reload();
+ } else {
+ toast.error('Failed Update Sucos');
+ setAlert({ show: true, message: 'Failed Update Sucos. Please try again' });
+ }
+ },
+ [selectedSucos, formField]
+ );
+
+ const handleUpdate = (e: React.FormEvent) => {
+ e.preventDefault();
+
+ if (formField.name === '' || formField.posto_adm_id === 0) {
+ setAlert({ show: true, message: 'Please fill in all required fields.' });
+ return;
+ }
+
+ // doUpdateSucos(e);
+ console.log(formField);
+ setAlert({ show: false, message: '' });
+ };
+
+ useEffect(() => {
+ const created_time = new Date();
+ const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' ');
+ if (showEditDialog) {
+ setFormField({
+ ...formField,
+ updated_by: parsedUser.username,
+ updated_at: formattedTime
+ });
+ }
+ }, [showEditDialog]);
+
+ return (
+
+ );
+};
+
+export default EditDialog;
diff --git a/src/pages/master/sucos/blocks/ListToolbar.tsx b/src/pages/master/sucos/blocks/ListToolbar.tsx
index e69de29..f0a23b8 100644
--- a/src/pages/master/sucos/blocks/ListToolbar.tsx
+++ b/src/pages/master/sucos/blocks/ListToolbar.tsx
@@ -0,0 +1,64 @@
+import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components';
+import { useManageSucosContext } from '../hooks/useManageSucosContext';
+import { Button } from '@/components/ui/button';
+
+const ListToolbar = () => {
+ const { table, reload } = useDataGrid();
+ const { handleAddDialog, handleSearchDialog } = useManageSucosContext();
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ListToolbar;
diff --git a/src/pages/master/sucos/hooks/ManageSucos.tsx b/src/pages/master/sucos/hooks/ManageSucos.tsx
deleted file mode 100644
index cf878fa..0000000
--- a/src/pages/master/sucos/hooks/ManageSucos.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import { apiConfig } from '@/config/api.config';
-import React, { createContext, useCallback, useState } from 'react';
-
-interface SucosProps {
- id: number;
- name: string;
-}
-
-interface ContextProps {
- sucos: SucosProps[];
- showSearchDialog: boolean;
- handleSearchDialog: (show: boolean) => void;
- showEditDialog: boolean;
- handleEditDialog: (show: boolean, selected_sucos: string | null) => void;
- showAddDialog: boolean;
- handleAddDialog: (show: boolean) => void;
- showDeleteDialog: boolean;
- handleDeleteDialog: (show: boolean, selected_sucos: string | null) => void;
- selectedSucos: string | null;
- getSucosLists: (
- limit: number,
- page: number,
- with_deleted: boolean,
- order_field: any,
- order_direction: any
- ) => Promise<{ data: SucosProps[]; totalCount: number } | undefined>;
-}
-
-const initialProps: ContextProps = {
- sucos: [],
- showSearchDialog: false,
- handleSearchDialog: () => {},
- showEditDialog: false,
- handleEditDialog: () => {},
- showAddDialog: false,
- handleAddDialog: () => {},
- showDeleteDialog: false,
- handleDeleteDialog: () => {},
- selectedSucos: null,
- getSucosLists: async () => undefined
-};
-
-const ManageSucosContext = createContext(initialProps);
-const API_URL = apiConfig.service_master_data;
-
-const ManageSucosContextProvider = ({ children }: { children: React.ReactNode }) => {
- const [sucos, setSucos] = useState([]);
- const [showSearchDialog, setShowSearchDialog] = useState(false);
- const [showEditDialog, setShowEditDialog] = useState(false);
- const [showAddDialog, setShowAddDialog] = useState(false);
- const [showDeleteDialog, setShowDeleteDialog] = useState(false);
- const [selectedSucos, setSelectedSucos] = useState(null);
-
- const handleSearchDialog = useCallback((show: boolean) => {
- setShowSearchDialog(show);
- }, []);
-
- const handleAddDialog = useCallback((show: boolean) => {
- setShowAddDialog(show);
- }, []);
-
- const hanldeEditDialog = useCallback((show: boolean, selected_sucos: string | null) => {
- setSelectedSucos(show ? selected_sucos : null);
- setShowEditDialog(show);
- }, [])
-};
diff --git a/src/pages/master/sucos/hooks/ManageSucosContext.tsx b/src/pages/master/sucos/hooks/ManageSucosContext.tsx
new file mode 100644
index 0000000..4e8628b
--- /dev/null
+++ b/src/pages/master/sucos/hooks/ManageSucosContext.tsx
@@ -0,0 +1,200 @@
+import { DataGridColumnHeader, DataGridProvider, KeenIcon } from '@/components';
+import { Toaster } from '@/components/ui/sonner';
+import { apiConfig } from '@/config/api.config';
+import { useCallApi } from '@/hooks';
+import { ColumnDef } from '@tanstack/react-table';
+import React, { createContext, useCallback, useMemo, useState } from 'react';
+import ListToolbar from '../blocks/ListToolbar';
+
+interface SucosProps {
+ id: number;
+ name: string;
+}
+
+interface ContextProps {
+ sucos: SucosProps[];
+ showSearchDialog: boolean;
+ handleSearchDialog: (show: boolean) => void;
+ showEditDialog: boolean;
+ handleEditDialog: (show: boolean, selected_sucos: string | null) => void;
+ showAddDialog: boolean;
+ handleAddDialog: (show: boolean) => void;
+ showDeleteDialog: boolean;
+ handleDeleteDialog: (show: boolean, selected_sucos: string | null) => void;
+ selectedSucos: string | null;
+ getSucosLists: (
+ limit: number,
+ page: number,
+ with_deleted: boolean,
+ order_field: any,
+ order_direction: any
+ ) => Promise<{ data: SucosProps[]; totalCount: number } | undefined>;
+}
+
+const initialProps: ContextProps = {
+ sucos: [],
+ showSearchDialog: false,
+ handleSearchDialog: () => {},
+ showEditDialog: false,
+ handleEditDialog: () => {},
+ showAddDialog: false,
+ handleAddDialog: () => {},
+ showDeleteDialog: false,
+ handleDeleteDialog: () => {},
+ selectedSucos: null,
+ getSucosLists: async () => undefined
+};
+
+const ManageSucosContext = createContext(initialProps);
+const API_URL = apiConfig.service_master_data;
+
+const ManageSucosContextProvider = ({ children }: { children: React.ReactNode }) => {
+ const [sucos, setSucos] = useState([]);
+ const [showSearchDialog, setShowSearchDialog] = useState(false);
+ const [showEditDialog, setShowEditDialog] = useState(false);
+ const [showAddDialog, setShowAddDialog] = useState(false);
+ const [showDeleteDialog, setShowDeleteDialog] = useState(false);
+ const [selectedSucos, setSelectedSucos] = useState(null);
+ const { GetData } = useCallApi();
+
+ const handleSearchDialog = useCallback((show: boolean) => {
+ setShowSearchDialog(show);
+ }, []);
+
+ const handleAddDialog = useCallback((show: boolean) => {
+ setShowAddDialog(show);
+ }, []);
+
+ const handleEditDialog = useCallback((show: boolean, selected_sucos: string | null) => {
+ setSelectedSucos(show ? selected_sucos : null);
+ setShowEditDialog(show);
+ }, []);
+
+ const handleDeleteDialog = useCallback((show: boolean, selected_sucos: string | null) => {
+ setSelectedSucos(show ? selected_sucos : null);
+ setShowDeleteDialog(show);
+ }, []);
+
+ const columns = useMemo[]>(
+ () => [
+ {
+ accessorFn: (row) => row.sucos_id,
+ id: 'id',
+ header: ({ column }) => ,
+ enableSorting: true,
+ enableHiding: false,
+ meta: {
+ headerClassName: 'w-[100px]'
+ }
+ },
+ {
+ accessorFn: (row) => row.sucos_name,
+ id: 'sucos_name',
+ header: ({ column }) => ,
+ enableSorting: true,
+ enableHiding: false,
+ meta: {
+ headerClassName: 'w-[250px]'
+ }
+ },
+ {
+ accessorFn: (row) => row.posto_name,
+ id: 'posto_name',
+ header: ({ column }) => ,
+ enableSorting: true,
+ enableHiding: false,
+ meta: {
+ headerClassName: 'w-[250px]'
+ }
+ },
+ {
+ id: 'actions',
+ header: ({ column }) => ,
+ enableSorting: false,
+ enableHiding: false,
+ cell: (data) => {
+ const row = data.row.original;
+ return (
+ <>
+
+
+ >
+ );
+ },
+ meta: {
+ headerClassName: 'w-[100px]',
+ cellClassName: 'text-center'
+ }
+ }
+ ],
+ [handleEditDialog, handleDeleteDialog]
+ );
+
+ const getSucosLists = async (page: number, limit: number, sorting: any, filter: any) => {
+ try {
+ sorting: sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting;
+ filter = filter.length == 0 ? {} : { any: filter[0].value?.toLowerCase() };
+ const response = await GetData(`${API_URL}/sucos/list`, {
+ limit,
+ page: page + 1,
+ with_deleted: true,
+ order_field: sorting[0].id,
+ order_direction: sorting[0].desc == false ? 'ASC' : 'DESC',
+ filter: JSON.stringify(filter)
+ });
+ console.log(response?.data);
+ setSucos(response?.data.list);
+ // console.log(sucos);
+ return { data: response?.data.list, totalCount: response?.data.total_count };
+ } catch (error) {
+ console.error('Error fetching Sucos', error);
+ }
+ };
+
+ return (
+
+
+
+ }
+ layout={{ card: true }}
+ sorting={[{ id: 'id', desc: false }]}
+ serverSide={true}
+ onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) =>
+ getSucosLists(pageIndex, pageSize, sorting, columnFilters)
+ }
+ >
+ {children}
+
+
+ );
+};
+
+export { ManageSucosContextProvider, ManageSucosContext };
+export type { SucosProps };
diff --git a/src/pages/master/sucos/hooks/useManageSucosContext.tsx b/src/pages/master/sucos/hooks/useManageSucosContext.tsx
new file mode 100644
index 0000000..194575a
--- /dev/null
+++ b/src/pages/master/sucos/hooks/useManageSucosContext.tsx
@@ -0,0 +1,12 @@
+import { useContext } from 'react';
+import { ManageSucosContext } from './ManageSucosContext';
+
+const useManageSucosContext = () => {
+ const context = useContext(ManageSucosContext);
+
+ if (!context) throw new Error('useManageSucosContext must be used within AuthProvider');
+
+ return context;
+};
+
+export { useManageSucosContext };