- 건축연수, 단열재의 유무 필드 기타 항목 유효성 검사 추가 - ORDER, MUSUBI 조사매물 목록 검색조건에 판매점Id, 시공점Id 추가 - T01 계정의 경우 제출받은 매물만 수정/삭제 가능하도록 수정 -
259 lines
9.5 KiB
TypeScript
259 lines
9.5 KiB
TypeScript
import Image from 'next/image'
|
||
import { usePopupController } from '@/store/popupController'
|
||
import { useParams } from 'next/navigation'
|
||
import { useSurvey } from '@/hooks/useSurvey'
|
||
import { useEffect, useRef, useState } from 'react'
|
||
import { useSessionStore } from '@/store/session'
|
||
import { useCommCode } from '@/hooks/useCommCode'
|
||
import { CommCode } from '@/types/CommCode'
|
||
import { sendEmail } from '@/libs/mailer'
|
||
import { useSpinnerStore } from '@/store/spinnerStore'
|
||
|
||
interface SubmitFormData {
|
||
saleBase: string | null
|
||
targetId: string | null
|
||
targetNm: string | null
|
||
sender: string
|
||
receiver: string[] | string
|
||
reference: string | null
|
||
title: string
|
||
contents: string | null
|
||
}
|
||
|
||
interface FormField {
|
||
id: keyof SubmitFormData
|
||
name: string
|
||
required: boolean
|
||
}
|
||
|
||
export default function SurveySaleSubmitPopup() {
|
||
const popupController = usePopupController()
|
||
const { session } = useSessionStore()
|
||
const params = useParams()
|
||
const routeId = params.id
|
||
|
||
const { setIsShow } = useSpinnerStore()
|
||
const { getCommCode } = useCommCode()
|
||
const { surveyDetail } = useSurvey(Number(routeId))
|
||
|
||
const [submitData, setSubmitData] = useState<SubmitFormData>({
|
||
saleBase: null,
|
||
targetId: null,
|
||
targetNm: null,
|
||
sender: '',
|
||
receiver: [],
|
||
reference: null,
|
||
title: '',
|
||
contents: '',
|
||
})
|
||
|
||
const [commCodeList, setCommCodeList] = useState<CommCode[]>([])
|
||
useEffect(() => {
|
||
if (!session?.isLoggedIn || !surveyDetail?.id) return
|
||
if (session?.role === 'Admin') {
|
||
getCommCode('SALES_OFFICE_CD').then((codes) => {
|
||
setCommCodeList(codes)
|
||
})
|
||
}
|
||
setSubmitData({
|
||
...submitData,
|
||
targetId: session?.role === 'Builder' ? surveyDetail?.storeId ?? null : null,
|
||
targetNm: session?.role === 'Builder' ? surveyDetail?.store ?? null : null,
|
||
sender: session?.email ?? '',
|
||
title: '[HANASYS現地調査] 調査物件が提出. (' + surveyDetail?.srlNo + ')',
|
||
})
|
||
}, [session, surveyDetail])
|
||
|
||
const FORM_FIELDS: FormField[] = [
|
||
{ id: 'sender', name: '発送者', required: true },
|
||
{ id: 'saleBase', name: '提出地点選択', required: session?.role === 'Admin' },
|
||
{ id: 'targetNm', name: '提出販売店', required: session?.role !== 'Admin' },
|
||
{ id: 'receiver', name: '受信者', required: true },
|
||
{ id: 'reference', name: '参考', required: false },
|
||
{ id: 'title', name: 'タイトル', required: true },
|
||
{ id: 'contents', name: '内容', required: false },
|
||
]
|
||
|
||
const { submitSurvey, isSubmittingSurvey } = useSurvey(Number(routeId))
|
||
|
||
const handleInputChange = (field: keyof SubmitFormData, value: string) => {
|
||
setSubmitData((prev) => ({ ...prev, [field]: value }))
|
||
}
|
||
|
||
const validateData = (data: SubmitFormData): boolean => {
|
||
const requiredFields = FORM_FIELDS.filter((field) => field.required)
|
||
|
||
for (const field of requiredFields) {
|
||
if (data[field.id] === '' || data[field.id] === null || data[field.id]?.length === 0) {
|
||
alert(`${field.name}は必須入力項目です。`)
|
||
const element = document.getElementById(field.id)
|
||
if (element) {
|
||
element.focus()
|
||
}
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// TODO: Admin_Sub 계정 매핑된 submit target id 추가!!!! && 메일 테스트트
|
||
const handleSubmit = () => {
|
||
if (validateData(submitData)) {
|
||
window.neoConfirm('送信しますか? 送信後は変更・修正することはできません。', () => {
|
||
setIsShow(true)
|
||
sendEmail({
|
||
to: submitData.receiver,
|
||
subject: submitData.title,
|
||
content: contentsRef.current?.innerHTML ?? '',
|
||
})
|
||
.then(() => {
|
||
if (!isSubmittingSurvey) {
|
||
alert('提出が完了しました。')
|
||
// submitSurvey({ targetId: submitData.targetId, targetNm: submitData.targetNm })
|
||
popupController.setSurveySaleSubmitPopup(false)
|
||
}
|
||
})
|
||
.catch((error) => {
|
||
console.error('Error sending email:', error)
|
||
alert('メール送信に失敗しました。 再度送信してください。')
|
||
})
|
||
.finally(() => {
|
||
submitSurvey({ targetId: submitData.targetId, targetNm: submitData.targetNm })
|
||
setIsShow(false)
|
||
popupController.setSurveySaleSubmitPopup(false)
|
||
})
|
||
})
|
||
}
|
||
}
|
||
|
||
const contentsRef = useRef<HTMLDivElement>(null)
|
||
|
||
const handleClose = () => {
|
||
popupController.setSurveySaleSubmitPopup(false)
|
||
}
|
||
|
||
const renderFormField = (field: FormField) => {
|
||
const isReadOnly = false
|
||
|
||
if (field.id === 'saleBase' && session?.role !== 'Admin') {
|
||
return null
|
||
}
|
||
if (field.id === 'targetNm' && session?.role === 'Admin') {
|
||
return null
|
||
}
|
||
|
||
return (
|
||
<div className="data-input-form-bx" key={field.id}>
|
||
<div className="data-input-form-tit">
|
||
{field.name} {field.required && <i className="import">*</i>}
|
||
</div>
|
||
<div className="data-input">
|
||
{field.id === 'contents' ? (
|
||
<div className="submit-content" id={field.id}>
|
||
<div ref={contentsRef}>
|
||
<p style={{ fontSize: '13px', fontWeight: '400', color: '#2e3a59', marginBottom: '15px' }}>
|
||
HANASYS現地調査アプリを使用した現地調査結果が送信されました。
|
||
</p>
|
||
<p style={{ fontSize: '13px', fontWeight: '400', color: '#2e3a59', marginBottom: '3px' }}>
|
||
-担当者名: <span style={{ color: '#417DDC' }}>{surveyDetail?.representative}</span>
|
||
</p>
|
||
<p style={{ fontSize: '13px', fontWeight: '400', color: '#2e3a59', marginBottom: '3px' }}>
|
||
-販売店名:
|
||
<span style={{ color: '#417DDC' }}>
|
||
{surveyDetail?.store} ({surveyDetail?.storeId})
|
||
</span>
|
||
</p>
|
||
<p style={{ fontSize: '13px', fontWeight: '400', color: '#2e3a59', marginBottom: '15px' }}>
|
||
-施工店名:
|
||
<span style={{ color: '#417DDC' }}>{surveyDetail?.constructionPoint}</span>
|
||
</p>
|
||
<p>
|
||
<a
|
||
style={{ fontSize: '13px', fontWeight: '400', color: '#1259CB', marginBottom: '5px', textDecoration: 'underline' }}
|
||
href={`${process.env.NEXT_PUBLIC_API_URL}/pdf/survey-sale/${surveyDetail?.id}`}
|
||
target="_blank"
|
||
>
|
||
現地調査結果PDFダウンロード
|
||
</a>
|
||
</p>
|
||
<p style={{ fontSize: '13px', fontWeight: '400', color: '#2e3a59' }}>
|
||
※リンクをクリックしてローカル調査結果PDFをダウンロードできます。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<>
|
||
{field.id === 'saleBase' && session?.role === 'Admin' ? (
|
||
<select
|
||
className="select-form"
|
||
id={field.id}
|
||
value={submitData[field.id] ?? ''}
|
||
onChange={(e) => {
|
||
const selectedOffice = commCodeList.find((item) => item.code === e.target.value)
|
||
if (selectedOffice) {
|
||
//@ts-ignore
|
||
const receiver = selectedOffice.REF_CHR1.split(';')
|
||
setSubmitData((prev) => ({ ...prev, receiver: receiver, saleBase: e.target.value }))
|
||
}
|
||
}}
|
||
>
|
||
<option value="">選択してください</option>
|
||
{commCodeList.map((item) => (
|
||
<option key={item.code} value={item.code}>
|
||
{item.codeJp}
|
||
</option>
|
||
))}
|
||
</select>
|
||
) : (
|
||
<input
|
||
className="input-frame"
|
||
type="text"
|
||
id={field.id}
|
||
value={submitData[field.id] ?? ''}
|
||
onChange={(e) => handleInputChange(field.id, e.target.value)}
|
||
readOnly={isReadOnly}
|
||
/>
|
||
)}
|
||
</>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="modal-popup">
|
||
<div className="modal-dialog">
|
||
<div className="modal-content">
|
||
<div className="modal-header">
|
||
<div className="modal-header-inner">
|
||
<div className="modal-name-wrap">
|
||
<div className="modal-img">
|
||
<Image src="/assets/images/layout/modal_header_icon04.svg" width={19} height={22} alt="" />
|
||
</div>
|
||
<div className="modal-name">調査物件の提出</div>
|
||
</div>
|
||
<button className="modal-close" onClick={handleClose}></button>
|
||
</div>
|
||
</div>
|
||
<div className="modal-body">
|
||
<div className="data-form-wrap">{FORM_FIELDS.map(renderFormField)}</div>
|
||
<div className="btn-flex-wrap">
|
||
<div className="btn-bx">
|
||
<button className="btn-frame n-blue icon" onClick={handleClose}>
|
||
閉じる<i className="btn-arr"></i>
|
||
</button>
|
||
</div>
|
||
<div className="btn-bx">
|
||
<button className="btn-frame red icon" onClick={handleSubmit} disabled={isSubmittingSurvey}>
|
||
転送<i className="btn-arr"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|