|
|
@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
import { useCallback, useEffect, useState } from 'react';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// material-ui
|
|
|
|
|
|
|
|
import { Button, Divider, FormControl, Grid, InputAdornment, InputLabel, Link, MenuItem, OutlinedInput, Select } from '@mui/material';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// assets
|
|
|
|
|
|
|
|
import { IconSearch } from '@tabler/icons';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// berry ui
|
|
|
|
|
|
|
|
import MainCard from 'ui-component/cards/MainCard';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// project imports
|
|
|
|
|
|
|
|
import MuiDataGrid from 'views/cmm/mui-grid/MuiDataGrid';
|
|
|
|
|
|
|
|
import { findBoards2, modifyBoardHitCount, removeBoard, saveBoard } from 'apis/board2';
|
|
|
|
|
|
|
|
import { useAlert } from 'react-alert';
|
|
|
|
|
|
|
|
import CmmModal from 'views/cmm/CmmModal';
|
|
|
|
|
|
|
|
import ModifyBoardForm from './ModifyBoardForm';
|
|
|
|
|
|
|
|
import useAuth from 'hooks/useAuth';
|
|
|
|
|
|
|
|
import { Save } from '@mui/icons-material';
|
|
|
|
|
|
|
|
import NewBoardForm from './NewBoardForm';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const Board = () => {
|
|
|
|
|
|
|
|
const { user } = useAuth();
|
|
|
|
|
|
|
|
const [owner, setOwner] = useState(false);
|
|
|
|
|
|
|
|
const [category, setCategory] = useState('ciTitle');
|
|
|
|
|
|
|
|
const [searchTxt, setSearchTxt] = useState('');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [totalCount, setTotalCount] = useState(0);
|
|
|
|
|
|
|
|
const [rowsState, setRowsState] = useState({
|
|
|
|
|
|
|
|
page: 0,
|
|
|
|
|
|
|
|
pageSize: 20,
|
|
|
|
|
|
|
|
rows: []
|
|
|
|
|
|
|
|
// loading: false
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
const [open, setOpen] = useState(false);
|
|
|
|
|
|
|
|
const [newBoard, setNewBoard] = useState(false);
|
|
|
|
|
|
|
|
const [selectedRow, setSelectedRow] = useState({});
|
|
|
|
|
|
|
|
const [create, setCreate] = useState(false);
|
|
|
|
|
|
|
|
const [title, setTitle] = useState();
|
|
|
|
|
|
|
|
const alert = useAlert();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
|
|
{ headerName: '글번호', headerAlign: 'center', field: 'ciContentno', align: 'center' },
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
headerName: '제목',
|
|
|
|
|
|
|
|
headerAlign: 'center',
|
|
|
|
|
|
|
|
field: 'ciTitle',
|
|
|
|
|
|
|
|
editable: true,
|
|
|
|
|
|
|
|
width: 400,
|
|
|
|
|
|
|
|
renderCell: (params) => {
|
|
|
|
|
|
|
|
let prefix = '';
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-plusplus
|
|
|
|
|
|
|
|
for (let idx = 0; idx < params.row.ciStep; idx++) {
|
|
|
|
|
|
|
|
prefix += ' ';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (params.row.ciStep > 0) prefix += '↳ ';
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<Link underline="hover" href="#">
|
|
|
|
|
|
|
|
{prefix}
|
|
|
|
|
|
|
|
{params.value}
|
|
|
|
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{ headerName: '작성자', headerAlign: 'center', field: 'ciName', align: 'center' },
|
|
|
|
|
|
|
|
{ headerName: '작성일', headerAlign: 'center', field: 'ciNalja', align: 'center' },
|
|
|
|
|
|
|
|
{ headerName: '조회수', headerAlign: 'center', field: 'ciHit', align: 'center' },
|
|
|
|
|
|
|
|
{ headerName: '게시판코드', headerAlign: 'center', field: 'ciCode', hide: true },
|
|
|
|
|
|
|
|
{ headerName: '작성자ID', headerAlign: 'center', field: 'ciId', hide: true },
|
|
|
|
|
|
|
|
{ headerName: '등록시간', headerAlign: 'center', field: 'ciTime', hide: true },
|
|
|
|
|
|
|
|
{ headerName: 'ref', headerAlign: 'center', field: 'ciRef', hide: true },
|
|
|
|
|
|
|
|
{ headerName: 'step', headerAlign: 'center', field: 'ciStep', hide: true },
|
|
|
|
|
|
|
|
{ headerName: '비번', headerAlign: 'center', field: 'ciPass', hide: true },
|
|
|
|
|
|
|
|
{ headerName: '내용', headerAlign: 'center', field: 'ciContents', hide: true },
|
|
|
|
|
|
|
|
{ headerName: 'IP', headerAlign: 'center', field: `ciIp`, hide: true },
|
|
|
|
|
|
|
|
{ headerName: 'level', headerAlign: 'center', field: 'ciRevel', hide: true }
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const search = useCallback(() => {
|
|
|
|
|
|
|
|
let params = {
|
|
|
|
|
|
|
|
page: rowsState.page,
|
|
|
|
|
|
|
|
size: rowsState.pageSize
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (searchTxt) {
|
|
|
|
|
|
|
|
params = {
|
|
|
|
|
|
|
|
...params,
|
|
|
|
|
|
|
|
[category]: searchTxt
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
findBoards2(params).then((response) => {
|
|
|
|
|
|
|
|
if (response && response.data) {
|
|
|
|
|
|
|
|
setTotalCount(response.count);
|
|
|
|
|
|
|
|
setRowsState((prevState) => ({ ...prevState, rows: response.data }));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}, [rowsState.page, rowsState.pageSize, category, searchTxt]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleSearch = async (event) => {
|
|
|
|
|
|
|
|
if (event.type === 'keydown' && event.key === 'Enter') {
|
|
|
|
|
|
|
|
const newString = event?.target.value;
|
|
|
|
|
|
|
|
setSearchTxt(newString);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleOnCellClick = (e) => {
|
|
|
|
|
|
|
|
if (e?.field === 'ciTitle') {
|
|
|
|
|
|
|
|
setOwner(user.id === e?.row.ciId);
|
|
|
|
|
|
|
|
setNewBoard(false);
|
|
|
|
|
|
|
|
setCreate(false);
|
|
|
|
|
|
|
|
setTitle('게시판 상세');
|
|
|
|
|
|
|
|
setSelectedRow(e?.row);
|
|
|
|
|
|
|
|
if (user.id !== e?.row.ciId) modifyBoardHitCount(e?.row?.ciCode);
|
|
|
|
|
|
|
|
setOpen(true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const submitBoard = (type, payload) => {
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
|
|
case 'SAVE':
|
|
|
|
|
|
|
|
if (window.confirm('저장 하시겠습니까?')) {
|
|
|
|
|
|
|
|
saveBoard(payload).then((res) => {
|
|
|
|
|
|
|
|
if (res?.success) {
|
|
|
|
|
|
|
|
search();
|
|
|
|
|
|
|
|
setOpen(false);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
alert.show(`${res?.data.message}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}); // .then((res) => {
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
window.close();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'DELETE':
|
|
|
|
|
|
|
|
if (window.confirm('삭제 하시겠습니까?')) {
|
|
|
|
|
|
|
|
removeBoard(payload).then((res) => {
|
|
|
|
|
|
|
|
if (res?.success) {
|
|
|
|
|
|
|
|
search();
|
|
|
|
|
|
|
|
setOpen(false);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
alert.show(`${res?.data.message}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}); // .then((res) => {
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
window.close();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 댓글인 경우 부모 댓글 번호를 ciRef, ciStep set
|
|
|
|
|
|
|
|
* @param parentCiCode
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
const onNewBoard = (e, parentCiCode, parentCiRef) => {
|
|
|
|
|
|
|
|
let title = '';
|
|
|
|
|
|
|
|
if (parentCiCode) {
|
|
|
|
|
|
|
|
setSelectedRow({
|
|
|
|
|
|
|
|
ciName: user.name,
|
|
|
|
|
|
|
|
ciRef: parentCiRef ?? parentCiCode,
|
|
|
|
|
|
|
|
ciStep: 1,
|
|
|
|
|
|
|
|
ciRevel: 1
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
title = '게시판 댓글 등록';
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
setSelectedRow({
|
|
|
|
|
|
|
|
ciName: user.name,
|
|
|
|
|
|
|
|
ciStep: 0,
|
|
|
|
|
|
|
|
ciRevel: 0
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
title = '게시판 새글 등록';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setNewBoard(true);
|
|
|
|
|
|
|
|
setTitle(title);
|
|
|
|
|
|
|
|
setOpen(true);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
search();
|
|
|
|
|
|
|
|
}, [search]); // rowsState.page, rowsState.pageSize, rowsState.rows]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<MainCard>
|
|
|
|
|
|
|
|
<Grid container spacing={2} alignItems="center">
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
|
|
|
|
<Grid item>
|
|
|
|
|
|
|
|
<FormControl fullWidth>
|
|
|
|
|
|
|
|
<InputLabel required>구분</InputLabel>
|
|
|
|
|
|
|
|
<Select
|
|
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
|
|
id="category"
|
|
|
|
|
|
|
|
name="reviewYear"
|
|
|
|
|
|
|
|
defaultValue={category}
|
|
|
|
|
|
|
|
value={category}
|
|
|
|
|
|
|
|
onChange={(e) => setCategory(e.target.value)}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<MenuItem key="1" value="ciTitle">
|
|
|
|
|
|
|
|
제목
|
|
|
|
|
|
|
|
</MenuItem>
|
|
|
|
|
|
|
|
<MenuItem key="2" value="ciName">
|
|
|
|
|
|
|
|
이름
|
|
|
|
|
|
|
|
</MenuItem>
|
|
|
|
|
|
|
|
<MenuItem key="3" value="ciContents">
|
|
|
|
|
|
|
|
내용
|
|
|
|
|
|
|
|
</MenuItem>
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
</FormControl>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item>
|
|
|
|
|
|
|
|
<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 item style={{ marginLeft: 'auto' }}>
|
|
|
|
|
|
|
|
<Button variant="contained" size="small" startIcon={<Save />} onClick={onNewBoard}>
|
|
|
|
|
|
|
|
글쓰기
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12} mt={1} mb={1}>
|
|
|
|
|
|
|
|
<Divider />
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<MuiDataGrid
|
|
|
|
|
|
|
|
columns={columns}
|
|
|
|
|
|
|
|
rowsState={rowsState}
|
|
|
|
|
|
|
|
totalCount={totalCount}
|
|
|
|
|
|
|
|
setRowsState={setRowsState}
|
|
|
|
|
|
|
|
handleCellClick={handleOnCellClick}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<CmmModal isBackdrop title={title} open={open} setOpen={setOpen}>
|
|
|
|
|
|
|
|
{newBoard && <NewBoardForm setOpen={setOpen} handleModalSave={submitBoard} rowData={selectedRow} owner={owner} />}
|
|
|
|
|
|
|
|
{!newBoard && (
|
|
|
|
|
|
|
|
<ModifyBoardForm
|
|
|
|
|
|
|
|
create={create}
|
|
|
|
|
|
|
|
setOpen={setOpen}
|
|
|
|
|
|
|
|
handleModalSave={submitBoard}
|
|
|
|
|
|
|
|
rowData={selectedRow}
|
|
|
|
|
|
|
|
owner={owner}
|
|
|
|
|
|
|
|
handleNewBoard={onNewBoard}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</CmmModal>
|
|
|
|
|
|
|
|
</MainCard>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Board;
|