import Search from '@components/Search' import CustomDataGrid from '@components/Table/CustomDataGrid' import { GRID_PAGE_SIZE } from '@constants' import usePage from '@hooks/usePage' import useSearchTypes from '@hooks/useSearchType' import { convertStringToDateFormat } from '@libs/date' import Box from '@material-ui/core/Box' import Link from '@material-ui/core/Link' import MenuItem from '@material-ui/core/MenuItem' import { createStyles, makeStyles, Theme } from '@material-ui/core/styles' import TextField from '@material-ui/core/TextField' import Typography from '@material-ui/core/Typography' import { GridCellParams, GridColDef, GridValueFormatterParams, GridValueGetterParams, } from '@material-ui/data-grid' import { ICode, ILocation, locationService, reserveItemService } from '@service' import { conditionAtom, conditionValue, errorStateSelector } from '@stores' import { Page, rownum } from '@utils' import { GetServerSideProps } from 'next' import { useRouter } from 'next/router' import React, { useCallback, useMemo, useState } from 'react' import { TFunction, useTranslation } from 'react-i18next' import { useRecoilValue, useSetRecoilState } from 'recoil' import { reserveService } from 'src/service/Reserve' // material-ui style const useStyles = makeStyles((theme: Theme) => createStyles({ root: { flexGrow: 1, '& .MuiOutlinedInput-input': { padding: theme.spacing(1), }, }, search: { padding: theme.spacing(1), textAlign: 'center', width: '10vw', maxWidth: 100, minWidth: 80, }, }), ) const conditionKey = 'reserve' type ColumnType = ( props: ReserveListProps, data: Page, handleUpdate: (id: number) => void, toggleIsUse: (event: React.ChangeEvent, id: number) => void, t: TFunction, ) => GridColDef[] //그리드 컬럼 정의 const getColumns: ColumnType = (props, data, handleUpdate, toggleIsUse, t) => { const { locations, categories, status } = props return [ { field: 'rownum', headerName: t('common.no'), headerAlign: 'center', align: 'center', width: 80, sortable: false, valueGetter: (params: GridValueGetterParams) => rownum(data, params.api.getRowIndex(params.id), 'asc'), }, { field: 'locationId', headerName: t('location'), headerAlign: 'center', align: 'center', flex: 1, sortable: false, renderCell: (params: GridCellParams) => ( <> { locations.find(item => item.locationId === params.value) .locationName } ), }, { field: 'categoryId', headerName: t('reserve_item.type'), headerAlign: 'center', align: 'center', flex: 1, sortable: false, renderCell: (params: GridCellParams) => ( <>{categories.find(item => item.codeId === params.value).codeName} ), }, { field: 'reserveItemName', headerName: t('reserve_item.name'), headerAlign: 'center', align: 'left', flex: 1, sortable: false, renderCell: (params: GridCellParams) => ( {params.value} ), }, { field: 'totalQty', headerName: `${t('reserve.count')}/${t('reserve.number_of_people')}`, headerAlign: 'center', align: 'center', flex: 1, sortable: false, }, { field: 'userName', headerName: t('reserve.user'), headerAlign: 'center', align: 'center', flex: 1, sortable: false, }, { field: 'reserveStatusId', headerName: t('reserve.status'), headerAlign: 'center', align: 'center', sortable: false, renderCell: (params: GridCellParams) => ( <>{status.find(item => item.codeId === params.value).codeName} ), }, { field: 'createDate', headerName: t('common.created_datetime'), headerAlign: 'center', align: 'center', sortable: false, flex: 1, valueFormatter: (params: GridValueFormatterParams) => convertStringToDateFormat( params.value as string, 'yyyy-MM-dd HH:mm:ss', ), }, ] } interface ReserveListProps { locations?: ILocation[] categories?: ICode[] status?: ICode[] } const Reserve = (props: ReserveListProps) => { const { locations, categories } = props const classes = useStyles() const { t } = useTranslation() const router = useRouter() //조회조건 상태관리 const keywordState = useRecoilValue(conditionAtom(conditionKey)) const [customKeyword, setCustomKeyword] = useState({ locationId: keywordState?.locationId || '0', categoryId: keywordState?.categoryId || 'all', }) const { page, setPageValue } = usePage(conditionKey) // 에러 상태관리 const setErrorState = useSetRecoilState(errorStateSelector) //조회조건 select items const searchTypes = useSearchTypes([ { key: 'item', label: t('reserve_item.name'), }, ]) //목록 데이터 조회 및 관리 const { data, mutate } = reserveService.search({ keywordType: keywordState?.keywordType || 'item', keyword: keywordState?.keyword || '', size: GRID_PAGE_SIZE, page, locationId: keywordState?.locationId !== '0' ? keywordState?.locationId : null, categoryId: keywordState?.categoryId !== 'all' ? keywordState?.categoryId : null, }) //목록 조회 const handleSearch = () => { if (page === 0) { mutate(data, false) } else { setPageValue(0) } } const handleRegister = () => { router.push('/reserve/item') } //datagrid page change event const handlePageChange = (page: number, details?: any) => { setPageValue(page) } const handleUpdate = (id: number) => { router.push(`/reserve-item/${id}`) } const handleCategoryChange = (e: React.ChangeEvent) => { e.preventDefault() setCustomKeyword({ ...customKeyword, categoryId: e.target.value, }) } const handleLocationChange = (e: React.ChangeEvent) => { e.preventDefault() setCustomKeyword({ ...customKeyword, locationId: e.target.value, }) } //사용여부 toggle 시 바로 update const toggleIsUse = useCallback( async (event: React.ChangeEvent, id: number) => { try { const result = await reserveItemService.updateUse( id, event.target.checked, ) if (result?.status === 204) { mutate() } } catch (error) { setErrorState({ error }) } }, [customKeyword], ) // 목록컬럼 재정의 > 컬럼에 비지니스 로직이 필요한 경우 const columns = useMemo(() => { return getColumns(props, data, handleUpdate, toggleIsUse, t) }, [props, data, t]) return (
{t('common.all')} {locations && locations.map(option => ( {option.locationName} ))} {t('common.all')} {categories && categories.map(option => ( {option.codeName} ))} } /> r.reserveId} />
) } export const getServerSideProps: GetServerSideProps = async ({ query }) => { let locations: ILocation[] = [] let categories: ICode[] = [] let status: ICode[] = [] try { let result = await locationService.getList() if (result) { locations = result.data } result = await reserveItemService.getCode('reserve-category') if (result) { categories = result.data } result = await reserveItemService.getCode('reserve-status') if (result) { status = result.data } } catch (error) { console.error(`reserve item query error ${error.message}`) } return { props: { categories, locations, status, }, } } export default Reserve