fix: 게시판관리 반영

main
minuk926 3 years ago
parent 843f0adc85
commit 3c71453d52

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------
import axios from 'utils/axios';
import { GET_BOARD_LIST } from 'commons/ApiUrl';
import { GET_BOARD_LIST, REMOVE_BOARD, SAVE_BOARD, SAVE_BOARD_HIT_CNT } from 'commons/ApiUrl';
import { setRowId } from './common';
// eslint-disable-next-line import/prefer-default-export
@ -15,3 +15,18 @@ export async function findBoards(params) {
}
return res;
}
export async function saveBoard(params) {
// eslint-disable-next-line no-return-await
return await axios.post(SAVE_BOARD, params);
}
export async function removeBoard(inCode) {
// eslint-disable-next-line no-return-await
return await axios.post(REMOVE_BOARD + inCode);
}
export async function modifyBoardHitCount(inCode) {
// eslint-disable-next-line no-return-await
return await axios.put(SAVE_BOARD_HIT_CNT + inCode);
}

@ -35,11 +35,8 @@ export async function saveJudgeData(formData) {
}
export async function findJudge(scCode) {
const res = await axios.get(GET_JUDGE_DATA + scCode);
if (res.success) {
return res;
}
return res;
// eslint-disable-next-line no-return-await
return await axios.get(GET_JUDGE_DATA + scCode);
}
export async function findJudges(params) {
@ -52,12 +49,8 @@ export async function findJudges(params) {
}
export async function findJudgeResults2(params) {
const res = await axios.get(GET_JUDGE_RESULT_LIST, { params });
if (res.success) {
// res.data = res.data.map((d, idx) => ({ ...d, rowId: setRowId(params, idx) }));
return res;
}
return res;
// eslint-disable-next-line no-return-await
return await axios.get(GET_JUDGE_RESULT_LIST, { params });
}
/**
@ -111,9 +104,6 @@ export async function findJudgeTargets(params) {
}
export async function saveJudgeTargets(params) {
const res = await axios.post(SAVE_JUDGE_TARGET_LIST, params);
if (res.success) {
return res;
}
return res;
// eslint-disable-next-line no-return-await
return await axios.post(SAVE_JUDGE_TARGET_LIST, params);
}

@ -31,10 +31,6 @@ export async function removePublicBoard(inCode) {
return await axios.post(REMOVE_PUBLIC_BOARD + inCode);
}
// getPublicBoard = async (inCode) => {
// await axios.get(GET_PUBLIC_BOARD + inCode);
// };
export async function modifyPublicBoardHitCount(inCode) {
const res = await axios.put(SAVE_PUBLIC_BOARD_HIT_CNT + inCode);
if (res.success) {

@ -13,6 +13,9 @@ export const REMOVE_PUBLIC_BOARD = '/api/v1/ctgy/file/pboard/';
// 게시판
export const GET_BOARD_LIST = '/api/v1/ctgy/board';
export const SAVE_BOARD_HIT_CNT = '/api/v1/ctgy/board/hit/';
export const SAVE_BOARD = '/api/v1/ctgy/board';
export const REMOVE_BOARD = '/api/v1/ctgy/board/';
// 주정차 의견 진술
export const GET_PARKING_LIST = '/api/v1/ctgy/parking';
@ -29,12 +32,6 @@ export const GET_JUDGE_RESULT_LIST = '/api/v1/ctgy/judge/result';
export const GET_JUDGE_TARGET_LIST = '/api/v1/ctgy/judge/target';
export const SAVE_JUDGE_TARGET_LIST = '/api/v1/ctgy/judge/target';
// 장애인 의견 진술
export const GET_DISABLED_DATA_LIST = '/api/v1/ctgy/judge/data';
export const SAVE_DISABLED_DATA = '/api/v1/ctgy/judge/data';
export const GET_DISABLED = '/api/v1/ctgy/judge/data/';
export const GET_DISABLED_LIST = '/api/v1/ctgy/judge';
// 사용자 관리
export const GET_USER_LIST = '/api/v1/ctgy/user';
export const SAVE_USER = '/api/v1/ctgy/user';

@ -156,36 +156,18 @@ const opst = {
/* 사용자 관리 */
id: 'opst-5',
title: <FormattedMessage id="opst-5" />,
type: 'collapse',
icon: icons.IconUserCheck,
children: [
{
/* 사용자 관리 */
id: 'opst-5-1',
title: <FormattedMessage id="opst-5" />,
type: 'item',
url: '/user/management',
icon: icons.IconDatabase
},
{
/* 심사위원 평가 */
id: 'opst-5-2',
title: <FormattedMessage id="opst-5-2" />,
type: 'item',
url: '/user/juror',
icon: icons.IconFileCertificate
}
]
},
{
/* SMS 관리 */
id: 'opst-6',
title: <FormattedMessage id="opst-6" />,
type: 'item',
url: '/sms/management',
icon: icons.IconMessage
url: '/user/management',
icon: icons.IconUserCheck
},
// {
// /* SMS 관리 */
// id: 'opst-6',
// title: <FormattedMessage id="opst-6" />,
// type: 'item',
// url: '/sms/management',
// icon: icons.IconMessage
// },
{
/* 게시판 관리 */
id: 'opst-7',

@ -25,7 +25,6 @@ const JudgeRegistReview = Loadable(lazy(() => import('views/biz/judge/JudgeRegis
// user
const UserManager = Loadable(lazy(() => import('views/biz/user/UserManager')));
const Juror = Loadable(lazy(() => import('views/biz/user/Juror')));
// component
const ModalForm = Loadable(lazy(() => import('views/form/Modal')));
@ -94,10 +93,6 @@ const MainRoutes = {
path: '/user/management',
element: <UserManager />
},
{
path: '/user/juror',
element: <Juror />
},
/* SMS */
{
path: '/sms/management',
@ -108,10 +103,6 @@ const MainRoutes = {
path: '/board',
element: <Board />
},
{
path: '/user/juror',
element: <Board />
},
// ----------------------------------------
{

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
// material-ui
import { Divider, Grid, InputAdornment, MenuItem, OutlinedInput, Select } from '@mui/material';
import { Button, Divider, FormControl, Grid, InputAdornment, InputLabel, Link, MenuItem, OutlinedInput, Select } from '@mui/material';
// assets
import { IconSearch } from '@tabler/icons';
@ -11,9 +11,18 @@ import MainCard from 'ui-component/cards/MainCard';
// project imports
import MuiDataGrid from 'views/cmm/MuiDataGrid';
import { findBoards } from 'apis/board';
import { findBoards, modifyBoardHitCount, removeBoard, saveBoard } from 'apis/board';
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();
console.log(user);
const [owner, setOwner] = useState(false);
const [category, setCategory] = useState('ciTitle');
const [searchTxt, setSearchTxt] = useState('');
@ -24,33 +33,51 @@ const Board = () => {
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: '게시판코드', 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' },
{ headerName: '내용', field: 'ciContents' },
{ headerName: 'IP', field: `ciIp` }
{ 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: false },
{ 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 handleSearch = async (event) => {
if (event.type === 'keydown' && event.key === 'Enter') {
const newString = event?.target.value;
setSearchTxt(newString);
}
};
useEffect(() => {
const search = useCallback(() => {
let params = {
page: rowsState.page,
size: rowsState.pageSize
@ -69,7 +96,79 @@ const Board = () => {
setRowsState((prevState) => ({ ...prevState, rows: response.data }));
}
});
}, [rowsState.page, rowsState.pageSize, category, searchTxt]); // rowsState.page, rowsState.pageSize, rowsState.rows]);
}, [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':
saveBoard(payload).then((res) => {
if (res?.success) {
search();
setOpen(false);
} else {
alert.show(`${res?.data.message}`);
}
}); // .then((res) => {
break;
case 'DELETE':
removeBoard(payload).then(() => {
search();
setOpen(false);
}); // .then((res) => {
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>
@ -77,17 +176,20 @@ const Board = () => {
<Grid item xs={12} lg={6}>
<Grid container spacing={1}>
<Grid item>
<Select id="category" name="reviewYear" defaultValue="ciTitle" 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 fullWidth>
<InputLabel required>소속팀</InputLabel>
<Select size="small" id="category" name="reviewYear" defaultValue="ciTitle" 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
@ -103,16 +205,37 @@ const Board = () => {
/>
{/* <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}>
<Divider />
</Grid>
<Grid item xs={12}>
<Grid item xs={12} mt={1} mb={1}>
<Divider />
</Grid>
<MuiDataGrid columns={columns} rowsState={rowsState} totalCount={totalCount} setRowsState={setRowsState} />
<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>
);
};

@ -0,0 +1,164 @@
import { useMemo, useRef, useState } from 'react';
import { useAlert } from 'react-alert';
// material-ui
import { Button, Divider, Grid, TextField } from '@mui/material';
// berry ui
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
// project imports
import { Delete, List, Save } from '@mui/icons-material';
import PropTypes from 'prop-types';
const ModifyBoardForm = (props) => {
// eslint-disable-next-line react/prop-types
const { setOpen, handleModalSave, rowData = {}, owner = false, handleNewBoard } = props;
console.log(`~~~~~~${owner}`);
const alert = useAlert();
const quillRef = useRef();
const [subject, setSubject] = useState(rowData.ciTitle);
const [contents, setContents] = useState(rowData.ciContents);
const [pass, setPass] = useState(rowData.ciPass);
const onList = () => {
setOpen(false);
};
const onSave = () => {
// TODO : validation check
const saveData = {
ciCode: rowData.ciCode,
ciTitle: subject,
ciContents: contents,
ciPass: pass
};
handleModalSave('SAVE', saveData);
};
const onRemove = () => {
handleModalSave('DELETE', rowData.ciCode);
};
const onResponse = (e) => {
// : ciRef, ciStep
handleNewBoard(e, rowData.ciCode, rowData.ciRef ?? rowData.ciCode);
};
const modules = useMemo(
() => ({
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[{ size: ['small', false, 'large', 'huge'] }, { color: [] }],
[{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }, { align: [] }]
// ['image', 'video']
]
}
}),
[]
);
return (
<>
<Grid mt={1}>
<Grid container spacing={1} item xs={12} mb={1}>
<Grid item sm={3}>
<TextField size="small" disabled label="작성자" value={rowData.ciName} fullWidth />
</Grid>
<Grid item sm={3}>
<TextField size="small" disabled label="등록일" value={rowData.ciNalja} fullWidth />
</Grid>
<Grid item sm={3}>
<TextField size="small" disabled label="글번호" value={rowData.ciCode} fullWidth />
</Grid>
<Grid item sm={3}>
<TextField size="small" disabled label="조회수" value={rowData.ciHit} fullWidth />
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={2}>
<Grid item sm={12}>
<TextField
disabled={!owner}
size="small"
required
label="제목"
value={subject}
onChange={(e) => setSubject(e.target.value)}
fullWidth
/>
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={2}>
<Grid item xs={12}>
<ReactQuill
ref={(element) => {
if (element !== null) {
quillRef.current = element;
}
}}
readOnly={!owner}
value={contents}
onChange={setContents}
modules={modules}
theme="snow"
placeholder="내용을 입력해주세요."
/>
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={2}>
<Grid item sm={12}>
<TextField
disabled={!owner}
size="small"
type="password"
required
label="비밀번호"
value={pass}
onChange={(e) => setPass(e.target.value)}
fullWidth
/>
</Grid>
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={1}>
<Grid item xs={12}>
<Divider />
</Grid>
</Grid>
<Grid item container spacing={0.5} xs={12} mt={1}>
<Grid item>
<Button variant="contained" size="small" startIcon={<List />} onClick={onList}>
목록
</Button>
</Grid>
<Grid item>
<Button disabled={owner} variant="contained" size="small" startIcon={<List />} onClick={onResponse}>
답변하기
</Button>
</Grid>
<Grid item style={{ marginLeft: 'auto' }}>
<Button disabled={!owner} variant="contained" size="small" startIcon={<Save />} onClick={onSave}>
저장
</Button>
</Grid>
<Grid item>
<Button disabled={!owner} variant="contained" size="small" startIcon={<Delete />} onClick={onRemove}>
삭제
</Button>
</Grid>
</Grid>
</>
);
};
ModifyBoardForm.propTypes = {
rowData: PropTypes.object.isRequired,
handleModalSave: PropTypes.func.isRequired,
handleNewBoard: PropTypes.func.isRequired,
setOpen: PropTypes.func.isRequired,
owner: PropTypes.bool.isRequired
};
export default ModifyBoardForm;

@ -0,0 +1,136 @@
import { useMemo, useRef, useState } from 'react';
import { useAlert } from 'react-alert';
// material-ui
import { Button, Divider, Grid, TextField } from '@mui/material';
// assets
// berry ui
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
// project imports
import { List, Save } from '@mui/icons-material';
import PropTypes from 'prop-types';
const BoardForm = (props) => {
// eslint-disable-next-line react/prop-types
const { setOpen, handleModalSave, rowData = {} } = props;
const alert = useAlert();
const quillRef = useRef();
const [subject, setSubject] = useState('');
const [contents, setContents] = useState('');
const [pass, setPass] = useState();
const onList = () => {
setOpen(false);
};
const onSave = () => {
// TODO : validation check
const saveData = {
ciRef: rowData.ciRef,
ciStep: rowData.ciStep,
ciRevel: rowData.ciRevel,
ciTitle: subject,
ciContents: contents,
ciPass: pass
};
handleModalSave('SAVE', saveData);
};
const modules = useMemo(
() => ({
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[{ size: ['small', false, 'large', 'huge'] }, { color: [] }],
[{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }, { align: [] }]
// ['image', 'video']
]
}
}),
[]
);
return (
<>
<Grid mt={1}>
<Grid container spacing={1} item xs={12} mb={1}>
<Grid item sm={3}>
<TextField size="small" disabled label="작성자" value={rowData.ciName} fullWidth />
</Grid>
<Grid item sm={3}>
<TextField size="small" disabled label="등록일" value={rowData.ciNalja} fullWidth />
</Grid>
<Grid item sm={3}>
<TextField size="small" disabled label="글번호" value={rowData.ciCode} fullWidth />
</Grid>
<Grid item sm={3}>
<TextField size="small" disabled label="조회수" value={rowData.ciHit} fullWidth />
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={2}>
<Grid item sm={12}>
<TextField size="small" required label="제목" value={subject} onChange={(e) => setSubject(e.target.value)} fullWidth />
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={2}>
<Grid item xs={12}>
<ReactQuill
ref={(element) => {
if (element !== null) {
quillRef.current = element;
}
}}
value={contents}
onChange={setContents}
modules={modules}
theme="snow"
placeholder="내용을 입력해주세요."
/>
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={2}>
<Grid item sm={12}>
<TextField
size="small"
type="password"
required
label="비밀번호"
value={pass}
onChange={(e) => setPass(e.target.value)}
fullWidth
/>
</Grid>
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mt={1}>
<Grid item xs={12}>
<Divider />
</Grid>
</Grid>
<Grid item container spacing={0.5} xs={12} mt={1}>
<Grid item>
<Button variant="contained" size="small" startIcon={<List />} onClick={onList}>
목록
</Button>
</Grid>
<Grid item style={{ marginLeft: 'auto' }}>
<Button variant="contained" size="small" startIcon={<Save />} onClick={onSave}>
저장
</Button>
</Grid>
</Grid>
</>
);
};
BoardForm.propTypes = {
rowData: PropTypes.object.isRequired,
handleModalSave: PropTypes.func.isRequired,
setOpen: PropTypes.func.isRequired
};
export default BoardForm;

@ -1,152 +0,0 @@
import { useEffect, useState } from 'react';
// material-ui
import { Button, Divider, Grid, InputAdornment, 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/MuiDataGrid';
import { findUsers } from 'apis/user';
import CmmModal from '../../cmm/CmmModal';
import UserManagerForm from './UserManagerForm';
import { removePublicBoard, savePublicBoard } from 'apis/public';
const UserManager = () => {
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
});
// state
const [open, setOpen] = useState(false);
const [selectedRow, setSelectedRow] = useState({});
const [create, setCreate] = useState(false);
const [title, setTitle] = useState();
const columns = [
{ headerName: '게시판코드', field: 'ciCode' },
{ headerName: '글번호', field: 'ciContentno' },
{ headerName: '제목', field: 'ciTitle', editable: true },
{ headerName: '사용자ID', field: 'ciId' },
{ headerName: '사용자 비번', field: 'ciPwd' }
];
const handleSearch = async (event) => {
if (event.type === 'keydown' && event.key === 'Enter') {
const newString = event?.target.value;
setSearchTxt(newString);
}
};
const search = () => {
const params = {
page: rowsState.page,
size: rowsState.pageSize
};
findUsers(params).then((response) => {
if (response && response.data) {
setTotalCount(response.count);
setRowsState((prevState) => ({ ...prevState, rows: response.data }));
}
});
};
useEffect(() => {
search();
}, [rowsState.page, rowsState.pageSize, category, searchTxt]); // rowsState.page, rowsState.pageSize, rowsState.rows]);
// model
const submitPublicBoard = (type, payload) => {
switch (type) {
case 'SAVE':
savePublicBoard(payload).then(() => {
search();
setOpen(false);
}); // .then((res) => {
break;
case 'DELETE':
removePublicBoard(payload).then(() => {
search();
setOpen(false);
}); // .then((res) => {
break;
default:
}
};
//
const handleCreate = () => {
setSelectedRow({});
setTitle('공지사항 등록');
setCreate(true);
setOpen(true);
};
return (
<MainCard>
<Grid container spacing={2} alignItems="center">
<Grid item xs={12} lg={6}>
<Grid container spacing={1}>
<Grid item>
<Select id="category" name="reviewYear" defaultValue="ciTitle" onChange={(e) => setCategory(e.target.value)}>
<MenuItem key="1" value="ciTitle">
이름
</MenuItem>
<MenuItem key="2" value="ciName">
아이디
</MenuItem>
</Select>
</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>
<Button variant="contained" size="small" onClick={handleCreate}>
평가 등록
</Button>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Divider />
</Grid>
<Grid item xs={12}>
<Divider />
</Grid>
<MuiDataGrid
columns={columns}
rowsState={rowsState}
totalCount={totalCount}
setRowsState={setRowsState}
// handleCellClick={handleOnCellClick}
/>
<CmmModal isBackdrop title={title} open={open} setOpen={setOpen}>
<UserManagerForm create={create} setOpen={setOpen} handleModalSave={submitPublicBoard} {...selectedRow} />
</CmmModal>
</MainCard>
);
};
export default UserManager;

@ -1,226 +0,0 @@
import { useMemo, useRef, useState } from 'react';
import { useAlert } from 'react-alert';
// material-ui
import { Button, FormControl, Grid, MenuItem, Select, TextField } from '@mui/material';
// assets
// berry ui
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
// project imports
import InputLabel from 'ui-component/extended/Form/InputLabel';
import { Delete, List, Save } from '@mui/icons-material';
import { fileDownload } from '../../../apis/common';
import FileForm from 'views/cmm/FileForm';
const PublicBoardForm = (props) => {
// eslint-disable-next-line react/prop-types
const { create, inCode, inDept, inTitle, inHit, inName, inNalja, inFilename, inContents, setOpen, handleModalSave } = props;
const alert = useAlert();
const quillRef = useRef();
const [dept, setDept] = useState(inDept || '주정차위반');
const [subject, setSubject] = useState(inTitle || '');
const [contents, setContents] = useState(inContents || '');
const [filesInfo, setFilesInfo] = useState();
const [selectedFile, setSelectedFile] = useState(inFilename || ''); //
// const [fileData, setFileData] = useState();
const onList = () => {
setOpen(false);
};
const onSave = () => {
// TODO : validation check
const formData = new FormData();
formData.append('inCode', inCode ?? '');
formData.append('inTitle', subject);
formData.append('inDept', dept);
formData.append('inContents', contents);
formData.append('inFilename', selectedFile ?? '');
if (filesInfo && filesInfo.length > 0) {
// eslint-disable-next-line no-plusplus
for (let i = 0; i < filesInfo.length; i++) formData.append('files', filesInfo[i]);
}
handleModalSave('SAVE', formData);
};
const onRemove = () => {
handleModalSave('DELETE', inCode);
};
const imageHandler = () => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = async () => {
if (input.files) {
const file = input.files[0];
const formData = new FormData();
formData.append('image', file);
console.log(formData);
// input
input.onchange = async () => {
const file = input.files;
if (file !== null) {
formData.append('image', file[0]);
try {
//
// const res = await axios.get('/');
//
const url = '/Users/minuk/Pictures/test.png';
//
const range = quillRef.current?.getEditor().getSelection()?.index;
if (range !== null && range !== undefined) {
const quill = quillRef.current?.getEditor();
quill?.setSelection(range, 1);
quill?.clipboard.dangerouslyPasteHTML(range, `<img src=${url} alt="이미지 태그가 삽입됩니다." />`);
}
} catch (error) {
console.log(error);
}
}
};
}
};
};
const modules = useMemo(
() => ({
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[{ size: ['small', false, 'large', 'huge'] }, { color: [] }],
[{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }, { align: [] }]
// ['image', 'video']
],
handlers: {
image: imageHandler
}
}
}),
[]
);
const onChangeFile = (file) => {
setSelectedFile(file.name);
setFilesInfo([file]);
};
// const onChangeFile = (e) => {
// setSelectedFile(e.target.files[0].name);
// setFilesInfo(e.target.files);
// };
const handleFileDownload = () => {
if (!inFilename) {
alert.show('등록된 파일이 없습니다.');
return;
}
fileDownload(inCode, inFilename, alert).then(() => {});
};
return (
<>
<Grid mt={2}>
<Grid container spacing={1} item xs={12} mb={1}>
<Grid item xs={12} sm={6}>
<TextField size="small" required label="제목" value={subject} onChange={(e) => setSubject(e.target.value)} fullWidth />
</Grid>
<Grid item xs={12} sm={3}>
<FormControl fullWidth>
<InputLabel required>진술유형</InputLabel>
<Select
size="small"
disabled={!create}
label="업무구분"
required
value={dept}
onChange={(e) => setDept(e.target.value)}
fullWidth
>
<MenuItem value="주정차위반">주정차위반</MenuItem>
<MenuItem value="장애인위반">장애인위반</MenuItem>
<MenuItem value="기타">기타</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={12} sm={3}>
<TextField size="small" disabled label="작성자" value={inName} fullWidth />
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mb={1}>
<Grid item xs={12} sm={3}>
<TextField size="small" disabled label="등록일" value={inNalja} fullWidth />
</Grid>
<Grid item xs={12} sm={3}>
<TextField size="small" disabled label="번호" value={inCode} fullWidth />
</Grid>
<Grid item xs={12} sm={3}>
<TextField size="small" disabled label="조회수" value={inHit} fullWidth />
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mb={1}>
<Grid item xs={12}>
<ReactQuill
ref={(element) => {
if (element !== null) {
quillRef.current = element;
}
}}
value={contents}
onChange={setContents}
modules={modules}
theme="snow"
placeholder="내용을 입력해주세요."
/>
</Grid>
</Grid>
<Grid container spacing={1} item xs={12} mb={1}>
<Grid item sm={6}>
<FileForm
isDownload={inFilename}
labelName="첨부파일"
savedFilename={inFilename}
selectedFile={selectedFile}
handleChangeFile={onChangeFile}
handleFileDownload={handleFileDownload}
alert={alert}
/>
</Grid>
</Grid>
</Grid>
<Grid item container spacing={0.5} xs={12}>
<Grid item>
<Button variant="contained" size="small" startIcon={<List />} onClick={onList}>
목록
</Button>
</Grid>
<Grid item>
<Button variant="contained" size="small" startIcon={<Save />} onClick={onSave}>
저장
</Button>
</Grid>
{!create && (
<Grid item>
<Button variant="contained" size="small" startIcon={<Delete />} onClick={onDelete}>
삭제
</Button>
</Grid>
)}
</Grid>
</>
);
};
export default PublicBoardForm;

@ -12,7 +12,7 @@ import PropTypes from 'prop-types';
const UserManagementForm = (props) => {
// eslint-disable-next-line react/prop-types
const { create, setOpen, handleModalSave, teams = [], accesstypes = [], rowData } = props;
const { create, setOpen, handleModalSave, teams = [], accesstypes = [], rowData = {} } = props;
console.log(rowData);
const [userid, setUserid] = useState(rowData?.userid || '');
const [passwd, setPasswd] = useState(rowData?.passwd || '');
@ -156,6 +156,10 @@ const UserManagementForm = (props) => {
};
UserManagementForm.propTypes = {
rowData: PropTypes.object.isRequired,
handleModalSave: PropTypes.func.isRequired
handleModalSave: PropTypes.func.isRequired,
create: PropTypes.bool.isRequired,
setOpen: PropTypes.func.isRequired,
accesstypes: PropTypes.array.isRequired,
teams: PropTypes.array.isRequired
};
export default UserManagementForm;

Loading…
Cancel
Save