From 14949a47f9d57a80b1b37d6537e1610effa8f6de Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Thu, 15 Feb 2024 10:43:32 +0700 Subject: [PATCH] tambah pagination dan search daily monitoring --- .../Api/DailyMonitoringController.php | 28 +- .../Transformers/DailyMonitoringResource.php | 29 ++ .../DailyMonitoring/Components/ClaimList.tsx | 249 +++++++++++++++--- .../Components/DailyMonitoringList.tsx | 243 +++++++++++++---- .../Components/DailyMonitoringListRow.tsx | 4 +- .../DailyMonitoring/Model/Functions.ts | 6 +- .../DailyMonitoring/Model/Types.ts | 4 +- 7 files changed, 455 insertions(+), 108 deletions(-) create mode 100644 Modules/Internal/Transformers/DailyMonitoringResource.php diff --git a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php index 67a49953..dcb25af4 100644 --- a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php +++ b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php @@ -1,7 +1,7 @@ leftJoin('members', 'request_logs.member_id', '=', 'members.id') @@ -45,18 +47,18 @@ class DailyMonitoringController extends Controller ->select('members.member_id','members.name','members.members_effective_date AS startdate','members.members_expire_date AS enddate', 'request_logs.submission_date as addmision_date', 'organizations.name as provider' ) ->where('request_logs.service_code', 'IP') ->where('request_logs.deleted_at', null) + ->when($request->search, function ($q, $search) { + $q->where('members.member_id', 'LIKE', "%".$search."%"); + $q->orWhere('members.name','LIKE',"%".$search."%"); + }) // ->where('request_logs.status_final_log', 'approved') ->groupBy('request_logs.member_id') ->orderBy('request_logs.created_at', 'desc') - ->get(); + // ->get() + ->paginate(); - return response()->json([ - 'error' => false, - 'message' => "success", - 'data' => [ - 'member_list'=> $memberList, - ] - ],200); + + return Helper::paginateResources(DailyMonitoringResource::collection($memberList)); } /** @@ -76,8 +78,12 @@ class DailyMonitoringController extends Controller ->where('request_logs.service_code', 'IP') ->where('request_logs.status_final_log', 'approved') ->where("request_logs.member_id", "=", $memberDetail->id) + ->when($request->search, function ($q, $search) { + $q->where('request_logs.code', 'LIKE', "%".$search."%"); + }) ->orderBy("request_logs.created_at", "desc") - ->get(); + // ->get() + ->paginate(); return response()->json([ 'error' => false, diff --git a/Modules/Internal/Transformers/DailyMonitoringResource.php b/Modules/Internal/Transformers/DailyMonitoringResource.php new file mode 100644 index 00000000..af6fd8ae --- /dev/null +++ b/Modules/Internal/Transformers/DailyMonitoringResource.php @@ -0,0 +1,29 @@ + $this->member_id, + 'name' => $this->name, + 'start_date' => $this->startdate, + 'end_date' => $this->enddate, + 'addmision_date' => $this->addmision_date, + 'provider' => $this->provider, + ]; + + return $data; + } +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx index b9363926..cd52ce87 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx @@ -2,7 +2,7 @@ * Core * ============================================ */ -import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from "@mui/material"; +import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Grid, Stack } from "@mui/material"; /** * Component @@ -15,65 +15,232 @@ import ClaimListRow from "./ClaimListRow"; * ============================================ */ import { ClaimListType } from "../Model/Types"; +import React, { ChangeEvent, useEffect, useRef, useState } from "react"; +import axios from "@/utils/axios"; +import { enqueueSnackbar } from "notistack"; +import { Button } from "@mui/material"; +import DataTable from '../../../../components/LaravelTable'; +import { LaravelPaginatedData, LaravelPaginatedDataDefault } from "@/@types/paginated-data"; +import { useParams, useSearchParams } from "react-router-dom"; +import { TextField } from "@mui/material"; +import { ButtonGroup } from "@mui/material"; type Props = { claim_list: ClaimListType[] | null, } export default function ClaimList({ ...props }: Props) { + const [searchParams, setSearchParams] = useSearchParams(); + const { member_id } = useParams(); + // State + // -------------------- + const [dataTableIsLoading, setDataTableLoading] = useState(true); + const [dataTableData, setDataTableData] = useState( + LaravelPaginatedDataDefault + ); // Tabel Style // -------------------- const TableHeadStyle = { fontWeight: 'bold', }; - return ( - - - - {/* Head Table */} - - - - Admission Date - Discharge Date - Code - Service Type - Status - - - + // Load Data + // ------------------- + const loadDataTableData = async (appliedFilter: any | null = null) => { + setDataTableLoading(true); + const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); + + const response = await axios.get('/case_management/claimlist/'+member_id, {params: filter}) + setDataTableLoading(false); + setDataTableData(response.data); + } - {/* Body Table */} - {props.claim_list == null ? + const applyFilter = async (searchFilter: { search: string }) => { + await loadDataTableData(searchFilter); + setSearchParams(searchFilter); + }; + + const handlePageChange = (event: ChangeEvent, value: number): void => { + const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]); + + loadDataTableData(filter); + setSearchParams(filter); + }; + + useEffect(() => { + loadDataTableData(); + }, []) + + function SearchInput(props: any) { + // SEARCH + const searchInput = useRef(null); + const [searchText, setSearchText] = useState(''); + + const handleSearchChange = (event: any) => { + const newSearchText = event.target.value ?? ''; + setSearchText(newSearchText); + }; + + const handleSearchSubmit = (event: any) => { + event.preventDefault(); + props.onSearch({ search: searchText }); // Trigger to Parent + }; + + useEffect(() => { + // Trigger First Search + setSearchText(searchParams.get('search') ?? ''); + }, []); + + return ( +
+ + + ); + } + + function ImportForm(props: any) { + // IMPORT + // Create Button Menu + const [anchorEl, setAnchorEl] = React.useState(null); + const createMenu = Boolean(anchorEl); + const importForm = useRef(null); + const [currentImportFileName, setCurrentImportFileName] = useState(null); + const [importLoading, setImportLoading] = useState(false); + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const handleImportButton = () => { + if (importForm?.current) { + handleClose(); + importForm.current ? importForm.current.click() : console.log('No File selected'); + } else { + alert('No file selected'); + } + }; + + const handleCancelImportButton = () => { + + }; + + const handleImportChange = (event: any) => { + if (event.target.files[0]) { + setCurrentImportFileName(event.target.files[0].name); + } else { + setCurrentImportFileName(null); + } + }; + + const handleUpload = () => { + + }; + + const handleGetTemplate = (type :string) => { + + } + + const handleGetData = (type :string) => { + + } + + return ( +
+ {!currentImportFileName && ( + + + {/* */} + + )} +
+ ); + } + + + function TableContent() { + return ( +
+ {/* Head Table */} + + + + Admission Date + Discharge Date + Code + Service Type + Status + + + + + {/* Body Table */} + {dataTableData.data.claim_list == null ? + ( + + + Loading + + + ) + : + ( + dataTableData.data.claim_list.data.length == 0 ? ( - Loading + No Data ) : ( - props.claim_list.length == 0 ? - ( - - - No Data - - - ) - : - ( - - {props.claim_list.map((row: ClaimListType, index) => ( - - ))} - - ) - )} -
-
-
- ) + + {dataTableData.data.claim_list.data.map((row: ClaimListType, index) => ( + + ))} + + ) + )} + + ) + } + + return ( + + + + + + + } + /> + + + ); } diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx index 60c152cb..bd0fbfa4 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx @@ -2,8 +2,8 @@ * Core * ============================================ */ -import { useEffect, useState } from "react"; -import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from "@mui/material"; +import React, { ChangeEvent, useEffect, useRef, useState } from "react"; +import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Stack, TextField, Button, Menu, } from "@mui/material"; /** * Types & Functions @@ -12,12 +12,21 @@ import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, Tabl import { getDailyMonitoringList } from "../Model/Functions"; import { DailyMonitoringListType } from "../Model/Types"; import DailyMonitoringListRow from "./DailyMonitoringListRow"; +import { LaravelPaginatedData, LaravelPaginatedDataDefault } from "@/@types/paginated-data"; +import { Grid } from "@mui/material"; +import DataTable from '../../../../components/LaravelTable'; +import { MenuItem } from "@mui/material"; +import { useSearchParams } from "react-router-dom"; +import axios from "@/utils/axios"; export default function DailyMonitoringList() { + const [searchParams, setSearchParams] = useSearchParams(); // State // -------------------- const [dataTableIsLoading, setDataTableLoading] = useState(true); - const [dataTableData, setDataTableData] = useState([]); + const [dataTableData, setDataTableData] = useState( + LaravelPaginatedDataDefault + ); // Tabel Style // -------------------- @@ -25,69 +34,205 @@ export default function DailyMonitoringList() { fontWeight: 'bold', }; + + // Load Data // ------------------- - const loadDataTableData = async () => { + const loadDataTableData = async (appliedFilter: any | null = null) => { setDataTableLoading(true); - - const response = await getDailyMonitoringList(); - + const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); + + const response = await axios.get('/case_management/memberlist', {params: filter}) setDataTableLoading(false); - setDataTableData(response); + setDataTableData(response.data); } + const applyFilter = async (searchFilter: { search: string }) => { + await loadDataTableData(searchFilter); + setSearchParams(searchFilter); + }; + + const handlePageChange = (event: ChangeEvent, value: number): void => { + const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]); + loadDataTableData(filter); + setSearchParams(filter); + }; + useEffect(() => { loadDataTableData(); }, []) - return ( - - - - {/* Head Table */} - - - - Member ID - Name - Start Date - End Date - Admission Date - Provider - - - + function SearchInput(props: any) { + // SEARCH + const searchInput = useRef(null); + const [searchText, setSearchText] = useState(''); + + const handleSearchChange = (event: any) => { + const newSearchText = event.target.value ?? ''; + setSearchText(newSearchText); + }; + + const handleSearchSubmit = (event: any) => { + event.preventDefault(); + props.onSearch({ search: searchText }); // Trigger to Parent + }; + + useEffect(() => { + // Trigger First Search + setSearchText(searchParams.get('search') ?? ''); + }, []); + + return ( +
+ + + ); + } - {/* Body Table */} - {dataTableIsLoading ? + function ImportForm(props: any) { + // IMPORT + // Create Button Menu + const [anchorEl, setAnchorEl] = React.useState(null); + const createMenu = Boolean(anchorEl); + const importForm = useRef(null); + const [currentImportFileName, setCurrentImportFileName] = useState(null); + const [importLoading, setImportLoading] = useState(false); + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const handleImportButton = () => { + if (importForm?.current) { + handleClose(); + importForm.current ? importForm.current.click() : console.log('No File selected'); + } else { + alert('No file selected'); + } + }; + + const handleCancelImportButton = () => { + + }; + + const handleImportChange = (event: any) => { + if (event.target.files[0]) { + setCurrentImportFileName(event.target.files[0].name); + } else { + setCurrentImportFileName(null); + } + }; + + const handleUpload = () => { + + }; + + const handleGetTemplate = (type :string) => { + + } + + const handleGetData = (type :string) => { + + } + + return ( +
+ {!currentImportFileName && ( + + + {/* */} + + )} +
+ ); + } + + function TableContent(){ + return ( +
+ {/* Head Table */} + + + + Member ID + Name + Start Date + End Date + Admission Date + Provider + + + + + {/* Body Table */} + {dataTableIsLoading ? + ( + + + Loading + + + ) + : + ( + dataTableData.data.length == 0 ? ( - Loading + No Data ) : ( - dataTableData.length == 0 ? - ( - - - No Data - - - ) - : - ( - - {dataTableData.map((row: DailyMonitoringListType, index) => ( - - ))} - - ) - )} -
-
-
- ) + + {dataTableData.data.map((row: DailyMonitoringListType, index) => ( + + ))} + + ) + )} + + ) + } + + return ( + + + + + + + } + /> + + + ); + } diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx index 2b6df13b..466499cb 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx @@ -42,7 +42,7 @@ export default function DailyMonitoringListRow ({ ...props }: Props) { variant="ghost" color="default" > - {fDate(props.row.startdate)} + {fDate(props.row.start_date)} @@ -50,7 +50,7 @@ export default function DailyMonitoringListRow ({ ...props }: Props) { variant="ghost" color="default" > - {fDate(props.row.enddate)} + {fDate(props.row.end_date)} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts index 74367218..ffbe3be3 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts @@ -7,10 +7,10 @@ import { fDate, fDateOnly } from '@/utils/formatTime'; /** * Listing Daily Monitoring */ -export const getDailyMonitoringList = async ( ): Promise => { - const response = await axios.get('/case_management/memberlist') +export const getDailyMonitoringList = async ( param: any) => { + const response = await axios.get('/case_management/memberlist', {params: param}) .then((res) =>{ - return res.data.data.member_list; + return res.data; }) .catch((res) => { enqueueSnackbar("server error !", { diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts index fa2b800d..8a39ff5c 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts @@ -4,8 +4,8 @@ export type DailyMonitoringListType = { member_id : string, name : string, - startdate : string, - enddate : string, + start_date : string, + end_date : string, addmision_date : string, provider : string }