feat: implement spinning when generate survey-sale pdf

- 조사매물 pdf 다운로드 기능 완성
- 지붕 정보 주택 구조 순서 radiobox로 변경경
This commit is contained in:
Dayoung 2025-05-28 16:49:45 +09:00
parent 23164a3f8c
commit 03d91f3fa0
3 changed files with 58 additions and 48 deletions

View File

@ -1,27 +1,29 @@
'use client' 'use client'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef } from 'react'
import generatePDF, { Margin, Resolution } from 'react-to-pdf' import generatePDF, { Margin, Resolution } from 'react-to-pdf'
import { useParams, useRouter } from 'next/navigation' import { useParams, useRouter } from 'next/navigation'
import { useSurvey } from '@/hooks/useSurvey' import { useSurvey } from '@/hooks/useSurvey'
import { radioEtcData, roofMaterial, selectBoxOptions, supplementaryFacilities } from '../survey-sale/detail/RoofForm' import { radioEtcData, roofMaterial, selectBoxOptions, supplementaryFacilities } from '../survey-sale/detail/RoofForm'
import { useSpinnerStore } from '@/store/spinnerStore'
export default function SurveySaleDownloadPdf() { export default function SurveySaleDownloadPdf() {
const params = useParams() const params = useParams()
const id = params.id const id = params.id
const router = useRouter()
const { surveyDetail, isLoadingSurveyDetail } = useSurvey(Number(id)) const { surveyDetail, isLoadingSurveyDetail } = useSurvey(Number(id))
const [isLoading, setIsLoading] = useState(false) const { setIsShow } = useSpinnerStore()
const router = useRouter()
const targetRef = useRef<HTMLDivElement>(null) const targetRef = useRef<HTMLDivElement>(null)
const isGeneratedRef = useRef(false) const isGeneratedRef = useRef(false)
// useEffect(() => { useEffect(() => {
// if (isLoadingSurveyDetail || !surveyDetail || isGeneratedRef.current) return setIsShow(true)
// isGeneratedRef.current = true if (isLoadingSurveyDetail || !surveyDetail || isGeneratedRef.current) return
// handleDownPdf() isGeneratedRef.current = true
// }, [surveyDetail?.id, isLoadingSurveyDetail]) handleDownPdf()
}, [surveyDetail?.id, isLoadingSurveyDetail])
const handleDownPdf = () => { const handleDownPdf = () => {
const options = { const options = {
@ -47,6 +49,7 @@ export default function SurveySaleDownloadPdf() {
} }
generatePDF(targetRef, options).then(() => { generatePDF(targetRef, options).then(() => {
setIsShow(false)
router.push(`/survey-sale/${id}`) router.push(`/survey-sale/${id}`)
}) })
} }
@ -56,11 +59,9 @@ export default function SurveySaleDownloadPdf() {
return ( return (
<> <>
{/* <button onClick={handleDownPdf}>down</button> */}
<div <div
ref={targetRef} ref={targetRef}
style={{ style={{
// boxSizing: 'border-box'
width: '794px', // A4 너비 width: '794px', // A4 너비
minHeight: '1123px', // A4 높이 minHeight: '1123px', // A4 높이
transform: 'scale(1.0)', transform: 'scale(1.0)',
@ -71,9 +72,7 @@ export default function SurveySaleDownloadPdf() {
fontSize: '12px', fontSize: '12px',
}} }}
> >
<div <div>
// style={{ margin: '0 auto', padding: 0, maxWidth: '800px', minWidth: '800px' }}
>
<div style={{ padding: '20px 20px 50px', borderBottom: '2px solid #2E3A59' }}> <div style={{ padding: '20px 20px 50px', borderBottom: '2px solid #2E3A59' }}>
<div style={{ float: 'left', verticalAlign: 'middle', fontSize: '18px', color: '#101010', fontWeight: 600, fontFamily: 'M-Gothic' }}> <div style={{ float: 'left', verticalAlign: 'middle', fontSize: '18px', color: '#101010', fontWeight: 600, fontFamily: 'M-Gothic' }}>
HWJ 調1/2 HWJ 調1/2
@ -449,8 +448,8 @@ export default function SurveySaleDownloadPdf() {
boxSizing: 'border-box', boxSizing: 'border-box',
}} }}
> >
{surveyDetail?.detailInfo?.houseStructure ? '木製' : ''} {radioEtcData.houseStructure.find((structure) => structure.id.toString() === surveyDetail?.detailInfo?.houseStructure)?.label ??
{surveyDetail?.detailInfo?.houseStructureEtc ? ` ${surveyDetail?.detailInfo?.houseStructureEtc}` : '-'} (surveyDetail?.detailInfo?.houseStructureEtc ? ` ${surveyDetail?.detailInfo?.houseStructureEtc}` : '-')}
</td> </td>
</tr> </tr>
<tr> <tr>
@ -479,10 +478,12 @@ export default function SurveySaleDownloadPdf() {
boxSizing: 'border-box', boxSizing: 'border-box',
}} }}
> >
{surveyDetail?.detailInfo?.rafterMaterial === null && surveyDetail?.detailInfo?.rafterMaterialEtc === null {/* {surveyDetail?.detailInfo?.rafterMaterial === null && surveyDetail?.detailInfo?.rafterMaterialEtc === null
? '-' ? '-'
: radioEtcData.rafterMaterial.find((material) => material.id.toString() === surveyDetail?.detailInfo?.rafterMaterial)?.label ?? : radioEtcData.rafterMaterial.find((material) => material.id.toString() === surveyDetail?.detailInfo?.rafterMaterial)?.label ??
surveyDetail?.detailInfo?.rafterMaterialEtc} surveyDetail?.detailInfo?.rafterMaterialEtc} */}
{radioEtcData.rafterMaterial.find((material) => material.id.toString() === surveyDetail?.detailInfo?.rafterMaterial)?.label ??
(surveyDetail?.detailInfo?.rafterMaterialEtc ? ` ${surveyDetail?.detailInfo?.rafterMaterialEtc}` : '-')}
</td> </td>
<th <th
style={{ style={{
@ -723,7 +724,7 @@ export default function SurveySaleDownloadPdf() {
radioEtcData.insulationPresence.find((presence) => presence.id.toString() === surveyDetail?.detailInfo?.insulationPresence) radioEtcData.insulationPresence.find((presence) => presence.id.toString() === surveyDetail?.detailInfo?.insulationPresence)
?.label ?.label
} }
{surveyDetail?.detailInfo?.insulationPresenceEtc ? ` ${surveyDetail?.detailInfo?.insulationPresenceEtc}` : '-'} {surveyDetail?.detailInfo?.insulationPresenceEtc ? `, ${surveyDetail?.detailInfo?.insulationPresenceEtc}` : ''}
</td> </td>
</tr> </tr>
<tr> <tr>
@ -753,7 +754,7 @@ export default function SurveySaleDownloadPdf() {
boxSizing: 'border-box', boxSizing: 'border-box',
}} }}
> >
{selectBoxOptions.structureOrder.find((order) => order.id.toString() === surveyDetail?.detailInfo?.structureOrder)?.name ?? {radioEtcData.structureOrder.find((order) => order.id.toString() === surveyDetail?.detailInfo?.structureOrder)?.label ??
(surveyDetail?.detailInfo?.structureOrderEtc ? `${surveyDetail?.detailInfo?.structureOrderEtc}` : '-')} (surveyDetail?.detailInfo?.structureOrderEtc ? `${surveyDetail?.detailInfo?.structureOrderEtc}` : '-')}
</td> </td>
</tr> </tr>
@ -792,12 +793,12 @@ export default function SurveySaleDownloadPdf() {
boxSizing: 'border-box', boxSizing: 'border-box',
}} }}
> >
{ {surveyDetail?.detailInfo?.installationAvailability === null && surveyDetail.detailInfo?.installationAvailabilityEtc === null
selectBoxOptions.installationAvailability.find( ? '-'
: selectBoxOptions.installationAvailability.find(
(availability) => availability.id.toString() === surveyDetail?.detailInfo?.installationAvailability, (availability) => availability.id.toString() === surveyDetail?.detailInfo?.installationAvailability,
)?.name )?.name}
} {surveyDetail?.detailInfo?.installationAvailabilityEtc ? `, ${surveyDetail?.detailInfo?.installationAvailabilityEtc}` : ''}
{surveyDetail?.detailInfo?.installationAvailabilityEtc ? ` ${surveyDetail?.detailInfo?.installationAvailabilityEtc}` : '-'}
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -6,12 +6,14 @@ import { useEffect, useState } from 'react'
import { useSessionStore } from '@/store/session' import { useSessionStore } from '@/store/session'
import { useCommCode } from '@/hooks/useCommCode' import { useCommCode } from '@/hooks/useCommCode'
import { CommCode } from '@/types/CommCode' import { CommCode } from '@/types/CommCode'
// import { sendEmail } from '@/libs/mailer'
import { useSpinnerStore } from '@/store/spinnerStore'
interface SubmitFormData { interface SubmitFormData {
saleBase: string | null saleBase: string | null
store: string store: string
sender: string sender: string
receiver: string[] receiver: string[] | string
reference: string | null reference: string | null
title: string title: string
contents: string contents: string
@ -29,6 +31,7 @@ export default function SurveySaleSubmitPopup() {
const params = useParams() const params = useParams()
const routeId = params.id const routeId = params.id
const { setIsShow } = useSpinnerStore()
const [commCodeList, setCommCodeList] = useState<CommCode[]>([]) const [commCodeList, setCommCodeList] = useState<CommCode[]>([])
const { getCommCode } = useCommCode() const { getCommCode } = useCommCode()
@ -86,10 +89,22 @@ export default function SurveySaleSubmitPopup() {
const handleSubmit = () => { const handleSubmit = () => {
if (validateData(submitData)) { if (validateData(submitData)) {
window.neoConfirm('送信しますか? 送信後は変更・修正することはできません。', () => { window.neoConfirm('送信しますか? 送信後は変更・修正することはできません。', () => {
setIsShow(true)
submitSurvey({ targetId: submitData.store }) submitSurvey({ targetId: submitData.store })
// sendEmail({
// to: submitData.receiver,
// subject: submitData.title,
// content: submitData.contents,
// })
// .then(() => {
if (!isSubmittingSurvey) { if (!isSubmittingSurvey) {
popupController.setSurveySaleSubmitPopup(false) popupController.setSurveySaleSubmitPopup(false)
} }
// })
// .catch((error) => {
// console.error('Error sending email:', error)
// alert('メール送信に失敗しました。')
// })
}) })
} }
} }

View File

@ -1,7 +1,14 @@
import { useState } from 'react' import { useState } from 'react'
import type { Mode, SurveyDetailInfo, SurveyDetailRequest } from '@/types/Survey' import type { Mode, SurveyDetailInfo, SurveyDetailRequest } from '@/types/Survey'
type RadioEtcKeys = 'houseStructure' | 'rafterMaterial' | 'waterproofMaterial' | 'insulationPresence' | 'rafterDirection' | 'leakTrace' type RadioEtcKeys =
| 'structureOrder'
| 'houseStructure'
| 'rafterMaterial'
| 'waterproofMaterial'
| 'insulationPresence'
| 'rafterDirection'
| 'leakTrace'
type SelectBoxKeys = type SelectBoxKeys =
| 'installationSystem' | 'installationSystem'
| 'constructionYear' | 'constructionYear'
@ -9,7 +16,6 @@ type SelectBoxKeys =
| 'rafterPitch' | 'rafterPitch'
| 'rafterSize' | 'rafterSize'
| 'openFieldPlateKind' | 'openFieldPlateKind'
| 'structureOrder'
| 'installationAvailability' | 'installationAvailability'
export const supplementaryFacilities = [ export const supplementaryFacilities = [
@ -115,24 +121,6 @@ export const selectBoxOptions: Record<SelectBoxKeys, { id: number; name: string
name: '小幅板', //소판 name: '小幅板', //소판
}, },
], ],
structureOrder: [
{
id: 1,
name: '屋根材', //지붕재
},
{
id: 2,
name: '防水材', //방수재
},
{
id: 3,
name: '屋根の基礎', //지붕의기초
},
{
id: 4,
name: '垂木', //서까래
},
],
installationAvailability: [ installationAvailability: [
{ {
id: 1, id: 1,
@ -146,6 +134,12 @@ export const selectBoxOptions: Record<SelectBoxKeys, { id: number; name: string
} }
export const radioEtcData: Record<RadioEtcKeys, { id: number; label: string }[]> = { export const radioEtcData: Record<RadioEtcKeys, { id: number; label: string }[]> = {
structureOrder: [
{
id: 1,
label: '屋根材 - 防水材 - 屋根の基礎 - 垂木', //지붕재 방수재 지붕의기초 서까래
},
],
houseStructure: [ houseStructure: [
{ {
id: 1, id: 1,
@ -438,7 +432,7 @@ export default function RoofForm(props: {
<div className="data-input-form-bx"> <div className="data-input-form-bx">
{/* 지붕 구조의 순서 */} {/* 지붕 구조의 순서 */}
<div className="data-input-form-tit red-f"></div> <div className="data-input-form-tit red-f"></div>
<SelectedBox mode={mode} column="structureOrder" detailInfoData={roofInfo as SurveyDetailInfo} setRoofInfo={setRoofInfo} /> <RadioSelected mode={mode} column="structureOrder" detailInfoData={roofInfo as SurveyDetailInfo} setRoofInfo={setRoofInfo} />
</div> </div>
<div className="data-input-form-bx"> <div className="data-input-form-bx">
{/* 지붕 제품명 설치 가능 여부 확인 */} {/* 지붕 제품명 설치 가능 여부 확인 */}