464 lines
16 KiB
JavaScript
464 lines
16 KiB
JavaScript
'use client'
|
|
|
|
import { useMessage } from '@/hooks/useMessage'
|
|
import { sessionStore } from '@/store/commonAtom'
|
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
|
import QnaFileUploader from '@/components/community/modal/QnaFileUploader'
|
|
import { useContext, useEffect, useRef, useState } from 'react'
|
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
|
import Select from 'react-select'
|
|
import dayjs from 'dayjs'
|
|
import { useSwal } from '@/hooks/useSwal'
|
|
import { QcastContext } from '@/app/QcastProvider'
|
|
import { useAxios } from '@/hooks/useAxios'
|
|
import { globalLocaleStore } from '@/store/localeAtom'
|
|
import { e } from 'mathjs'
|
|
import { set } from 'react-hook-form'
|
|
|
|
|
|
export default function QnaRegModal({ setOpen, setReload, searchValue, selectPageBlock }) {
|
|
const { getMessage } = useMessage()
|
|
const [fileList, setFileList] = useState([])
|
|
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
|
const [files, setFiles] = useState([])
|
|
//const [qnaData, setQnaData] = useState([])
|
|
const [qnaData, setQnaData] = useState({})
|
|
const [closeMdFlg, setCloseMdFlg] = useState(true)
|
|
const [closeSmFlg, setCloseSmFlg] = useState(true)
|
|
const [hideSmFlg, setHideSmFlg] = useState(false)
|
|
const qnaTypeLgCodeRef = useRef(null)
|
|
const qnaTypeMdCodeRef = useRef(null)
|
|
const qnaTypeSmCodeRef = useRef(null)
|
|
const qstMail = useRef(null);
|
|
const regUserNmRef = useRef(null)
|
|
const regUserTelNoRef = useRef(null)
|
|
const titleRef = useRef(null)
|
|
const contentsRef = useRef(null)
|
|
const { findCommonCode } = useCommonCode()
|
|
const [qnaTypeLgCodeList, setQnaTypeLgCodeList] = useState([])
|
|
const [qnaTypeMdCodeList, setQnaTypeMdCodeList] = useState([])
|
|
const [qnaTypeSmCodeList, setQnaTypeSmCodeList] = useState([])
|
|
const [phoneNumber, setPhoneNumber] = useState("");
|
|
const { swalFire } = useSwal()
|
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
|
const [isBtnDisable, setIsBtnDisable] = useState(false);
|
|
const { promiseGet, post, promisePost } = useAxios(globalLocaleState)
|
|
|
|
useEffect(() => {
|
|
console.log('qnaData updated:', qnaData);
|
|
}, [qnaData]);
|
|
|
|
let fileCheck = false;
|
|
const regPhoneNumber = (e) => {
|
|
const result = e.target.value
|
|
.replace(/[^0-9.]/g, "")
|
|
//.replace(/^(\d{0,3})(\d{0,4})(\d{0,4})$/g, "$1-$2-$3")
|
|
//.replace(/(-{1,2})$/g, "");
|
|
//setPhoneNumber(result);
|
|
|
|
setQnaData({...qnaData, regUserTelNo: result })
|
|
}
|
|
|
|
const fileUploadProps = {
|
|
uploadFiles: files,
|
|
setUploadFiles: setFiles,
|
|
|
|
}
|
|
|
|
// const fileSave = (qnaData, fileUploadProps) => {
|
|
// return qnaData.files.push(fileUploadProps.uploadFiles)
|
|
// }
|
|
|
|
const initQnaReg = async () => {
|
|
|
|
|
|
qstMail.current.value = ''
|
|
regUserNmRef.current.value = ''
|
|
regUserTelNoRef.current.value = ''
|
|
qnaTypeLgCodeRef.current.setValue();
|
|
qnaTypeMdCodeRef.current.setValue();
|
|
qnaTypeSmCodeRef.current?.setValue();
|
|
titleRef.current.value = ''
|
|
contentsRef.current.value = ''
|
|
|
|
//setQnaData([])
|
|
|
|
setQnaData({
|
|
compCd: "5200",
|
|
siteTpCd: "QC",
|
|
schNoticeClsCd: "QNA",
|
|
regId: sessionState?.userId || '',
|
|
storeId: sessionState?.storeId || '',
|
|
qstMail: sessionState?.email || '',
|
|
qnaClsLrgCd: '',
|
|
qnaClsMidCd: '',
|
|
qnaClsSmlCd: ''
|
|
});
|
|
|
|
const codeL = findCommonCode(204200)
|
|
if (codeL != null) {
|
|
setQnaTypeLgCodeList(codeL)
|
|
}
|
|
setIsGlobalLoading(false)
|
|
setIsBtnDisable(false);
|
|
}
|
|
const onChangeQnaTypeL = (e) => {
|
|
if(e === undefined || e === null) return;
|
|
const codeM = findCommonCode(204300)
|
|
if (codeM != null) {
|
|
|
|
let codeList = []
|
|
|
|
codeM.map((item) => {
|
|
|
|
if(item.clRefChr1 === e.clCode) {
|
|
codeList.push(item);
|
|
|
|
}
|
|
})
|
|
setQnaTypeMdCodeList(codeList)
|
|
setQnaData({ ...qnaData, qnaClsLrgCd:e.clCode})
|
|
setCloseMdFlg(false)
|
|
qnaTypeMdCodeRef.current.setValue();
|
|
qnaTypeSmCodeRef.current?.setValue();
|
|
}
|
|
|
|
}
|
|
const onChangeQnaTypeM = (e) => {
|
|
if (!e?.clCode) return;
|
|
|
|
// 중분류 코드 업데이트
|
|
setQnaData(prevState => ({
|
|
...prevState,
|
|
qnaClsMidCd: e.clCode,
|
|
// 소분류는 초기화 (새로 선택하도록)
|
|
qnaClsSmlCd: ''
|
|
}));
|
|
|
|
// 소분류 코드 목록 설정
|
|
const codeS = findCommonCode(204400);
|
|
if (codeS) {
|
|
const filteredCodeList = codeS.filter(item => item.clRefChr1 === e.clCode);
|
|
setQnaTypeSmCodeList(filteredCodeList);
|
|
|
|
// 소분류가 있으면 초기화, 없으면 숨김
|
|
const hasSubCategories = filteredCodeList.length > 0;
|
|
setCloseSmFlg(!hasSubCategories);
|
|
setHideSmFlg(!hasSubCategories);
|
|
} else {
|
|
setHideSmFlg(true)
|
|
}
|
|
|
|
// 소분류 선택기 초기화
|
|
qnaTypeSmCodeRef.current?.setValue();
|
|
};
|
|
|
|
|
|
const onChangeQnaTypeS = (e) => {
|
|
if (!e?.clCode) return;
|
|
|
|
setQnaData(prevState => ({
|
|
...prevState,
|
|
qnaClsSmlCd: e.clCode
|
|
}));
|
|
}
|
|
|
|
const onFileSave = () => {
|
|
const formData= []
|
|
if(fileUploadProps.uploadFiles.length === 0) return;
|
|
if(!fileCheck) return;
|
|
|
|
fileUploadProps.uploadFiles.forEach((file) => {
|
|
//console.log("file::::::::",file)
|
|
formData.push(file)
|
|
|
|
})
|
|
setQnaData({ ...qnaData, files:formData })
|
|
fileCheck = false;
|
|
}
|
|
|
|
const isValidEmail = (email) => {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
return emailRegex.test(email);
|
|
};
|
|
|
|
const isEmpty = (value) => {
|
|
return value === null || value === undefined || value.trim() === "";
|
|
};
|
|
|
|
|
|
const handleQnaSubmit = async () => {
|
|
//필수 체크
|
|
|
|
//console.log("1::::",qnaData)
|
|
|
|
|
|
let regUserNm = qnaData?.regUserNm??'';
|
|
|
|
if (!isValidEmail(qnaData.qstMail)) {
|
|
qstMail.current.focus();
|
|
swalFire({
|
|
title: getMessage('qna.reg.alert.require.qstMail'),
|
|
icon: 'warning',
|
|
});
|
|
return;
|
|
}
|
|
|
|
|
|
if (isEmpty(regUserNm)) {
|
|
regUserNmRef.current.value = '';
|
|
regUserNmRef.current.focus()
|
|
swalFire({
|
|
title: getMessage('qna.reg.alert.require.regUserNm'),
|
|
icon: 'warning',
|
|
})
|
|
return false
|
|
}
|
|
|
|
let qnaClsLrgCd = qnaData?.qnaClsLrgCd??'';
|
|
let qnaClsMidCd = qnaData?.qnaClsMidCd??'';
|
|
|
|
if (isEmpty(qnaClsLrgCd) || isEmpty(qnaClsMidCd) ) {
|
|
(isEmpty(qnaClsLrgCd))?qnaTypeLgCodeRef.current.focus():qnaTypeMdCodeRef.current.focus()
|
|
swalFire({
|
|
title: getMessage('qna.reg.alert.select.type'),
|
|
icon: 'warning',
|
|
})
|
|
return false
|
|
}
|
|
|
|
let title = qnaData?.title??'';
|
|
|
|
if (isEmpty(title)) {
|
|
titleRef.current.value = '';
|
|
titleRef.current.focus()
|
|
swalFire({
|
|
title: getMessage('qna.reg.alert.require.title'),
|
|
icon: 'warning',
|
|
})
|
|
return false
|
|
}
|
|
//console.log("5::::",qnaData)
|
|
let contents = qnaData?.contents??'';
|
|
|
|
if (isEmpty(contents)) {
|
|
contentsRef.current.value = '';
|
|
contentsRef.current.focus()
|
|
swalFire({
|
|
title: getMessage('qna.reg.alert.require.contents'),
|
|
icon: 'warning',
|
|
})
|
|
return false
|
|
}
|
|
|
|
const formData = new FormData()
|
|
if(qnaData?.files?.length > 0) {
|
|
qnaData?.files.forEach((file) => {
|
|
formData.append('files', file.data)
|
|
})
|
|
}
|
|
formData.append("compCd", qnaData.compCd)
|
|
formData.append("siteTpCd", qnaData.siteTpCd)
|
|
formData.append("qnaClsLrgCd", qnaData.qnaClsLrgCd)
|
|
formData.append("qnaClsMidCd", qnaData.qnaClsMidCd)
|
|
formData.append("qnaClsSmlCd", qnaData.qnaClsSmlCd)
|
|
formData.append("title", qnaData.title)
|
|
formData.append("contents", qnaData.contents)
|
|
formData.append("regId", qnaData.regId)
|
|
formData.append("storeId", qnaData.storeId)
|
|
formData.append("regUserNm", qnaData.regUserNm)
|
|
formData.append("regUserTelNo", qnaData.regUserTelNo)
|
|
formData.append("qstMail", qnaData.qstMail)
|
|
formData.append("schNoticeClsCd", qnaData.schNoticeClsCd)
|
|
|
|
|
|
|
|
//console.log(Array.from(formData));
|
|
|
|
swalFire({
|
|
html: getMessage('qna.reg.confirm.save'),
|
|
type: 'confirm',
|
|
confirmFn: async () => {
|
|
|
|
setIsBtnDisable(true);
|
|
setIsGlobalLoading(true)
|
|
|
|
try {
|
|
|
|
const apiUrl = 'api/board'
|
|
//console.log("7::::",qnaData)
|
|
await post({ url: `${apiUrl}/saveQna`, data: formData }).then((res) => {
|
|
if (res?.result.code === 200) {
|
|
//qnaData.newFileList = []
|
|
setIsGlobalLoading(false)
|
|
swalFire({ text: getMessage('qna.reg.alert.save'), type: 'alert' })
|
|
setOpen(false)
|
|
setReload(searchValue, selectPageBlock);
|
|
}else{
|
|
setIsGlobalLoading(false)
|
|
swalFire({ text: getMessage('qna.reg.alert.saveFail'), type: 'alert', icon: 'error' })
|
|
console.error('error::::::::::::', res)
|
|
}
|
|
|
|
setIsBtnDisable(false)
|
|
})
|
|
} catch (e) {
|
|
setIsGlobalLoading(false)
|
|
setIsBtnDisable(false);
|
|
console.error('error::::::::::::', e.message)
|
|
swalFire({ text: e.message, type: 'alert' , icon: 'error'})
|
|
console.error('error::::::::::::', e.message)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
useEffect(() => {
|
|
initQnaReg()
|
|
},[])
|
|
|
|
// useEffect(() => {
|
|
// onFileSave()
|
|
//
|
|
// }, [onFileSave])
|
|
return (
|
|
<div className="modal-popup">
|
|
<div className="modal-dialog big">
|
|
<div className="modal-content">
|
|
<div className="modal-header">
|
|
<h1 className="title">{getMessage('qna.title')}</h1>
|
|
<button className="modal-close"
|
|
onClick={() => {
|
|
setOpen(false)
|
|
}}>{getMessage('board.sub.btn.close')}</button>
|
|
</div>
|
|
<div className="modal-body">
|
|
<div className="modal-body-inner">
|
|
<div className="design-request-table">
|
|
<div className="common-table">
|
|
<table>
|
|
<colgroup>
|
|
<col style={{ width: '100px' }} />
|
|
<col />
|
|
<col style={{ width: '120px' }} />
|
|
<col />
|
|
<col style={{ width: '150px' }} />
|
|
<col />
|
|
</colgroup>
|
|
<tbody>
|
|
<tr>
|
|
<th>{getMessage('qna.list.header.regNm')}</th>
|
|
<td><input type="text" className="input-light" value={sessionState?.userNm || ''} readOnly /></td>
|
|
<th>E-Mail<span className="red">*</span></th>
|
|
<td ><input type="text" className="input-light" required
|
|
ref={qstMail}
|
|
value={qnaData?.qstMail || ''}
|
|
onChange={(e) => setQnaData({...qnaData, qstMail: e.target.value })}
|
|
onBlur={(e) => setQnaData({ ...qnaData, qstMail: e.target.value })} />
|
|
</td>
|
|
|
|
<th>{getMessage('qna.reg.header.regDt')}</th>
|
|
<td>{dayjs(new Date()).format('YYYY-MM-DD')}</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Customer</th>
|
|
<td><input type="text" className="input-light" value={sessionState?.custNm || ''} readOnly /></td>
|
|
<th>{getMessage('qna.reg.header.regUserNm')}<span className="red">*</span></th>
|
|
<td ><input type="text" className="input-light" required
|
|
ref={regUserNmRef}
|
|
value={qnaData?.regUserNm || '' }
|
|
onChange={(e) => setQnaData({...qnaData, regUserNm: e.target.value })}
|
|
onBlur={(e) => setQnaData({ ...qnaData, regUserNm: e.target.value })} /> </td>
|
|
<th>{getMessage('qna.reg.header.regUserTelNo')}</th>
|
|
<td ><input type="text" className="input-light"
|
|
ref={regUserTelNoRef}
|
|
maxLength={13}
|
|
value={qnaData?.regUserTelNo || '' }
|
|
onChange={regPhoneNumber}
|
|
/></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div className="design-request-grid">
|
|
<div className="design-request-count">
|
|
<div className="design-request-grid-tit">{getMessage("qna.reg.header.type")}, {getMessage("qna.reg.header.title")} <span
|
|
className="red">*</span></div>
|
|
</div>
|
|
<div className="flx-box one-on-one">
|
|
<div className="select-wrap mr5" >
|
|
<Select name="" ref={qnaTypeLgCodeRef}
|
|
options={qnaTypeLgCodeList}
|
|
placeholder="Select"
|
|
onChange={(e) => onChangeQnaTypeL(e)}
|
|
getOptionLabel={(x) => x.clCodeNm}
|
|
getOptionValue={(x) => x.clCode}
|
|
isClearable={false}
|
|
isSearchable={false}
|
|
|
|
/>
|
|
|
|
</div>
|
|
<div className="select-wrap mr5" >
|
|
<Select name="" ref={qnaTypeMdCodeRef}
|
|
options={qnaTypeMdCodeList}
|
|
placeholder="Select"
|
|
onChange={(e) => onChangeQnaTypeM(e)}
|
|
getOptionLabel={(x) => x.clCodeNm}
|
|
getOptionValue={(x) => x.clCode}
|
|
isClearable={false}
|
|
isSearchable={false}
|
|
isDisabled={closeMdFlg}
|
|
defaultValue={''}
|
|
/>
|
|
</div>
|
|
<div className="select-wrap" >
|
|
{!hideSmFlg && (
|
|
<Select name="" ref={qnaTypeSmCodeRef}
|
|
options={qnaTypeSmCodeList}
|
|
placeholder="Select"
|
|
onChange={(e) => onChangeQnaTypeS(e)}
|
|
getOptionLabel={(x) => x.clCodeNm}
|
|
getOptionValue={(x) => x.clCode}
|
|
isClearable={false}
|
|
isSearchable={false}
|
|
isDisabled={closeSmFlg}
|
|
/>)}
|
|
</div>
|
|
</div>
|
|
<div className="input-wrap mt5">
|
|
<input type="text" className="input-light" maxLength={200}
|
|
ref = {titleRef}
|
|
value={qnaData?.title || '' }
|
|
onChange={(e) => {setQnaData({ ...qnaData, title: e.target.value })}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="design-request-grid mt15">
|
|
<div className="design-request-count">
|
|
<div className="design-request-grid-tit">{getMessage("qna.reg.header.contents")} <span className="red">*</span></div>
|
|
</div>
|
|
<div>
|
|
<textarea className="textarea-form" name="" id="" maxLength={4000}
|
|
ref={contentsRef}
|
|
value={qnaData?.contents || '' }
|
|
onChange={(e) => {setQnaData({ ...qnaData, contents: e.target.value })}} ></textarea>
|
|
</div>
|
|
</div>
|
|
<QnaFileUploader {...fileUploadProps} qnaData={qnaData} setQnaData={setQnaData} />
|
|
|
|
</div>
|
|
<div className="footer-btn-wrap">
|
|
{isBtnDisable === false && <button className="btn-origin navy mr5" onClick={handleQnaSubmit}>{getMessage("qna.reg.header.save")}</button>}
|
|
<button className="btn-origin grey" onClick={() => {
|
|
setOpen(false)
|
|
}}>{getMessage("board.sub.btn.close")}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
} |