feat: 주정차 의견 진술 - 심의 목록 반영1

main
Lim Jonguk 3 years ago
parent 8f43d84268
commit dac5dc0cbe

@ -1,3 +1,3 @@
REACT_APP_VERSION = v0.0.1
REACT_APP_API_URL=http://localhost:8090
REACT_APP_SERVER_TIMEOUT=60000
REACT_APP_SERVER_TIMEOUT=6000

@ -41,6 +41,7 @@
"jwt-decode": "^3.1.2",
"lodash": "^4.17.21",
"material-ui-popup-state": "^2.0.0",
"moment": "^2.29.1",
"prop-types": "^15.8.1",
"react": "^17.0.2",
"react-apexcharts": "^1.3.9",

@ -1,133 +0,0 @@
import axios, { AxiosInstance, AxiosInterceptorManager, AxiosRequestConfig, AxiosResponse } from 'axios';
import Swal from 'sweetalert2';
type CustomResponseFormat<T = any> = {
response: T, // e<T>;
refreshedToken?: string
};
export interface CustomInstance extends AxiosInstance {
interceptors: {
request: AxiosInterceptorManager<AxiosRequestConfig>,
response: AxiosInterceptorManager<AxiosResponse<CustomResponseFormat>>
};
getUri(config?: AxiosRequestConfig): string;
request<T>(config: AxiosRequestConfig): Promise<T>;
get<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
delete<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
head<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
options<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
patch<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
}
const reqApi: CustomInstance = axios.create({
baseURL: process.env.NODE_ENV === 'development' ? process.env.REACT_APP_API_URL : '',
withCredentials: process.env.NODE_ENV === 'development', // 개발시만 사용 : crossdomain
timeout: 1000
// headers: {
// 'Content-Type': 'application/json'
// // AUTH_HEADER_NAME: accessToken
// }
// params: {key: key}
});
/**
* before axios request
*/
reqApi.interceptors.request.use(
(config) => {
Swal.fire({
title: 'Please Wait ...',
// html: '',
// imageUrl:
// timer: 10000,
didOpen: () => Swal.showLoading()
}).then((r) => {});
return config;
},
({ config, request, response, ...error }) => {
console.error('========== ApiService.request error Data ==========');
return alertError(config, request, response, error);
}
);
/**
* after axios response
*/
reqApi.interceptors.response.use(
(response: AxiosResponse) => {
Swal.close();
if (!response.data.success) {
Swal.fire({
icon: 'error',
title: 'Api Error',
html: `${response.data.message}`,
// imageUrl:
timer: 5000
}).then((r) => {});
console.log(response);
}
return Promise.resolve(response.data);
},
({ config, request, response, ...error }) => {
console.error('========== ApiService.response Error Data ==========');
alertError(config, request, response, error);
// error 데이타 return
// return response.data;
return error;
}
);
/**
* 에러 처리
* TODO :: 토큰 에러인 경우 업무 정의에 따라 alert 처리 여부등 결정하여 내용 추가
* @param config
* @param request
* @param response
* @param error
*/
const alertError = (config: AxiosRequestConfig, request: any, response: AxiosResponse, error: Error) => {
if (!response) {
Swal.fire({
icon: 'error',
title: 'Api Error',
html: `시스템 에러~~~~~~~~~~~~`,
// imageUrl:
timer: 5000
}).then((r) => {});
return;
}
const errCode = response.data.code;
const errMsg = response.data.error;
console.error(`${errCode}: ${errMsg}`);
console.error('=================================');
// Alert.error(`${errCode}: ${errMsg}`);
Swal.fire({
icon: 'error',
title: 'Api Error',
html: `${errCode}: ${errMsg}`,
// imageUrl:
timer: 5000
}).then((r) => {});
// return Promise.reject({
// config,
// //message: errMsg,
// response,
// ...error
// })
};
export default reqApi;

@ -1,17 +1,17 @@
import reqApi from './ApiService';
import { CMM_CODE_LIST_URL } from 'commons/ApiUrl';
import { IApiResponse } from 'types/api';
import { IComboCode, IParam } from 'types/Data';
import axios from 'utils/axios';
class CmmService {
// eslint-disable-next-line class-methods-use-this
getComboCodeList(params) {
return reqApi.get(CMM_CODE_LIST_URL, { params });
// .then(r => console.log(r))
// .catch(e => {
// console.log(e)
// });
}
// eslint-disable-next-line no-return-await
getComboCodeList = async (params) => await axios.get(CMM_CODE_LIST_URL, { params });
// getComboCodeList(params) {
// return reqApi.get(CMM_CODE_LIST_URL, { params });
// .then(r => console.log(r))
// .catch(e => {
// console.log(e)
// });
// }
}
export default CmmService;

@ -64,6 +64,7 @@ export const JWTProvider = ({ children }) => {
setLocalStorage(ACCESS_TOKEN_NAME, accessToken);
const response = await axios.get('/api/v1/ctgy/user');
console.log(response);
// TODO : 적용 필요
const { userid, email, name } = response.data;
dispatch({
type: LOGIN,

@ -131,7 +131,7 @@ const opst = {
id: 'opst-4-1',
title: <FormattedMessage id="opst-3-1" />,
type: 'item',
url: '/disabled/dataMgt',
url: '/disabled/data',
icon: icons.IconDatabase
},
{

@ -11,8 +11,10 @@ const DashboardDefault = Loadable(lazy(() => import('views/dashboard/Default')))
const DashboardAnalytics = Loadable(lazy(() => import('views/dashboard/Analytics')));
// opst page routing
const PublicBoard = Loadable(lazy(() => import('views/biz/board/public')));
const Board = Loadable(lazy(() => import('views/biz/board')));
const PublicBoard = Loadable(lazy(() => import('views/biz/board/PublicBoard')));
const Board = Loadable(lazy(() => import('views/biz/board/Board')));
const ParkingReview = Loadable(lazy(() => import('views/biz/parking/Review')));
const ParkingRegister = Loadable(lazy(() => import('views/biz/parking/Regist')));
// ==============================|| MAIN ROUTING ||============================== //
@ -41,11 +43,11 @@ const MainRoutes = {
/* 주정차 */
{
path: '/parking/review',
element: <Board />
element: <ParkingReview />
},
{
path: '/parking/register',
element: <Board />
element: <ParkingRegister />
},
/* 거주자 */
{

@ -45,7 +45,7 @@ const MuiGridList = ({ columns, rowsState, totalCount, setRowsState }) => {
{...rowsState}
onPageChange={(page) => setRowsState((prev) => ({ ...prev, page }))}
onPageSizeChange={(pageSize) => setRowsState((prev) => ({ ...prev, page: 0, pageSize }))}
rowsPerPageOptions={[5, 10, 50, 100]}
rowsPerPageOptions={[10, 50, 100]}
pagination
/>
</Box>

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
// material-ui
import { Button, Divider, FormControl, FormControlLabel, Grid, OutlinedInput, Radio, RadioGroup } from '@mui/material';
import { Button, Divider, FormControl, FormControlLabel, Grid, InputAdornment, OutlinedInput, Radio, RadioGroup } from '@mui/material';
// assets
import { IconSearch } from '@tabler/icons';
@ -13,14 +13,14 @@ import MainCard from 'ui-component/cards/MainCard';
import MuiGridList from 'ui-component/MuiGridList';
import boardService from 'apis/BoardService';
const Index = () => {
const Board = () => {
const [category, setCategory] = useState('ciTitle');
const [searchTxt, setSearchTxt] = useState('');
const [totalCount, setTotalCount] = useState(0);
const [rowsState, setRowsState] = useState({
page: 0,
pageSize: 5,
pageSize: 10,
rows: []
// loading: false
});
@ -84,7 +84,7 @@ const Index = () => {
setRowsState((prevState) => ({ ...prevState, rows: response.data }));
}
});
}, [rowsState.page, rowsState.pageSize, searchTxt]); // rowsState.page, rowsState.pageSize, rowsState.rows]);
}, [rowsState.page, rowsState.pageSize, category, searchTxt]); // rowsState.page, rowsState.pageSize, rowsState.rows]);
return (
<MainCard>
@ -107,8 +107,18 @@ const Index = () => {
</FormControl>
</Grid>
<Grid item>
<OutlinedInput id="input-search-list-style1" placeholder="Search" onKeyDown={handleSearch} size="small" autoFocus />
<IconSearch stroke={1.5} size="1rem" />
<OutlinedInput
placeholder="Search"
onKeyDown={handleSearch}
size="small"
autoFocus
endAdornment={
<InputAdornment position="end">
<IconSearch stroke={1.5} size="1rem" />
</InputAdornment>
}
/>
{/* <IconSearch stroke={1.5} size="1rem" /> */}
</Grid>
</Grid>
</Grid>
@ -123,4 +133,4 @@ const Index = () => {
</MainCard>
);
};
export default Index;
export default Board;

@ -1,121 +0,0 @@
import React, { useState, useEffect } from 'react';
import { NavLink } from 'react-router-dom';
// material-ui
import { DataGrid } from '@mui/x-data-grid';
import { Box, Button } from '@mui/material';
import ListItemText from '@mui/material/ListItemText';
import { useTheme } from '@mui/material/styles';
// project imports
import CmmService from 'apis/CmmService';
import boardService from '../../../apis/BoardService';
const columns = [
{ headerName: '게시판코드', field: 'ciCode' },
{ headerName: '글번호', field: 'ciContentno' },
{ headerName: '제목', field: 'ciTitle', editable: true },
{ headerName: '사용자ID', field: 'ciId' },
{ headerName: '사용자 비번', field: 'ciPwd' },
{ headerName: '사용자 이름', field: 'ciName' },
{ headerName: '등록일', field: 'ciNalja' },
{ headerName: '등록시간', field: 'ciTime' },
{ headerName: '조회수', field: 'ciHit' },
{ headerName: 'ref', field: 'ciRef' },
{ headerName: 'step', field: 'ciStep' },
{ headerName: 'level', field: 'ciRevel' },
{ headerName: '비번', field: 'ciPass' },
{
headerName: 'email',
field: 'ciEmail',
renderCell: (params) => (
<strong>
{params.value}
<Button variant="contained" color="primary" size="small">
Open
</Button>
</strong>
)
},
{ headerName: '내용', field: 'ciContents' },
{
headerName: 'IP',
field: `ciIp`
}
];
const cmmService = new CmmService();
const BoardList = () => {
const theme = useTheme();
const [totalCount, setTotalCount] = useState(0);
const [rowsState, setRowsState] = useState({
page: 0,
pageSize: 5,
rows: []
// loading: false
});
const [ciDiv, setCiDiv] = useState();
useEffect(() => {
const params = {
page: rowsState.page + 1,
size: rowsState.pageSize
};
boardService.getBoardList(params).then((response) => {
console.log(response);
if (response && response.data) {
setTotalCount(response.count);
setRowsState((prevState) => ({ ...prevState, rows: response.data }));
}
});
}, [rowsState.page, rowsState.pageSize]); // rowsState.page, rowsState.pageSize, rowsState.rows]);
return (
// <CardContent>
// <div style={{ height: 700, width: '100%' }}>
<Box
sx={{
height: 700,
width: '100%',
'& .MuiDataGrid-root': {
border: 'none',
'& .MuiDataGrid-cell': {
borderColor: theme.palette.mode === 'dark' ? theme.palette.text.primary + 15 : 'grey.200'
},
'& .MuiDataGrid-columnsContainer': {
color: theme.palette.mode === 'dark' ? 'grey.600' : 'grey.900',
borderColor: theme.palette.mode === 'dark' ? theme.palette.text.primary + 15 : 'grey.200'
},
'& .MuiDataGrid-columnSeparator': {
color: theme.palette.mode === 'dark' ? theme.palette.text.primary + 15 : 'grey.200'
}
}
}}
>
<DataGrid
paginationMode="server"
getRowId={(row) => row.ciContentno}
rowCount={totalCount}
checkboxSelection
disableSelectionOnClick
// isRowSelectable={(params: any) => params.row.id > 0}
// rows={tableData}
columns={columns}
// pageSize={pageSize}
{...rowsState}
onPageChange={(page) => setRowsState((prev) => ({ ...prev, page }))}
onPageSizeChange={(pageSize) => setRowsState((prev) => ({ ...prev, pageSize }))}
rowsPerPageOptions={[5, 10, 50, 100]}
pagination
/>
<NavLink to="/writeBoard">
<ListItemText>글쓰기</ListItemText>
</NavLink>
</Box>
);
};
export default BoardList;

@ -15,7 +15,7 @@ import MuiGridList from 'ui-component/MuiGridList';
import InputLabel from 'ui-component/extended/Form/InputLabel';
import boardService from '../../../apis/BoardService';
const Index = () => {
const PublicBoard = () => {
const [totalCount, setTotalCount] = useState(0);
const [rowsState, setRowsState] = useState({
page: 0,
@ -208,4 +208,4 @@ const Index = () => {
</MainCard>
);
};
export default Index;
export default PublicBoard;

@ -0,0 +1,5 @@
import React from 'react';
const ParkingRegister = () => <div>주정차 의견진술 심의 등록</div>;
export default ParkingRegister;

@ -0,0 +1,138 @@
import { useEffect, useState } from 'react';
import _ from 'lodash';
// material-ui
import { Button, Divider, Grid, InputAdornment, MenuItem, OutlinedInput, Select } from '@mui/material';
import MuiTooltip from '@mui/material/Tooltip';
// assets
import { IconSearch } from '@tabler/icons';
// berry ui
import MainCard from 'ui-component/cards/MainCard';
// project imports
import MuiGridList from 'ui-component/MuiGridList';
import boardService from 'apis/BoardService';
import moment from 'moment';
const ParkingReview = () => {
const toYear = Number(moment().format('YYYY'));
const years = _.range(toYear, toYear - 14, -1);
const [selectedYear, setSelectedYear] = useState(toYear);
const [searchTxt, setSearchTxt] = useState('');
const [totalCount, setTotalCount] = useState(0);
const [rowsState, setRowsState] = useState({
page: 0,
pageSize: 10,
rows: []
// loading: false
});
const columns = [
{ headerName: '게시판코드', field: 'ciCode' },
{ headerName: '글번호', field: 'ciContentno' },
{ headerName: '제목', field: 'ciTitle', editable: true },
{ headerName: '사용자ID', field: 'ciId' },
{ headerName: '사용자 비번', field: 'ciPwd' },
{ headerName: '사용자 이름', field: 'ciName' },
{ headerName: '등록일', field: 'ciNalja' },
{ headerName: '등록시간', field: 'ciTime' },
{ headerName: '조회수', field: 'ciHit' },
{ headerName: 'ref', field: 'ciRef' },
{ headerName: 'step', field: 'ciStep' },
{ headerName: 'level', field: 'ciRevel' },
{ headerName: '비번', field: 'ciPass' },
{
headerName: 'email',
field: 'ciEmail',
renderCell: (params) => (
<strong>
{params.value}
<Button variant="contained" color="primary" size="small">
Open
</Button>
</strong>
)
},
{ headerName: '내용', field: 'ciContents' },
{
headerName: 'IP',
field: `ciIp`
}
];
const handleSearch = async (event) => {
if (event.type === 'keydown' && event.key === 'Enter') {
const newString = event?.target.value;
setSearchTxt(newString);
}
};
useEffect(() => {
let params = {
page: rowsState.page + 1,
size: rowsState.pageSize
};
console.log(selectedYear);
if (searchTxt) {
params = {
...params,
year: selectedYear
};
}
// boardService.getBoardList(params).then((response) => {
// console.log(response);
// if (response && response.data) {
// setTotalCount(response.count);
// setRowsState((prevState) => ({ ...prevState, rows: response.data }));
// }
// });
}, [rowsState.page, rowsState.pageSize, searchTxt]); // rowsState.page, rowsState.pageSize, rowsState.rows]);
return (
<MainCard>
<Grid container spacing={2} alignItems="center">
<Grid item xs={12} lg={6}>
<Grid container spacing={1}>
<Grid item>
<MuiTooltip title="의견진술 심의 년도">
<Select id="reviewYear" name="reviewYear" defaultValue={toYear} onChange={(e) => setSelectedYear(e.target.value)}>
{years.map((year, idx) => (
<MenuItem key={idx} value={year}>
{year}
</MenuItem>
))}
</Select>
</MuiTooltip>
</Grid>
<Grid item>
<OutlinedInput
placeholder="심의차수"
onKeyDown={handleSearch}
size="small"
autoFocus
endAdornment={
<InputAdornment position="end">
<IconSearch stroke={1.5} size="1rem" />
</InputAdornment>
}
/>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Divider />
</Grid>
<Grid item xs={12}>
<Divider />
</Grid>
<MuiGridList columns={columns} rowsState={rowsState} totalCount={totalCount} setRowsState={setRowsState} />
</MainCard>
);
};
export default ParkingReview;
Loading…
Cancel
Save