/* ---------------------------------- @mui ---------------------------------- */ import { styled } from '@mui/material/styles'; import { Paper, Table as TableContent, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Button, TableSortLabel, Box, Card, Checkbox, Grid, FormControl, InputLabel, Select, MenuItem, SelectChangeEvent, Stack, Typography, LinearProgress, linearProgressClasses, Collapse, Divider, IconButton, Modal, CircularProgress } from '@mui/material'; import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'; import { visuallyHidden } from '@mui/utils'; import { DatePicker, LocalizationProvider, MobileDatePicker } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import { fDate, fDateSuffix, fDateTime, fDateTimeWithAge } from '../utils/formatTime'; /* ---------------------------------- axios --------------------------------- */ import axios from '../utils/axios'; /* ---------------------------------- react --------------------------------- */ import { Fragment, useContext, useEffect, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; /* -------------------------------- component ------------------------------- */ import BaseTablePagination from './BaseTablePagination'; /* ---------------------------------- theme --------------------------------- */ import palette from '../theme/palette'; /* ---------------------------------- utils --------------------------------- */ import { UserCurrentCorporateContext } from '../contexts/UserCurrentCorporate'; import { fSplit } from '../utils/formatNumber'; import { Download, Search as SearchIcon, Upload } from '@mui/icons-material'; /* ---------------------------------- types --------------------------------- */ import { DivisionDataProps, Order, PaginationTableProps, TableListProps } from '../@types/table'; import { InputAdornment } from '@mui/material'; import GetAppIcon from '@mui/icons-material/GetApp'; import { LanguageContext } from '@/contexts/LanguageContext'; import CancelIcon from '@mui/icons-material/Cancel'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import CloseIcon from '@mui/icons-material/Close'; import InfoIcon from '@mui/icons-material/Info'; import { enqueueSnackbar } from 'notistack'; import useAuth from '@/hooks/useAuth'; /* --------------------------------- styled --------------------------------- */ const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({ height: 10, borderRadius: 6, [`&.${linearProgressClasses.colorPrimary}`]: { backgroundColor: '#D1F1F1', }, [`& .${linearProgressClasses.bar}`]: { borderRadius: 6, backgroundColor: theme.palette.primary.main, }, })); /* -------------------------------------------------------------------------- */ export default function Table({ headCells, rows, paginations, orders, loadings, params, filters, filterStatus, filterStartDate, filterEndDate, searchs, exportReport, selected, openRowId, // Receive the currently opened row ID setOpenRowId, // Receive the function to set the opened row ID reloadData, }: TableListProps) { /* ------------------------------- handle sort ------------------------------ */ const handleRequestSort = async (event: React.MouseEvent, property: string) => { const isAsc = orders?.orderBy === property && orders?.order === 'asc'; orders?.setOrder(isAsc ? 'desc' : 'asc'); orders?.setOrderBy(property); const parameters = Object.fromEntries([ ...params.searchParams.entries(), ['order', isAsc ? 'desc' : 'asc'], ['orderBy', property], ]); params.setAppliedParams(parameters); }; const { localeData }: any = useContext(LanguageContext); /* -------------------------------------------------------------------------- */ /* -------------------------- enchanced table head -------------------------- */ const EnhancedTableHead = () => { const createSortHandler = (property: string) => (event: React.MouseEvent) => { handleRequestSort(event, property); }; return ( {selected.useSelected && selected.selectedRows.length > 0 ? ( <> {selected.selectedRows.length > 0 ? selected.selectedRows.length : '0'}   {localeData.txtSelected} {selected.useDecline ? ( ):''} ):( <> {selected.useSelected ? ( ):''} {headCells && headCells.map((headCell, index) => ( {headCell.isSort ? ( {headCell.label} {orders?.orderBy === headCell.id ? ( {orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'} ) : null} ) : ( headCell.label )} ))} )} ); }; /* -------------------------------------------------------------------------- */ /* ------------------------ button change pagination ------------------------ */ const onPageChangeHandle = async ( event: React.MouseEvent | null, newPage: number ) => { const parameters = Object.fromEntries([ ...params.searchParams.entries(), ['page', newPage + 1], ['per_page', paginations.rowsPerPage] ]); paginations.setPage(newPage); await new Promise((resolve) => setTimeout(resolve, 500)); params.setAppliedParams(parameters); }; /* -------------------------------------------------------------------------- */ /* --------------------------- row page per limit --------------------------- */ const onRowsPerPageChangeHandle = async (event: React.ChangeEvent) => { params.searchParams.delete('page'); const parameters = Object.fromEntries([ ...params.searchParams.entries(), ['per_page', parseInt(event.target.value, 10)], ]); paginations.setPage(0); paginations.setRowsPerPage(parseInt(event.target.value, 10)); await new Promise((resolve) => setTimeout(resolve, 500)); params.setAppliedParams(parameters); }; /* -------------------------------------------------------------------------- */ //============================== APOTEK =======================================// const {user} = useAuth(); const formattedRoleName = user?.role.name; // List of statuses for 'apotek' const allowedStatusesForApotek = ['waiting_pharmacy', 'order_prepared']; const allowedStatusesForCSLMS = ['ready', 'waiting_for_courir', 'package_picked_up', 'package_on_delivery']; const [open, setOpen] = useState(false); const [loading, setLoading] = useState(true); const handleClick = () => { // handleClickKonfirmasi(row); // Call the function passed from parent setOpen(true); // Show modal setLoading(true); // Show loading animation // Simulate finding driver (3 seconds delay) setTimeout(() => { setLoading(false); // Hide loading after 3 seconds }, 3000); }; const [openDialogStatus, setOpenDialogStatus] = useState(false); const [dialogIDRow, setDialogIDRow] = useState(null); const [dialogIDRowDriver, setDialogIDRowDriver] = useState(null); const [txtStatusDriver, setTxtStatusDriver] = useState(''); const [txtIDDriver, setTxtIDDriver] = useState(''); const handleClose = (row:any) => { setDialogIDRowDriver(row.id === dialogIDRowDriver ? null : row.id); if (reloadData) { reloadData(); } }; const handleCloseDialogUpdate = () => { setOpenDialogStatus(false); } const handleEditDataStatus = (data: any) => { setOpenDialogStatus(true); } const [isDisabled, setIsDisabled] = useState(false); const handleClickKonfirmasi = (row: any) => { setTxtStatusDriver(''); setTxtIDDriver(''); if(row.sStatus === 'ready') { //close setDialogIDRow(row.id === dialogIDRow ? null : row.id); //get driver setDialogIDRowDriver(row.id === dialogIDRowDriver ? null : row.id); // setOpen(true); // Show modal setLoading(true); // Show loading animation // Simulate finding driver (3 seconds delay) // setTimeout(() => { // setLoading(false); // Hide loading after 3 seconds // }, 3000); const updateData = { sStatus: row.sStatus }; axios .put(`/put-driver-prescription-orders/${row.nID_orders}`, updateData) .then((response) => { setTxtStatusDriver(response?.data?.data?.status); setTxtIDDriver(response?.data?.data?.deliveryID); setLoading(false); // enqueueSnackbar(response?.data?.meta?.message, { variant: 'success' }); // Call reloadData to refresh the table }) .catch((error) => { const errorMessage = error.response?.data?.meta?.message || 'Failed to update status'; enqueueSnackbar(errorMessage, { variant: 'error' }); setLoading(false); setIsDisabled(false); // Re-enable the button after success }); } else { putPrescriptionOrders(row); } } const putPrescriptionOrders = (row: any) => { setIsDisabled(true); // Disable button after clicking const updateData = { sStatus: row.sStatus }; axios .put(`/put-prescription-orders/${row.nID_orders}`, updateData) .then((response) => { enqueueSnackbar(response?.data?.meta?.message, { variant: 'success' }); setDialogIDRow(row.id === dialogIDRow ? null : row.id); setIsDisabled(false); // Re-enable the button after success // Call reloadData to refresh the table if (reloadData) { reloadData(); } }) .catch((error) => { const errorMessage = error.response?.data?.meta?.message || 'Failed to update status'; enqueueSnackbar(errorMessage, { variant: 'error' }); setIsDisabled(false); // Re-enable the button after success }); } return ( // {/* Field 1 */} {filters && filters.useFilter ? ( Division
searchs.setSearchText(event.target.value)} value={searchs.searchText} fullWidth />
) : null } {searchs && searchs.useSearchs ? ( {filterStatus && filterStatus.useFilter ? (
searchs.setSearchText(event.target.value)} value={searchs.searchText} fullWidth InputProps={{ startAdornment: ( ), }} placeholder={localeData.txtSearch} />
) :
searchs.setSearchText(event.target.value)} value={searchs.searchText} fullWidth InputProps={{ startAdornment: ( ), }} placeholder={localeData.txtSearch} />
}
) : null } {/* Start date */} {filterStartDate && filterStartDate.useFilter ? ( {/*
filterStartDate.handleStartDateChange(event)}> */} { filterStartDate.setStartDate( (newValue)); }} inputFormat="dd-MM-yyyy" renderInput={(params) => } />
) : null } {/* End Date */} {filterEndDate && filterEndDate.useFilter ? ( {/*
filterEndDate.handleEndDateChange(event)}> */} { filterEndDate.setEndDate( (newValue)); }} inputFormat="dd-MM-yyyy" renderInput={(params) => } />
) : null } {/* Filter status */} {filterStatus && filterStatus.useFilter ? ( Status ) : null } {/* Export Report */} {exportReport && exportReport.useExport ? ( ) : null }
{/* End Field 1 */} {/* Field 2 */} {/* Table */} {/* Table Header */} {/* End Table Header */} {/* Table Body */} {loadings.isLoading ? ( Loading . . . ) : rows && rows.length >= 1 ? ( rows.map((row, rowIndex) => ( <> {!selected.useSelected ? ( '' ): (selected.useSelected && row.check_status === 'approved' && !row.check_claim ? ( selected.handleCheckboxChange(row.id)} /> ):( ))} {headCells && //@ts-ignore headCells.map((head, headIndex) => ( //@ts-ignore {row[head.id]} ))} {/* COLLAPSIBLE ROW */} {/* Icon inside a Box for spacing and alignment */} {/* Adjust size and color */} {row.status} {row.nDeliveryID && ( Grab Delivery ID: {row.nDeliveryID} )} {setOpenRowId(openRowId === row.id ? null : row.id);}} sx={{ padding: '20px', maxWidth: '1200px', margin: '0 auto', backgroundColor: '#ffffff', borderRadius: '8px' }}> {/* Row 1 */} {localeData.txtProviderDoctorInformation} {localeData.txtNamaDokter} : {row.nama_dokter} {localeData.txtSpesialisasiDokter} : {row.spesialis} SIP : {row.sip} {localeData.txtNoPonsel} : {row.no_ponsel_dokter} {localeData.txtInformasiPasien} {localeData.txtNamaPasien} : {row.pasien} {localeData.txtTanggalLahirUmur} : {row.tgl_lahir_pasien ? fDateTimeWithAge(row.tgl_lahir_pasien) : ''} {localeData.txtJenisKelamin} : {row.jenis_kelamin_pasien} {localeData.txtTinggi} : {row.tinggi_berat} {/* Divider */} {localeData.txtInformasiAsuransi} {localeData.txtNomorKartu} : {row.no_polis} {localeData.txtAsuransi} : {row.perusahaan_asuransi} {localeData.txtPerusahaan} : {row.nama_perusahaan} {localeData.txtTipeAsuransi} : {row.kode_produk} {localeData.txtKelasAsuransi} : {row.kelas_asuransi} {localeData.txtTipeMember} : {row.tipe_member} {localeData.txtInformasiOrder} {localeData.txtNamaPenerima} : {row.pasien} {localeData.txtAlamatPenerima} : {row.alamat_penerima} {localeData.txtPengiriman} : {row.pengiriman} {localeData.txtTotal} : {row.total_kirim} {/* Divider */} {/* Row 2 */} {localeData.txtInformasiResep} {localeData.txtNomorResep} : {row.no_resep} {localeData.txtNomorRefDokter} : {row.noref_dokter} {localeData.txtTanggalTerbitResep} : {row.tanggal} {localeData.txtTanggalKedaluwarsa} : {row.valid_tanggal} {localeData.txtInformasiKonsultasi} {localeData.txtNomorPenjamin} : {row.nomor_penjamin} {localeData.txtTanggalKonsultasi} : {row.tgl_livechat} {localeData.txtAlergi} : {row.alergi_desc} {localeData.txtDiagnosis} : {row.diagnosa} {setOpenRowId(openRowId === row.id ? null : row.id);}} sx={{ padding: '20px', maxWidth: '1200px', margin: '20px auto', backgroundColor: '#ffffff', borderRadius: '8px' }}> {localeData.txtObat} {localeData.txtSigna} {localeData.txtWaktu} {localeData.txtDurasi} {localeData.txtJumlah} {localeData.txtCatatanObat} {row.prescription_items ? ( row.prescription_items.map((row : any, rowIndex: any) => ( {row.sItemName} {row.sSigna} {row.sTiming} {row.sDuration} {row.nQty} {row.sNote} )) ) : ( {localeData.txtDataNotFound} )} {/* Close Button on the Left */} {/* Accept Button on the Right */} {row.button_accept && formattedRoleName === 'admin-apotek' && allowedStatusesForApotek.includes(row.sStatus) ? ( ) : ''} {row.button_accept && formattedRoleName === 'cs-lms' && allowedStatusesForCSLMS.includes(row.sStatus) ? ( ) : ''} {/* Dialog Update Status */} {localeData.txtConfirmation} setDialogIDRow(row.id === dialogIDRow ? null : row.id)}> {localeData.txtDialogConfirmation} {localeData.txtNomorResep} {row.no_resep} {localeData.txtTanggalTerbitResep} {row.tanggal} {/* Modal for fullscreen display */} handleClose(row)}> {loading ? ( <> {localeData.txtFindingDriver} ) : ( <> Info! {txtIDDriver ? ( `${localeData.txtDriverFound} ${txtIDDriver} status ${txtStatusDriver}.` ) : ( // You can add an alternative UI or message here, or leave it empty `Failed to get driver, please check the message info.` )} )} )) ) : ( {localeData.txtDataNotFound} )} {/* End Table Body */} {/* End Table */} {/* Pagination */} {/* End Pagination */} {/* End Field 2 */}
//
); }