281 lines
11 KiB
JavaScript
281 lines
11 KiB
JavaScript
import React, {useState, useEffect, useRef, useCallback} from 'react';
|
|
import {Link, useNavigate, useLocation, useParams} from 'react-router-dom';
|
|
import Modal from "react-bootstrap/Modal";
|
|
|
|
import * as EgovNet from 'api/egovFetch';
|
|
import URL from 'constants/url';
|
|
import CODE from 'constants/code';
|
|
|
|
import {default as EgovLeftNav} from 'components/leftmenu/EgovLeftNavAdmin';
|
|
import EgovRadioButtonGroup from 'components/EgovRadioButtonGroup';
|
|
import {Form} from "react-bootstrap";
|
|
import RichTextEditor from "../../../components/editor/RichTextEditor";
|
|
import AttachFile from "../../../components/file/AttachFile";
|
|
|
|
|
|
function AdminPostMgtEdit({props, reloadFunction}) {
|
|
console.group("AdminPostMgtEdit");
|
|
console.log("[Start] AdminPostMgtEdit ------------------------------");
|
|
console.log("AdminPostMgtEdit [props] : ", props);
|
|
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
const checkRef = useRef([]);
|
|
|
|
console.log("AdminPostMgtEdit [location] : ", location);
|
|
|
|
let item = null;
|
|
item = props;
|
|
console.log("@@@ item : " + JSON.stringify(item));
|
|
|
|
const [modeInfo, setModeInfo] = useState(props.selectedBbsSeq ? {mode: CODE.MODE_CREATE} : {mode: props.mode});
|
|
const [boardDetail, setBoardDetail] = useState({});
|
|
console.log("@@@ mode : " + modeInfo.mode);
|
|
|
|
const [categoryList, setCategoryList] = useState([]);
|
|
|
|
const retrieveList = useCallback(() => {
|
|
const retrieveListURL = '/admin/boards/posts/get-category-and-file-list';
|
|
|
|
const requestOptions = {
|
|
method: "POST",
|
|
headers: {
|
|
'Content-type': 'application/json',
|
|
},
|
|
body: JSON.stringify(item ? item : {})
|
|
}
|
|
|
|
EgovNet.requestFetch(retrieveListURL,
|
|
requestOptions,
|
|
(resp) => {
|
|
setCategoryList(resp.result.categoryList);
|
|
if (resp.result.files) {
|
|
setServerFiles(resp.result.files);
|
|
console.log("@@@ files : " + JSON.stringify(resp.result.files));
|
|
}
|
|
console.log("@@@ categoryList : " + JSON.stringify(resp.result.categoryList));
|
|
},
|
|
function (resp) {
|
|
console.log("err response : ", resp);
|
|
}
|
|
);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
retrieveList();
|
|
initMode();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
const initMode = () => {
|
|
if (modeInfo.mode === CODE.MODE_MODIFY) {
|
|
setBoardDetail(item);
|
|
setSelectedBbsSeq(props?.bbsSeq);
|
|
}
|
|
}
|
|
|
|
function editPost(e) {
|
|
const formData = new FormData();
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
const form = e.target;
|
|
formData.append('fixedYn', defaultFixedYn);
|
|
formData.append('secretYn', defaultSecretYn);
|
|
formData.append('bbsId', form.bbsId.value);
|
|
formData.append('bbsSeq', selectedBbsSeq ? selectedBbsSeq : props.selectedBbsSeq);
|
|
formData.append('bbsContTitle', form.bbsContTitle.value);
|
|
formData.append('bbsContents', text);
|
|
//첨부파일
|
|
if (files) {
|
|
for (let i = 0; i < files.length; i++) {
|
|
if (files[i].seq) {
|
|
// 살아남은 file의 seq 목록 서버로 보내면 서버가 알아서 기존파일을 정리해준다.
|
|
formData.append("survivingFiles", files[i].seq);
|
|
continue;
|
|
}
|
|
formData.append("files", files[i]);
|
|
}
|
|
}
|
|
if (modeInfo.mode === CODE.MODE_MODIFY) {
|
|
formData.append('bbsContSeq', props.bbsContSeq);
|
|
}
|
|
EgovNet.requestFetch(
|
|
'/admin/boards/posts/post-mgt',
|
|
{
|
|
method: "PUT",
|
|
body: formData
|
|
},
|
|
(resp) => {
|
|
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
|
|
alert("저장되었습니다.");
|
|
reloadFunction();
|
|
} else if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) {
|
|
console.log("토큰 갱신중.")
|
|
} else {
|
|
alert(resp.result.resultMessage)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
function deletePost(post) {
|
|
if (window.confirm("삭제하시겠습니까?")) {
|
|
EgovNet.requestFetch(
|
|
'/admin/boards/posts/post-mgt',
|
|
{
|
|
method: "DELETE",
|
|
headers: {
|
|
'Content-type': 'application/json'
|
|
},
|
|
body: JSON.stringify(post)
|
|
},
|
|
(resp) => {
|
|
if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) {
|
|
reloadFunction();
|
|
} else if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) {
|
|
console.log("토큰 갱신중.")
|
|
} else {
|
|
alert(resp.result.resultMessage)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
console.log("------------------------------AdminPostMgtEdit [End]");
|
|
console.groupEnd("AdminPostMgtEdit");
|
|
|
|
const [defaultFixedYn, setDefaultFixedYn] = useState(props?.fixedYn || "N");
|
|
const [defaultSecretYn, setDefaultSecretYn] = useState(props?.secretYn || "N");
|
|
const [text, setText] = useState(props?.bbsContents);
|
|
const [selectedBbsSeq, setSelectedBbsSeq] = useState(null);
|
|
|
|
const handleSelectChange = (e) => {
|
|
const selectedBbsSeq = e.target.value;
|
|
setSelectedBbsSeq(selectedBbsSeq);
|
|
}
|
|
|
|
const fileTypes = ["JPG", "PNG", "GIF", "PDF", "HWP", "HWPX", "ZIP", "JPEG", "MP4", "TXT"];
|
|
const [serverFiles, setServerFiles] = useState([]);
|
|
const [files, setFiles] = useState([]);
|
|
|
|
// 첨부된 file을 삭제하는 요청
|
|
const deleteFile = (fileSeq) => {
|
|
const deleteFileURL = `/contents/api/popup-manage/file/${fileSeq}`;
|
|
|
|
const requestOptions = {
|
|
method: "DELETE",
|
|
headers: {
|
|
'Content-type': 'application/json',
|
|
}
|
|
}
|
|
|
|
EgovNet.requestFetch(deleteFileURL,
|
|
requestOptions,
|
|
(resp) => {
|
|
}
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<style>
|
|
{`
|
|
.modal-dialog {
|
|
max-width: 50%;
|
|
}
|
|
`}
|
|
</style>
|
|
{/* <!-- 본문 --> */}
|
|
<Modal.Header closeButton>
|
|
<Modal.Title>
|
|
{modeInfo.mode === CODE.MODE_CREATE && '글 작성'}
|
|
{modeInfo.mode === CODE.MODE_MODIFY && '글 수정'}
|
|
</Modal.Title>
|
|
</Modal.Header>
|
|
|
|
<Modal.Body>
|
|
<div className="board_view2">
|
|
<Form onSubmit={(e) => {
|
|
editPost(e)
|
|
}} noValidate>
|
|
<dl>
|
|
<dt><label htmlFor="siteTitle">상단고정</label><span className="req">필수</span></dt>
|
|
<dd>
|
|
<Form.Check
|
|
type="checkbox"
|
|
id="fixedYnCheckbox"
|
|
label="상단고정"
|
|
checked={defaultFixedYn === 'Y'}
|
|
onChange={(e) => setDefaultFixedYn(e.target.checked ? 'Y' : 'N')}
|
|
/>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><label htmlFor="siteTitle">비밀글</label><span className="req">필수</span></dt>
|
|
<dd>
|
|
<Form.Check
|
|
type="checkbox"
|
|
id="secretYnCheckbox"
|
|
label="비밀글"
|
|
checked={defaultSecretYn === 'Y'}
|
|
onChange={(e) => setDefaultSecretYn(e.target.checked ? 'Y' : 'N')}
|
|
/>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><label htmlFor="siteTitle">카테고리</label><span className="req">필수</span></dt>
|
|
<dd>
|
|
<Form.Select id="select1" name="bbsId" onChange={handleSelectChange}>
|
|
<option value="">선택</option>
|
|
{categoryList.map((item) => (
|
|
<option key={item.bbsSeq} value={item.bbsSeq}
|
|
selected={props?.mode === CODE.MODE_MODIFY ? item.bbsSeq == props.bbsSeq : item.bbsSeq == props.selectedBbsSeq}>{item.bbsTitle}</option>
|
|
))}
|
|
</Form.Select>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><label htmlFor="siteTitle">제목</label><span className="req">필수</span></dt>
|
|
<dd>
|
|
<Form.Control className="f_input2 w_full" type="text" name="bbsContTitle" placeholder="제목" required
|
|
defaultValue={props?.bbsContTitle}/>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><label htmlFor="fileGrpId">파일</label><span className="req">필수</span></dt>
|
|
<dd>
|
|
<AttachFile name="preDataFile" multiple={true} files={files} setFiles={setFiles} serverFiles={serverFiles} fileTypes={fileTypes} deleteFile={deleteFile}/>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><label htmlFor="contents">내용</label><span className="req">필수</span></dt>
|
|
<dd>
|
|
<RichTextEditor item={text} setText={setText}/>
|
|
</dd>
|
|
</dl>
|
|
|
|
{/* <!-- 버튼영역 --> */}
|
|
<div className="board_btn_area">
|
|
<div className="left_col btn1">
|
|
{modeInfo.mode === CODE.MODE_MODIFY &&
|
|
<button type={"button"} className="btn btn_red_h46 w_100" onClick={() => {
|
|
deletePost(props)
|
|
}}>삭제</button>
|
|
}
|
|
</div>
|
|
|
|
<div className="right_col btn1">
|
|
<button type="submit" className="btn btn_skyblue_h46 w_100">저장</button>
|
|
</div>
|
|
</div>
|
|
{/* <!--// 버튼영역 --> */}
|
|
</Form>
|
|
</div>
|
|
</Modal.Body>
|
|
</>
|
|
|
|
);
|
|
}
|
|
|
|
export default AdminPostMgtEdit; |