[1004] 1:1 문의게시판 추가
This commit is contained in:
parent
37b12b5deb
commit
bbb8bef37d
9
src/app/community/qna/page.jsx
Normal file
9
src/app/community/qna/page.jsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import Qna from '@/components/community/Qna'
|
||||||
|
|
||||||
|
export default async function CommunityQnaPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Qna />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
214
src/components/community/Qna.jsx
Normal file
214
src/components/community/Qna.jsx
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import Link from 'next/link'
|
||||||
|
import Image from 'next/image'
|
||||||
|
|
||||||
|
import Search from '@/components/community/Search'
|
||||||
|
import Pagination from '@/components/community/Pagination'
|
||||||
|
|
||||||
|
import { useContext } from 'react'
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useResetRecoilState, useRecoilValue, useRecoilState } from 'recoil'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
|
||||||
|
import { searchState } from '@/store/boardAtom'
|
||||||
|
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
import QnaBoardDetailModal from '@/components/community/modal/QnaDetailModal'
|
||||||
|
import { sessionStore } from '@/store/commonAtom'
|
||||||
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
|
|
||||||
|
export default function Qna() {
|
||||||
|
const { getMessage } = useMessage()
|
||||||
|
const resetSearch = useResetRecoilState(searchState)
|
||||||
|
const [isInitialized, setIsInitialized] = useState(false)
|
||||||
|
|
||||||
|
//const search = useRecoilValue(searchState)
|
||||||
|
const [searchForm, setSearchForm] = useRecoilState(searchState)
|
||||||
|
const { findCommonCode } = useCommonCode()
|
||||||
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||||
|
const { get } = useAxios()
|
||||||
|
const [boardList, setBoardList] = useState([])
|
||||||
|
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
||||||
|
const [search, setSearch] = useRecoilState(searchState)
|
||||||
|
// 팝업 관련
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
const [modalQnaNo, setModalQnaNo] = useState('')
|
||||||
|
const [modalQnaType, setModalQnaType] = useState('')
|
||||||
|
|
||||||
|
// 목록 조회
|
||||||
|
useEffect(() => {
|
||||||
|
async function fetchData() {
|
||||||
|
setIsGlobalLoading(true)
|
||||||
|
const startRow = (search.currentPage - 1) * search.pageBlock > 0 ? (search.currentPage - 1) * search.pageBlock + 1 : 1
|
||||||
|
const endRow = search.currentPage * search.pageBlock
|
||||||
|
|
||||||
|
const url = `/api/board/list`
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
schNoticeTpCd : 'QC',
|
||||||
|
schNoticeClsCd: 'QNA',
|
||||||
|
compCd : 5200,
|
||||||
|
storeId : sessionState.storeId,
|
||||||
|
loginId : sessionState.userId,
|
||||||
|
schTitle : search.searchValue ? search.searchValue : '',
|
||||||
|
startRow : startRow,
|
||||||
|
endRow : endRow,
|
||||||
|
schMainYn : 'N',
|
||||||
|
siteTpCd : 'QC',
|
||||||
|
})
|
||||||
|
const apiUrl = `${url}?${params.toString()}`
|
||||||
|
|
||||||
|
const resultData = await get({ url: apiUrl })
|
||||||
|
|
||||||
|
if (resultData) {
|
||||||
|
if (resultData.result.code === 200) {
|
||||||
|
if (resultData.data.length > 0) {
|
||||||
|
setBoardList(resultData.data)
|
||||||
|
setSearch({ ...search, totalCount: resultData.data[0].totCnt })
|
||||||
|
} else {
|
||||||
|
setBoardList([])
|
||||||
|
setSearch({ ...search, totalCount: 0 })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert(resultData.result.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setIsGlobalLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchData()
|
||||||
|
}, [search.currentPage, search.searchValue, search.pageBlock, search.searchFlag])
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (search.mainFlag === 'N') {
|
||||||
|
resetSearch()
|
||||||
|
} else {
|
||||||
|
//메인에서 FAQ 조회 왔을때 로딩바 해제
|
||||||
|
setIsGlobalLoading(false)
|
||||||
|
setSearchForm({ ...searchForm, mainFlag: 'N' })
|
||||||
|
}
|
||||||
|
setIsInitialized(true)
|
||||||
|
|
||||||
|
//문의구분코드
|
||||||
|
// const codeL = findCommonCode(204200)
|
||||||
|
// const codeM = findCommonCode(204300)
|
||||||
|
// const codeS = findCommonCode(204400)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (!isInitialized) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const boardType = {
|
||||||
|
boardTitle: getMessage('qna.title'),
|
||||||
|
subTitle: getMessage('qna.sub.title'),
|
||||||
|
clsCode: 'QNA',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="sub-header">
|
||||||
|
<div className="sub-header-inner">
|
||||||
|
<ul className="sub-header-title-wrap">
|
||||||
|
<li className="title-item">
|
||||||
|
<Link className="sub-header-title" href={'#'}>
|
||||||
|
{getMessage('qna.title')}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul className="sub-header-location">
|
||||||
|
<li className="location-item">
|
||||||
|
<span className="home">
|
||||||
|
<Image src="/static/images/main/home_icon.svg" alt="react" width={16} height={16} />
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li className="location-item">
|
||||||
|
<span>{getMessage('header.menus.community')}</span>
|
||||||
|
</li>
|
||||||
|
<li className="location-item">
|
||||||
|
<span>{getMessage('qna.title')}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="sub-content">
|
||||||
|
<div className="sub-content-inner">
|
||||||
|
<div className="sub-table-box">
|
||||||
|
<Search title={boardType.boardTitle} subTitle={boardType.subTitle} isSelectUse={true} clsCode={boardType.clsCode} />
|
||||||
|
{/*<QnaTable clsCode={boardType.clsCode} />*/}
|
||||||
|
<div className="community-table">
|
||||||
|
<table>
|
||||||
|
<colgroup>
|
||||||
|
<col width={100}/>
|
||||||
|
<col width={150}/>
|
||||||
|
<col />
|
||||||
|
<col width={150}/>
|
||||||
|
<col width={150}/>
|
||||||
|
</colgroup>
|
||||||
|
<tbody>
|
||||||
|
{boardList.length > 0 ? (
|
||||||
|
boardList?.map((board) => (
|
||||||
|
<tr
|
||||||
|
key={board.qnaNo}
|
||||||
|
onClick={() => {
|
||||||
|
setOpen(true)
|
||||||
|
setModalQnaNo(board.qnaNo)
|
||||||
|
setModalQnaType("["+board?.qnaClsLrgCd+"/"+board?.qnaClsMidCd+"/"+board?.qnaClsSmlCd+"]")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<td className="al-c">
|
||||||
|
{/* 번호 */}
|
||||||
|
{board.totCnt - board.rowNumber + 1}
|
||||||
|
</td>
|
||||||
|
{/* 답변 */}
|
||||||
|
{board?.answerYn === 'Y'? (<td className="al-c "> {getMessage('qna.list.header.answer.yes')}</td>) : (<td className="al-c org"> {getMessage('qna.list.header.answer.no')}</td>)}
|
||||||
|
<td>
|
||||||
|
<div className="mb5">[{board?.qnaClsLrgCd} / {board?.qnaClsMidCd} / {board?.qnaClsSmlCd}]</div>
|
||||||
|
{/* 제목 */}
|
||||||
|
<div className="text-frame">
|
||||||
|
<div className="text-overflow">{board.title}{board.qstTitle}</div>
|
||||||
|
{board.attachYn === 'Y' && <span className="clip"></span>}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="renewal">
|
||||||
|
{/*{board.uptDt && (*/}
|
||||||
|
{/* <>*/}
|
||||||
|
{/* (<span>{getMessage('board.uptDt')}</span> : {board.uptDt})*/}
|
||||||
|
{/* </>*/}
|
||||||
|
{/*)}*/}
|
||||||
|
{board.regUserNm}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="al-c">
|
||||||
|
{/* 등록일 */}
|
||||||
|
{board.regDt.split(' ')[0]}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<tr>
|
||||||
|
<td colSpan={4} className="al-c">
|
||||||
|
{getMessage('common.message.no.data')}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Pagination />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{open && <QnaBoardDetailModal qnaNo={modalQnaNo} setOpen={setOpen} qnaType = {modalQnaType} />}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -4,10 +4,11 @@ import { searchState } from '@/store/boardAtom'
|
|||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import QnaRegModal from '@/components/community/modal/QnaRegModal'
|
||||||
|
|
||||||
export default function Search({ title = '', subTitle = '', isSelectUse = false }) {
|
export default function Search({ title = '', subTitle = '', isSelectUse = false, clsCode = '' }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
const search = useRecoilValue(searchState)
|
const search = useRecoilValue(searchState)
|
||||||
const [searchForm, setSearchForm] = useRecoilState(searchState)
|
const [searchForm, setSearchForm] = useRecoilState(searchState)
|
||||||
|
|
||||||
@ -32,7 +33,13 @@ export default function Search({ title = '', subTitle = '', isSelectUse = false
|
|||||||
} else {
|
} else {
|
||||||
setSearchView(false)
|
setSearchView(false)
|
||||||
setSearchViewText('')
|
setSearchViewText('')
|
||||||
setSearchForm({ ...searchForm, currentPage: 1, searchValue: '', pageBlock: block, searchFlag: !searchForm.searchFlag })
|
setSearchForm({
|
||||||
|
...searchForm,
|
||||||
|
currentPage: 1,
|
||||||
|
searchValue: '',
|
||||||
|
pageBlock : block,
|
||||||
|
searchFlag : !searchForm.searchFlag,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 조회 후 값 비워주기
|
// 조회 후 값 비워주기
|
||||||
setSearchValue('')
|
setSearchValue('')
|
||||||
@ -57,7 +64,10 @@ export default function Search({ title = '', subTitle = '', isSelectUse = false
|
|||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
value={searchValue}
|
value={searchValue}
|
||||||
/>
|
/>
|
||||||
<button type="button" className="community-search-ico" onClick={() => handleSearch(searchValue, selectPageBlock)}></button>
|
|
||||||
|
<button type="button" className="community-search-ico"
|
||||||
|
onClick={() => handleSearch(searchValue, selectPageBlock)}></button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{searchView && (
|
{searchView && (
|
||||||
<div className="community-search-keyword">
|
<div className="community-search-keyword">
|
||||||
@ -92,6 +102,14 @@ export default function Search({ title = '', subTitle = '', isSelectUse = false
|
|||||||
</div>
|
</div>
|
||||||
{isSelectUse && (
|
{isSelectUse && (
|
||||||
<div className="left-unit-box">
|
<div className="left-unit-box">
|
||||||
|
{clsCode === 'QNA' &&
|
||||||
|
<div>
|
||||||
|
<button className="btn-origin navy mr10"
|
||||||
|
onClick={() => {
|
||||||
|
setOpen(true)
|
||||||
|
}}> {getMessage('qna.sub.btn.inquiry')}</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<div className="select-box" style={{ width: '80px' }}>
|
<div className="select-box" style={{ width: '80px' }}>
|
||||||
<select
|
<select
|
||||||
className="select-light black"
|
className="select-light black"
|
||||||
@ -112,6 +130,7 @@ export default function Search({ title = '', subTitle = '', isSelectUse = false
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{open && <QnaRegModal setOpen={setOpen} setReload={handleSearch} searchValue={searchValue ? searchValue : searchViewText} selectPageBlock = {selectPageBlock}/>}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
127
src/components/community/modal/QnaDetailModal.jsx
Normal file
127
src/components/community/modal/QnaDetailModal.jsx
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
import { handleFileDown } from '@/util/board-utils'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { sessionStore } from '@/store/commonAtom'
|
||||||
|
import { useRecoilState } from 'recoil'
|
||||||
|
|
||||||
|
export default function QnaDetailModal({ qnaNo, setOpen, qnaType }) {
|
||||||
|
const { getMessage } = useMessage()
|
||||||
|
// api 조회 관련
|
||||||
|
const { get } = useAxios()
|
||||||
|
const [boardDetail, setBoardDetail] = useState({})
|
||||||
|
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// 상세 조회
|
||||||
|
const fetchDetail = async (qnaNo) => {
|
||||||
|
const url = `/api/board/detail`
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
noticeNo : qnaNo,
|
||||||
|
qnaNo : qnaNo,
|
||||||
|
schNoticeClsCd: 'QNA',
|
||||||
|
compCd : 5200,
|
||||||
|
loginId : sessionState.userId,
|
||||||
|
langCd : 'JA',
|
||||||
|
})
|
||||||
|
const apiUrl = `${url}?${params.toString()}`
|
||||||
|
|
||||||
|
const resultData = await get({ url: apiUrl })
|
||||||
|
|
||||||
|
if (resultData) {
|
||||||
|
if (resultData.result.code === 200) {
|
||||||
|
const boardDetail = resultData.data
|
||||||
|
setBoardDetail(boardDetail)
|
||||||
|
} else {
|
||||||
|
alert(resultData.result.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchDetail(qnaNo)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div key={qnaNo} className="modal-popup community">
|
||||||
|
<div className="modal-dialog">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="modal-close"
|
||||||
|
onClick={() => {
|
||||||
|
setOpen(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('board.sub.btn.close')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="oneonone-header-wrap">
|
||||||
|
<div className="oneonone-title"> {qnaType} {boardDetail.qstTitle}</div>
|
||||||
|
<div className="oneonone-infor">
|
||||||
|
<div className="profile">{boardDetail.regUserNm}</div>
|
||||||
|
<div className="date">{boardDetail.regDt}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="oneonone-detail">
|
||||||
|
{boardDetail.listFile && (
|
||||||
|
<dl className="community_detail-file-wrap">
|
||||||
|
<dt>{getMessage('qna.detail.sub.fileList')}</dt>
|
||||||
|
{boardDetail.listFile.map((boardFile) => (
|
||||||
|
<dd key={boardFile.encodeFileNo}>
|
||||||
|
<button type="button" className="down" onClick={() => handleFileDown(boardFile.fileNo, 'N')}>
|
||||||
|
{boardFile.srcFileNm}
|
||||||
|
</button>
|
||||||
|
</dd>
|
||||||
|
))}
|
||||||
|
</dl>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className="community_detail-inner"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: boardDetail.qstContents ? boardDetail.qstContents.replaceAll('\n', '<br/>') : '',
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
{boardDetail?.answerYn === 'Y' && (
|
||||||
|
<div className="oneonone-answer">
|
||||||
|
<div className="answer-title-wrap">
|
||||||
|
<div className="answer-title">Hanwha Japan {getMessage('qna.detail.sub.answer')}</div>
|
||||||
|
<div className="oneonone-infor">
|
||||||
|
<div className="profile">{boardDetail.ansRegNm}</div>
|
||||||
|
<div className="date">{boardDetail.ansRegDt}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="community_detail-inner"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: boardDetail.ansContents ? boardDetail.ansContents.replaceAll('\n', '<br/>') : '',
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
{boardDetail.ansListFile && (
|
||||||
|
<dl className="community_detail-file-wrap">
|
||||||
|
<dt>{getMessage('qna.detail.sub.fileList')}</dt>
|
||||||
|
{boardDetail.ansListFile.map((boardFile) => (
|
||||||
|
<dd key={boardFile.encodeFileNo}>
|
||||||
|
<button type="button" className="down" onClick={() => handleFileDown(boardFile.fileNo, 'N')}>
|
||||||
|
{boardFile.srcFileNm}
|
||||||
|
</button>
|
||||||
|
</dd>
|
||||||
|
))}
|
||||||
|
</dl>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
140
src/components/community/modal/QnaFileUploader.jsx
Normal file
140
src/components/community/modal/QnaFileUploader.jsx
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useRef } from 'react'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
|
||||||
|
export default function QnaFileUploader({ uploadFiles, setUploadFiles, qnaData, setQnaData }) {
|
||||||
|
const fileInputRef = useRef(null)
|
||||||
|
const { getMessage } = useMessage()
|
||||||
|
|
||||||
|
const { swalFire } = useSwal()
|
||||||
|
|
||||||
|
const handleButtonClick = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
fileInputRef.current.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangeFiles = async (e) => {
|
||||||
|
if (e.target.files.length <= 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileList = []
|
||||||
|
let passFlag = true
|
||||||
|
const allowedFileTypes = [
|
||||||
|
'image/',
|
||||||
|
'application/pdf',
|
||||||
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
'application/vnd.ms-excel',
|
||||||
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation', // PPTX 형식
|
||||||
|
'application/vnd.ms-powerpoint', // PPT 형식
|
||||||
|
]
|
||||||
|
Array.from(e.target.files).forEach((file) => {
|
||||||
|
//엑셀, pdf, 이미지
|
||||||
|
const fileType = file.type
|
||||||
|
if (!allowedFileTypes.some((type) => fileType.includes(type))) {
|
||||||
|
passFlag = false
|
||||||
|
} else {
|
||||||
|
fileList.push({ data: file, id: uuidv4() })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!passFlag) {
|
||||||
|
swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert', icon: 'error' })
|
||||||
|
}
|
||||||
|
|
||||||
|
setUploadFiles([...uploadFiles, ...fileList])
|
||||||
|
setQnaData({...qnaData, files:[...uploadFiles, ...fileList]})
|
||||||
|
e.target.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteFile = (id) => {
|
||||||
|
setUploadFiles(uploadFiles.filter((file) => file.id !== id))
|
||||||
|
setQnaData({...qnaData, files:uploadFiles.filter((file) => file.id !== id)})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDrop = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
const fileList = []
|
||||||
|
let passFlag = true
|
||||||
|
const allowedFileTypes = [
|
||||||
|
'image/',
|
||||||
|
'application/pdf',
|
||||||
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
'application/vnd.ms-excel',
|
||||||
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation', // PPTX 형식
|
||||||
|
'application/vnd.ms-powerpoint', // PPT 형식
|
||||||
|
]
|
||||||
|
|
||||||
|
Array.from(e.dataTransfer.files).forEach((file) => {
|
||||||
|
//엑셀, pdf, 이미지
|
||||||
|
let fileType = file.type
|
||||||
|
if (!allowedFileTypes.some((type) => fileType.includes(type))) {
|
||||||
|
passFlag = false
|
||||||
|
} else {
|
||||||
|
fileList.push({ data: file, id: uuidv4() })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!passFlag) {
|
||||||
|
swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert', icon: 'error' })
|
||||||
|
}
|
||||||
|
|
||||||
|
setUploadFiles([...uploadFiles, ...fileList])
|
||||||
|
setQnaData({...qnaData, files:[...uploadFiles, ...fileList]})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDragOver = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDragEnd = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDragLeave = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<div className="design-request-grid mt15">
|
||||||
|
<div className="design-request-count">
|
||||||
|
<div className="design-request-grid-tit">{getMessage("qna.reg.header.fileList")}</div>
|
||||||
|
<div className="btn-area one-on-one">
|
||||||
|
<label className="file-upload" htmlFor="img" onClick={handleButtonClick}>
|
||||||
|
Attach File
|
||||||
|
</label>
|
||||||
|
<input type="file" multiple name="file" ref={fileInputRef} style={{ display: 'none' }} onChange={(e) => onChangeFiles(e)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="drag-file-box one-on-one">
|
||||||
|
<div className="drag-file-area"
|
||||||
|
draggable
|
||||||
|
onDrop={(e) => handleDrop(e)}
|
||||||
|
onDragOver={(e) => handleDragOver(e)}
|
||||||
|
onDragEnd={(e) => handleDragEnd(e)}
|
||||||
|
onDragLeave={(e) => handleDragLeave(e)}>
|
||||||
|
<p>Drag file here</p>
|
||||||
|
<ul className="file-list">
|
||||||
|
{uploadFiles.length > 0 &&
|
||||||
|
uploadFiles.map((file) => (
|
||||||
|
<li className="file-item" key={file.id}>
|
||||||
|
<span>
|
||||||
|
{file.data.name} <button className="delete" onClick={() => deleteFile(file.id)}></button>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
412
src/components/community/modal/QnaRegModal.jsx
Normal file
412
src/components/community/modal/QnaRegModal.jsx
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
'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'
|
||||||
|
|
||||||
|
|
||||||
|
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 [closeMdFlg, setCloseMdFlg] = useState(true)
|
||||||
|
const [closeSmFlg, setCloseSmFlg] = useState(true)
|
||||||
|
const qnaTypeLgCodeRef = useRef(null)
|
||||||
|
const qnaTypeMdCodeRef = useRef(null)
|
||||||
|
const qnaTypeSmCodeRef = 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)
|
||||||
|
|
||||||
|
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 () => {
|
||||||
|
|
||||||
|
|
||||||
|
regUserNmRef.current.value = ''
|
||||||
|
regUserTelNoRef.current.value = ''
|
||||||
|
qnaTypeLgCodeRef.current.setValue();
|
||||||
|
qnaTypeMdCodeRef.current.setValue();
|
||||||
|
qnaTypeSmCodeRef.current.setValue();
|
||||||
|
titleRef.current.value = ''
|
||||||
|
contentsRef.current.value = ''
|
||||||
|
|
||||||
|
//setQnaData([])
|
||||||
|
|
||||||
|
setQnaData({
|
||||||
|
...qnaData,
|
||||||
|
compCd: "5200",
|
||||||
|
siteTpCd: "QC",
|
||||||
|
schNoticeClsCd: "QNA",
|
||||||
|
regId: sessionState.userId,
|
||||||
|
storeId: sessionState.userId,
|
||||||
|
qstMail : sessionState.email
|
||||||
|
})
|
||||||
|
|
||||||
|
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 === undefined || e === null) return;
|
||||||
|
const codeS = findCommonCode(204400)
|
||||||
|
if (codeS != null) {
|
||||||
|
|
||||||
|
let codeList = []
|
||||||
|
|
||||||
|
codeS.map((item) => {
|
||||||
|
|
||||||
|
if (item.clRefChr1 === e.clCode) {
|
||||||
|
codeList.push(item);
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setQnaTypeSmCodeList(codeList)
|
||||||
|
setQnaData({ ...qnaData, qnaClsMidCd: e.clCode })
|
||||||
|
setCloseSmFlg(false)
|
||||||
|
qnaTypeSmCodeRef.current.setValue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
const onChangeQnaTypeS = (e) => {
|
||||||
|
if(e === undefined || e === null) return;
|
||||||
|
setQnaData({ ...qnaData, 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 handleQnaSubmit = async () => {
|
||||||
|
//필수 체크
|
||||||
|
|
||||||
|
//console.log("1::::",qnaData)
|
||||||
|
|
||||||
|
|
||||||
|
let regUserNm = qnaData?.regUserNm??'';
|
||||||
|
|
||||||
|
if (regUserNm.trim().length === 0) {
|
||||||
|
|
||||||
|
regUserNmRef.current.value = '';
|
||||||
|
regUserNmRef.current.focus()
|
||||||
|
swalFire({
|
||||||
|
text: getMessage('qna.reg.alert.require.regUserNm'),
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let qnaClsLrgCd = qnaData?.qnaClsLrgCd??'';
|
||||||
|
let qnaClsMidCd = qnaData?.qnaClsMidCd??'';
|
||||||
|
|
||||||
|
if (qnaClsLrgCd.trim().length === 0 || qnaClsMidCd.trim().length === 0 ) {
|
||||||
|
(qnaClsLrgCd.trim().length === 0)?qnaTypeLgCodeRef.current.focus():qnaTypeMdCodeRef.current.focus()
|
||||||
|
swalFire({
|
||||||
|
text: getMessage('qna.reg.alert.select.type'),
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = qnaData?.title??'';
|
||||||
|
|
||||||
|
if (title.trim().length === 0) {
|
||||||
|
titleRef.current.value = '';
|
||||||
|
titleRef.current.focus()
|
||||||
|
swalFire({
|
||||||
|
text: getMessage('qna.reg.alert.require.title'),
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
//console.log("5::::",qnaData)
|
||||||
|
let contents = qnaData?.contents??'';
|
||||||
|
|
||||||
|
if (contents.trim().length === 0) {
|
||||||
|
contentsRef.current.value = '';
|
||||||
|
contentsRef.current.focus()
|
||||||
|
swalFire({
|
||||||
|
text: getMessage('qna.reg.alert.require.contents'),
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
setIsGlobalLoading(false)
|
||||||
|
setIsBtnDisable(false)
|
||||||
|
swalFire({ text: getMessage('qna.reg.alert.saveFail'), type: 'alert', icon: 'error' })
|
||||||
|
console.error('error::::::::::::', e.message)
|
||||||
|
})
|
||||||
|
} 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" value={sessionState?.email || ''} readOnly /></td>
|
||||||
|
<th>{getMessage('qna.reg.header.regDt')}</th>
|
||||||
|
<td>{dayjs(new Date()).format('YYYY-MM-DD')}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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 colSpan={3}><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" >
|
||||||
|
<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 grey mr5" onClick={handleQnaSubmit}>{getMessage("qna.reg.header.save")}</button>}
|
||||||
|
<button className="btn-origin navy" onClick={() => {
|
||||||
|
setOpen(false)
|
||||||
|
}}>{getMessage("board.sub.btn.close")}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -142,6 +142,7 @@ export default function Header(props) {
|
|||||||
{ id: 7, name: 'header.menus.community.archive', url: '/community/archive', children: [] },
|
{ id: 7, name: 'header.menus.community.archive', url: '/community/archive', children: [] },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{ id: 8, name: 'qna.title', url: '/community/qna', children: [] },
|
||||||
]
|
]
|
||||||
|
|
||||||
const syncSession = useCallback(() => {
|
const syncSession = useCallback(() => {
|
||||||
@ -199,7 +200,7 @@ export default function Header(props) {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
// moveHome()
|
// moveHome()
|
||||||
removeStuffRecoil(menu)
|
removeStuffRecoil(menu)
|
||||||
if (pathName === '/') {
|
if (pathName === '/' && menu.id !== 8) {
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -347,9 +347,9 @@
|
|||||||
"modal.actual.size.setting.not.exist.size": "実際の寸法の長さを入力してください",
|
"modal.actual.size.setting.not.exist.size": "実際の寸法の長さを入力してください",
|
||||||
"modal.actual.size.setting.plane.size.length": "廊下寸法の長さ",
|
"modal.actual.size.setting.plane.size.length": "廊下寸法の長さ",
|
||||||
"modal.actual.size.setting.actual.size.length": "実寸長",
|
"modal.actual.size.setting.actual.size.length": "実寸長",
|
||||||
"plan.message.confirm.save": "プラン保存しますか?",
|
"plan.message.confirm.save": "プラン保存しますか?",
|
||||||
"plan.message.confirm.copy": "プランコピーしますか?",
|
"plan.message.confirm.copy": "プランコピーしますか?",
|
||||||
"plan.message.confirm.delete": "プラン削除しますか?",
|
"plan.message.confirm.delete": "プラン削除しますか?",
|
||||||
"plan.message.save": "保存されました。",
|
"plan.message.save": "保存されました。",
|
||||||
"plan.message.delete": "削除されました。",
|
"plan.message.delete": "削除されました。",
|
||||||
"plan.message.leave": "物件状況(リスト)に移動しますか? [はい]を選択した場合は保存して移動します。",
|
"plan.message.leave": "物件状況(リスト)に移動しますか? [はい]を選択した場合は保存して移動します。",
|
||||||
@ -597,6 +597,29 @@
|
|||||||
"board.sub.updDt": "更新",
|
"board.sub.updDt": "更新",
|
||||||
"board.sub.btn.close": "閉じる",
|
"board.sub.btn.close": "閉じる",
|
||||||
"board.uptDt": "更新",
|
"board.uptDt": "更新",
|
||||||
|
"qna.sub.btn.inquiry": "お問い合わせ登録",
|
||||||
|
"qna.title": "お問合せ",
|
||||||
|
"qna.detail.sub.answer": "回答",
|
||||||
|
"qna.detail.sub.fileList": "添付ファイル",
|
||||||
|
"qna.sub.title": "お問合せリスト",
|
||||||
|
"qna.reg.header.regDt": "お問い合わせ登録日",
|
||||||
|
"qna.reg.header.regUserNm": "名前",
|
||||||
|
"qna.reg.header.regUserTelNo": "お問い合わせ",
|
||||||
|
"qna.reg.header.type": "お問い合わせ区分",
|
||||||
|
"qna.reg.header.title": "お問い合わせタイトル",
|
||||||
|
"qna.reg.header.contents": "お問い合わせ内容",
|
||||||
|
"qna.reg.header.fileList": "ファイル添付",
|
||||||
|
"qna.reg.header.save": "保存",
|
||||||
|
"qna.reg.alert.require.regUserNm": "名前を入力してください。",
|
||||||
|
"qna.reg.alert.select.type": "お問い合わせ区分を選択してください。",
|
||||||
|
"qna.reg.alert.require.title": "タイトルを入力してください。",
|
||||||
|
"qna.reg.alert.require.contents": "内容を入力してください。",
|
||||||
|
"qna.reg.confirm.save": "1:1お問い合わせを登録しますか? <br/>Hanwha Japan 担当者にお問い合わせメールが送信されます。",
|
||||||
|
"qna.reg.alert.save": "保存されました。",
|
||||||
|
"qna.reg.alert.saveFail": "保存に失敗しました。",
|
||||||
|
"qna.list.header.regNm": "登録者",
|
||||||
|
"qna.list.header.answer.yes": "回答完了",
|
||||||
|
"qna.list.header.answer.no": "未回答",
|
||||||
"myinfo.title": "社員情報",
|
"myinfo.title": "社員情報",
|
||||||
"myinfo.info.userId": "ユーザーID",
|
"myinfo.info.userId": "ユーザーID",
|
||||||
"myinfo.info.nameKana": "担当者名日本語",
|
"myinfo.info.nameKana": "担当者名日本語",
|
||||||
@ -1052,7 +1075,6 @@
|
|||||||
"module.not.found": "インストールモジュールを選択してください。",
|
"module.not.found": "インストールモジュールを選択してください。",
|
||||||
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
|
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
|
||||||
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
|
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
|
||||||
"module.circuit.fix.not.same.roof.error": "異なる屋根面のモジュールが選択されています。 モジュールの選択をや直してください。",
|
|
||||||
"construction.length.difference": "屋根面工法をすべて選択してください。",
|
"construction.length.difference": "屋根面工法をすべて選択してください。",
|
||||||
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
|
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
|
||||||
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
|
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
|
||||||
|
|||||||
@ -597,6 +597,29 @@
|
|||||||
"board.sub.updDt": "업데이트",
|
"board.sub.updDt": "업데이트",
|
||||||
"board.sub.btn.close": "닫기",
|
"board.sub.btn.close": "닫기",
|
||||||
"board.uptDt": "갱신",
|
"board.uptDt": "갱신",
|
||||||
|
"qna.sub.btn.inquiry": "문의등록",
|
||||||
|
"qna.title": "문의",
|
||||||
|
"qna.sub.title": "문의 목록",
|
||||||
|
"qna.detail.sub.answer": "답변",
|
||||||
|
"qna.detail.sub.fileList": "첨부파일",
|
||||||
|
"qna.reg.header.regDt": "문의등록일",
|
||||||
|
"qna.reg.header.regUserNm": "이름",
|
||||||
|
"qna.reg.header.regUserTelNo": "연락처",
|
||||||
|
"qna.reg.header.type": "문의구분",
|
||||||
|
"qna.reg.header.title": "문의제목",
|
||||||
|
"qna.reg.header.contents": "문의정보",
|
||||||
|
"qna.reg.header.fileList": "파일첨부",
|
||||||
|
"qna.reg.header.save": "저장",
|
||||||
|
"qna.reg.alert.require.regUserNm": "이름을 입력하세요.",
|
||||||
|
"qna.reg.alert.select.type": "문의구분을 선택하세요.",
|
||||||
|
"qna.reg.alert.require.title": "제목을 입력하세요.",
|
||||||
|
"qna.reg.alert.require.contents": "내용을 입력하세요.",
|
||||||
|
"qna.reg.confirm.save": "1:1문의를 등록하시겠습니까? <br/> Hanwha Japan 담당자에게 문의메일이 발송됩니다.",
|
||||||
|
"qna.reg.alert.save": "저장 되었습니다.",
|
||||||
|
"qna.reg.alert.saveFail": "저장에 실패하였습니다.",
|
||||||
|
"qna.list.header.regNm": "등록자",
|
||||||
|
"qna.list.header.answer.yes": "답변완료",
|
||||||
|
"qna.list.header.answer.no": "미답변",
|
||||||
"myinfo.title": "내정보",
|
"myinfo.title": "내정보",
|
||||||
"myinfo.info.userId": "사용자ID",
|
"myinfo.info.userId": "사용자ID",
|
||||||
"myinfo.info.nameKana": "담당자명 일본어",
|
"myinfo.info.nameKana": "담당자명 일본어",
|
||||||
|
|||||||
@ -151,6 +151,7 @@ button{
|
|||||||
.al-r{text-align: right !important;}
|
.al-r{text-align: right !important;}
|
||||||
.al-c{text-align: center !important;}
|
.al-c{text-align: center !important;}
|
||||||
|
|
||||||
|
.org{color: #f86a56 !important;}
|
||||||
|
|
||||||
// button
|
// button
|
||||||
.btn-frame{
|
.btn-frame{
|
||||||
|
|||||||
@ -388,6 +388,10 @@
|
|||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
.drag-file-area{
|
.drag-file-area{
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
.file-list {
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 100px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user