339 lines
12 KiB
TypeScript

'use client'
import { useInquiry } from '@/hooks/useInquiry'
import { useSessionStore } from '@/store/session'
import { InquiryRequest } from '@/types/Inquiry'
import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { CONFIRM_MESSAGE, ERROR_MESSAGE, SUCCESS_MESSAGE, useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
export default function RegistForm() {
const { saveInquiry, isSavingInquiry, commonCodeList } = useInquiry(undefined, false)
const { showErrorAlert, showSuccessAlert, showConfirm } = useAlertMsg()
const { session } = useSessionStore()
const router = useRouter()
const { setIsMyInquiry } = useInquiryFilterStore()
const [inquiryRequest, setInquiryRequest] = useState<InquiryRequest>({
compCd: '5200',
siteTpCd: 'QC',
qnaClsLrgCd: '',
qnaClsMidCd: '',
qnaClsSmlCd: null,
title: '',
contents: '',
regId: '',
regUserNm: '',
regUserTelNo: null,
storeId: '',
qstMail: '',
})
const requiredFieldNames = [
{ id: 'qnaClsLrgCd', name: 'お問い合わせタイプ' },
{ id: 'qnaClsMidCd', name: 'お問い合わせタイプ' },
{ id: 'regUserNm', name: '名前' },
{ id: 'qstMail', name: 'E-mail' },
{ id: 'title', name: 'お問い合わせタイトル' },
{ id: 'contents', name: 'お問い合わせ内容' },
]
useEffect(() => {
if (session?.isLoggedIn) {
setInquiryRequest({
...inquiryRequest,
regId: session?.userId ?? '',
regUserNm: session?.userNm ?? '',
storeId: session?.storeId ?? '',
qstMail: session?.email ?? '',
})
}
}, [session])
const [attachedFiles, setAttachedFiles] = useState<File[]>([])
/** 파일 첨부 처리 */
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files
if (files && files.length > 0) {
setAttachedFiles(attachedFiles.concat(Array.from(files)))
}
e.target.value = ''
}
/** 파일 삭제 처리 */
const handleRemoveFile = (index: number) => {
setAttachedFiles(attachedFiles.filter((_, i) => i !== index))
}
/** 필수 필드 포커스 처리 */
const focusOnRequiredField = (fieldId: string) => {
const element = document.getElementById(fieldId)
if (element) element.focus()
}
/** 제출 처리 */
const handleSubmit = async () => {
const emptyField = requiredFieldNames.find((field) => inquiryRequest[field.id as keyof InquiryRequest] === '')
if (emptyField) {
showErrorAlert(WARNING_MESSAGE.REQUIRED_FIELD_IS_EMPTY, emptyField?.name)
focusOnRequiredField(emptyField?.id ?? '')
return
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(inquiryRequest.qstMail)) {
showErrorAlert(WARNING_MESSAGE.EMAIL_PREFIX_IS_INVALID)
focusOnRequiredField('qstMail')
return
}
if (inquiryRequest.title.length > 100) {
showErrorAlert(WARNING_MESSAGE.TITLE_MAX_LENGTH)
focusOnRequiredField('title')
return
}
if (inquiryRequest.contents.length > 2000) {
showErrorAlert(WARNING_MESSAGE.CONTENTS_MAX_LENGTH)
focusOnRequiredField('contents')
return
}
const formData = new FormData()
attachedFiles.forEach((file) => {
formData.append('files', file)
})
Object.entries(inquiryRequest).forEach(([key, value]) => {
formData.append(key, value ?? '')
})
showConfirm(
CONFIRM_MESSAGE.SAVE_INQUIRY_CONFIRM,
async () => {
try {
const res = await saveInquiry(formData)
showSuccessAlert(SUCCESS_MESSAGE.SAVE_SUCCESS)
router.push(`/inquiry/${res.qnaNo}`)
} catch (error) {
showErrorAlert(ERROR_MESSAGE.SERVER_ERROR)
}
},
() => null,
)
}
const handlePhoneNumberChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value.replace(/[^\d]/g, '')
let formattedNumber = ''
if (value.length <= 3) {
formattedNumber = value
} else if (value.length <= 7) {
formattedNumber = `${value.slice(0, 3)}-${value.slice(3)}`
} else {
formattedNumber = `${value.slice(0, 3)}-${value.slice(3, 7)}-${value.slice(7, 11)}`
}
setInquiryRequest({ ...inquiryRequest, regUserTelNo: formattedNumber })
}
return (
<>
<div className="inquiry-frame">
<div className="data-form-wrap">
<div className="data-input-form-bx">
<div className="data-input-form-tit">
<i className="import">*</i>
</div>
<div className="data-input">
<select
className="select-form"
name="qnaClsLrgCd"
id="qnaClsLrgCd"
value={inquiryRequest.qnaClsLrgCd}
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qnaClsLrgCd: e.target.value })}
>
<option value="" hidden>
</option>
{commonCodeList
.filter((code) => code.headCd === '204200')
.map((code) => (
<option key={code.code} value={code.code}>
{code.name}
</option>
))}
</select>
</div>
{commonCodeList.filter((code) => code.refChar1 === inquiryRequest.qnaClsLrgCd).length > 0 && (
<div className="data-input mt5">
<select
className="select-form"
name="qnaClsMidCd"
id="qnaClsMidCd"
value={inquiryRequest.qnaClsMidCd}
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qnaClsMidCd: e.target.value })}
>
<option value="" hidden>
</option>
{commonCodeList
.filter((code) => code.refChar1 === inquiryRequest.qnaClsLrgCd)
.map((code) => (
<option key={code.code} value={code.code}>
{code.name}
</option>
))}
</select>
</div>
)}
{commonCodeList.filter((code) => code.refChar1 === inquiryRequest.qnaClsMidCd).length > 0 && (
<div className="data-input mt5">
<select
className="select-form"
name="qnaClsSmlCd"
id="qnaClsSmlCd"
value={inquiryRequest.qnaClsSmlCd ?? ''}
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qnaClsSmlCd: e.target.value })}
>
<option value="" hidden>
</option>
{commonCodeList
.filter((code) => code.refChar1 === inquiryRequest.qnaClsMidCd)
.map((code) => (
<option key={code.code} value={code.code}>
{code.name}
</option>
))}
</select>
</div>
)}
</div>
<div className="data-input-form-bx">
<div className="data-input-form-tit">
<i className="import">*</i>
</div>
<div className="data-input">
<input
className="input-frame"
type="text"
placeholder="名前を書いてください"
onChange={(e) => setInquiryRequest({ ...inquiryRequest, regUserNm: e.target.value })}
value={inquiryRequest.regUserNm}
id="regUserNm"
/>
</div>
</div>
<div className="data-input-form-bx">
<div className="data-input-form-tit"></div>
<div className="data-input">
<input
className="input-frame"
type="tel"
inputMode="tel"
placeholder="電話番号を書き留めてください"
onChange={handlePhoneNumberChange}
value={inquiryRequest.regUserTelNo ?? ''}
id="regUserTelNo"
maxLength={13}
/>
</div>
</div>
<div className="data-input-form-bx">
<div className="data-input-form-tit">
E-mail <i className="import">*</i>
</div>
<div className="data-input">
<input
className="input-frame"
type="text"
placeholder="E-mailを書いてください"
value={inquiryRequest.qstMail}
onChange={(e) => setInquiryRequest({ ...inquiryRequest, qstMail: e.target.value })}
id="qstMail"
/>
</div>
</div>
<div className="data-input-form-bx">
<div className="data-input-form-tit">
<i className="import">*</i>
</div>
<div className="data-input">
<input
className="input-frame"
type="text"
placeholder="お問い合わせタイトルを記入してください"
onChange={(e) => {
if (e.target.value.length >= 100) {
showErrorAlert(WARNING_MESSAGE.TITLE_MAX_LENGTH)
return
}
setInquiryRequest({ ...inquiryRequest, title: e.target.value })
}}
maxLength={100}
id="title"
/>
</div>
</div>
<div className="data-input-form-bx">
<div className="data-input-form-tit">
<i className="import">*</i>
</div>
<div className="data-input">
<textarea
className="textarea-form"
rows={6}
id="contents"
placeholder="お問い合わせ内容を入力してください"
onChange={(e) => {
if (e.target.value.length >= 2000) {
showErrorAlert(WARNING_MESSAGE.CONTENTS_MAX_LENGTH)
return
}
setInquiryRequest({ ...inquiryRequest, contents: e.target.value })
}}
value={inquiryRequest.contents}
maxLength={2000}
></textarea>
</div>
</div>
</div>
<div className="inquiry-file-wrap">
<div className="filebox">
<label className="btn-frame l-blue icon" htmlFor="file">
<i className="btn-clip"></i>Attach
</label>
<input type="file" id="file" onChange={handleFileChange} multiple style={{ display: 'none' }} />
</div>
<div className="file-list-wrap">
<div className="file-list-tit">
<span>{attachedFiles.length}</span>
</div>
<ul className="file-list">
{attachedFiles.map((file, index) => (
<li className="file-item" key={`${file.name}-${index}`}>
<div className="file-item-bx">
<div className="file-item-name">{file.name}</div>
<button className="file-del" onClick={() => handleRemoveFile(index)} aria-label="Remove file" />
</div>
</li>
))}
</ul>
</div>
<div className="btn-flex-wrap">
<button
className="btn-frame n-blue icon"
onClick={() => {
setIsMyInquiry(session?.userId ?? null)
router.push('/inquiry/list')
}}
>
<i className="btn-arr"></i>
</button>
<button className="btn-frame n-blue icon" onClick={handleSubmit} disabled={isSavingInquiry}>
<i className="btn-arr"></i>
</button>
</div>
</div>
</div>
</>
)
}