Merge pull request 'feature/survey' (#86) from feature/survey into dev
Reviewed-on: #86
This commit is contained in:
commit
798cd3b6d4
@ -124,7 +124,7 @@ export class SurveySalesService {
|
|||||||
case 'Admin_Sub':
|
case 'Admin_Sub':
|
||||||
where.OR = [
|
where.OR = [
|
||||||
{
|
{
|
||||||
AND: [{ STORE_ID: { equals: this.session?.storeId } }, { CONSTRUCTION_POINT_ID: { equals: this.session?.builderId } }],
|
AND: [{ STORE_ID: { equals: this.session?.storeId } }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
AND: [
|
AND: [
|
||||||
@ -440,8 +440,8 @@ export class SurveySalesService {
|
|||||||
return survey.SUBMISSION_STATUS
|
return survey.SUBMISSION_STATUS
|
||||||
? survey.SUBMISSION_TARGET_ID === storeId ||
|
? survey.SUBMISSION_TARGET_ID === storeId ||
|
||||||
survey.SUBMISSION_TARGET_NM === storeNm ||
|
survey.SUBMISSION_TARGET_NM === storeNm ||
|
||||||
(survey.STORE_ID === storeId && !survey.CONSTRUCTION_POINT_ID)
|
survey.STORE_ID === storeId
|
||||||
: survey.STORE_ID === storeId && !survey.CONSTRUCTION_POINT_ID
|
: survey.STORE_ID === storeId
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -56,7 +56,7 @@ export default function Detail() {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>お問い合わせ</th>
|
<th>お問い合わせ</th>
|
||||||
<td>{inquiryDetail?.regUserTelNo}</td>
|
<td>{inquiryDetail?.regUserTelNo ? inquiryDetail?.regUserTelNo : '-'}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -6,13 +6,14 @@ import { InquiryRequest } from '@/types/Inquiry'
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
import { CONFIRM_MESSAGE, SUCCESS_MESSAGE, useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
import { CONFIRM_MESSAGE, SUCCESS_MESSAGE, useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
||||||
|
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
|
||||||
|
|
||||||
export default function RegistForm() {
|
export default function RegistForm() {
|
||||||
const { saveInquiry, isSavingInquiry, commonCodeList } = useInquiry(undefined, false)
|
const { saveInquiry, isSavingInquiry, commonCodeList } = useInquiry(undefined, false)
|
||||||
const { showErrorAlert, showSuccessAlert, showConfirm } = useAlertMsg()
|
const { showErrorAlert, showSuccessAlert, showConfirm } = useAlertMsg()
|
||||||
const { session } = useSessionStore()
|
const { session } = useSessionStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const { setIsMyInquiry } = useInquiryFilterStore()
|
||||||
const [inquiryRequest, setInquiryRequest] = useState<InquiryRequest>({
|
const [inquiryRequest, setInquiryRequest] = useState<InquiryRequest>({
|
||||||
compCd: '5200',
|
compCd: '5200',
|
||||||
siteTpCd: 'QC',
|
siteTpCd: 'QC',
|
||||||
@ -255,7 +256,13 @@ export default function RegistForm() {
|
|||||||
className="input-frame"
|
className="input-frame"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="お問い合わせタイトルを記入してください"
|
placeholder="お問い合わせタイトルを記入してください"
|
||||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, title: e.target.value })}
|
onChange={(e) => {
|
||||||
|
if (e.target.value.length >= 100) {
|
||||||
|
showErrorAlert(WARNING_MESSAGE.TITLE_MAX_LENGTH)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setInquiryRequest({ ...inquiryRequest, title: e.target.value })
|
||||||
|
}}
|
||||||
maxLength={100}
|
maxLength={100}
|
||||||
id="title"
|
id="title"
|
||||||
/>
|
/>
|
||||||
@ -271,7 +278,13 @@ export default function RegistForm() {
|
|||||||
rows={6}
|
rows={6}
|
||||||
id="contents"
|
id="contents"
|
||||||
placeholder="お問い合わせ内容を入力してください"
|
placeholder="お問い合わせ内容を入力してください"
|
||||||
onChange={(e) => setInquiryRequest({ ...inquiryRequest, contents: e.target.value })}
|
onChange={(e) => {
|
||||||
|
if (e.target.value.length >= 2000) {
|
||||||
|
showErrorAlert(WARNING_MESSAGE.CONTENTS_MAX_LENGTH)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setInquiryRequest({ ...inquiryRequest, contents: e.target.value })
|
||||||
|
}}
|
||||||
value={inquiryRequest.contents}
|
value={inquiryRequest.contents}
|
||||||
maxLength={2000}
|
maxLength={2000}
|
||||||
></textarea>
|
></textarea>
|
||||||
@ -301,7 +314,13 @@ export default function RegistForm() {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="btn-flex-wrap">
|
<div className="btn-flex-wrap">
|
||||||
<button className="btn-frame n-blue icon" onClick={() => router.push('/inquiry/list')}>
|
<button
|
||||||
|
className="btn-frame n-blue icon"
|
||||||
|
onClick={() => {
|
||||||
|
setIsMyInquiry(session?.userId ?? null)
|
||||||
|
router.push('/inquiry/list')
|
||||||
|
}}
|
||||||
|
>
|
||||||
リスト<i className="btn-arr"></i>
|
リスト<i className="btn-arr"></i>
|
||||||
</button>
|
</button>
|
||||||
<button className="btn-frame n-blue icon" onClick={handleSubmit} disabled={isSavingInquiry}>
|
<button className="btn-frame n-blue icon" onClick={handleSubmit} disabled={isSavingInquiry}>
|
||||||
|
|||||||
@ -1,18 +1,25 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
|
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
import { useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
||||||
|
|
||||||
export default function ListForm() {
|
export default function ListForm() {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { inquiryListRequest, setInquiryListRequest, reset, setOffset } = useInquiryFilterStore()
|
const { inquiryListRequest, setInquiryListRequest, setOffset } = useInquiryFilterStore()
|
||||||
const { showErrorAlert } = useAlertMsg()
|
const { showErrorAlert } = useAlertMsg()
|
||||||
const [searchKeyword, setSearchKeyword] = useState(inquiryListRequest.schTitle ?? '')
|
const [searchKeyword, setSearchKeyword] = useState(inquiryListRequest.schTitle ?? '')
|
||||||
|
const searchParams = useSearchParams()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (searchParams.get('isMyInquiry') === 'false') {
|
||||||
|
setSearchKeyword('')
|
||||||
|
setInquiryListRequest({ ...inquiryListRequest, schTitle: null })
|
||||||
|
}
|
||||||
|
}, [searchParams])
|
||||||
|
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
if (searchKeyword.length >= 2) {
|
if (searchKeyword.length >= 2) {
|
||||||
reset()
|
|
||||||
setInquiryListRequest({ ...inquiryListRequest, schTitle: searchKeyword })
|
setInquiryListRequest({ ...inquiryListRequest, schTitle: searchKeyword })
|
||||||
} else {
|
} else {
|
||||||
showErrorAlert(WARNING_MESSAGE.KEYWORD_MINIMUM_LENGTH)
|
showErrorAlert(WARNING_MESSAGE.KEYWORD_MINIMUM_LENGTH)
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useEffect, useState } from 'react'
|
|||||||
import LoadMoreButton from '../../LoadMoreButton'
|
import LoadMoreButton from '../../LoadMoreButton'
|
||||||
import { useInquiry } from '@/hooks/useInquiry'
|
import { useInquiry } from '@/hooks/useInquiry'
|
||||||
import { InquiryList } from '@/types/Inquiry'
|
import { InquiryList } from '@/types/Inquiry'
|
||||||
import { usePathname, useRouter } from 'next/navigation'
|
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
||||||
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
|
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
|
||||||
import { useSessionStore } from '@/store/session'
|
import { useSessionStore } from '@/store/session'
|
||||||
import ListForm from './ListForm'
|
import ListForm from './ListForm'
|
||||||
@ -26,27 +26,37 @@ export default function ListTable() {
|
|||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
|
|
||||||
const { inquiryList, isLoadingInquiryList } = useInquiry(undefined, true)
|
const { inquiryList, isLoadingInquiryList } = useInquiry(undefined, true)
|
||||||
const { inquiryListRequest, setInquiryListRequest, reset, offset, setOffset } = useInquiryFilterStore()
|
const { inquiryListRequest, setInquiryListRequest, reset, offset, setOffset, isMyInquiry, setIsMyInquiry } = useInquiryFilterStore()
|
||||||
|
|
||||||
const [hasMore, setHasMore] = useState(false)
|
const [hasMore, setHasMore] = useState(false)
|
||||||
|
|
||||||
const [heldInquiryList, setHeldInquiryList] = useState<InquiryList[]>([])
|
const [heldInquiryList, setHeldInquiryList] = useState<InquiryList[]>([])
|
||||||
|
|
||||||
const { session } = useSessionStore()
|
const { session } = useSessionStore()
|
||||||
|
const searchParams = useSearchParams()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setOffset(1)
|
setOffset(1)
|
||||||
setHeldInquiryList([])
|
setHeldInquiryList([])
|
||||||
}, [pathname])
|
}, [pathname, searchParams])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!session.isLoggedIn || isLoadingInquiryList) return
|
if (!session.isLoggedIn || isLoadingInquiryList) return
|
||||||
if (session.isLoggedIn) {
|
if (session.isLoggedIn) {
|
||||||
setInquiryListRequest({ ...inquiryListRequest, storeId: session.storeId ?? '', loginId: session.userId ?? '' })
|
setInquiryListRequest({ ...inquiryListRequest, storeId: session.storeId ?? '', loginId: session.userId ?? '' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (searchParams.get('isMyInquiry') === 'true') {
|
||||||
|
setIsMyInquiry(session.userId)
|
||||||
|
router.replace('/inquiry/list')
|
||||||
|
} else if (searchParams.get('isMyInquiry') === 'false') {
|
||||||
|
reset()
|
||||||
|
router.replace('/inquiry/list')
|
||||||
|
}
|
||||||
|
|
||||||
if (inquiryList.length > 0 && inquiryList[0].totCnt > 0) {
|
if (inquiryList.length > 0 && inquiryList[0].totCnt > 0) {
|
||||||
if (offset > 1) {
|
if (offset > 1) {
|
||||||
setHeldInquiryList([...heldInquiryList, ...inquiryList])
|
setHeldInquiryList((prev) => [...prev, ...inquiryList])
|
||||||
} else {
|
} else {
|
||||||
setHeldInquiryList(inquiryList)
|
setHeldInquiryList(inquiryList)
|
||||||
}
|
}
|
||||||
@ -55,15 +65,12 @@ export default function ListTable() {
|
|||||||
setHeldInquiryList([])
|
setHeldInquiryList([])
|
||||||
setHasMore(false)
|
setHasMore(false)
|
||||||
}
|
}
|
||||||
}, [session, inquiryList])
|
}, [session, inquiryList, searchParams])
|
||||||
|
|
||||||
/** 내 문의 필터 처리 - 체크 시 자신의 문의 목록만 조회 */
|
/** 내 문의 필터 처리 - 체크 시 자신의 문의 목록만 조회 */
|
||||||
const handleMyInquiry = () => {
|
const handleMyInquiry = () => {
|
||||||
setOffset(1)
|
setOffset(1)
|
||||||
setInquiryListRequest({
|
setIsMyInquiry(isMyInquiry ? null : session.userId)
|
||||||
...inquiryListRequest,
|
|
||||||
schRegId: inquiryListRequest.schRegId ? null : session.userId,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 답변 여부 필터 처리리 */
|
/** 답변 여부 필터 처리리 */
|
||||||
@ -76,7 +83,7 @@ export default function ListTable() {
|
|||||||
setInquiryListRequest({ ...inquiryListRequest, schAnswerYn: 'Y' })
|
setInquiryListRequest({ ...inquiryListRequest, schAnswerYn: 'Y' })
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
reset()
|
setInquiryListRequest({ ...inquiryListRequest, schAnswerYn: null })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,7 +95,7 @@ export default function ListTable() {
|
|||||||
<div className="inquiry-table-filter">
|
<div className="inquiry-table-filter">
|
||||||
<div className="filter-check">
|
<div className="filter-check">
|
||||||
<div className="check-form-box">
|
<div className="check-form-box">
|
||||||
<input type="checkbox" id="ch01" onChange={handleMyInquiry} checked={inquiryListRequest.schRegId === session.userId} />
|
<input type="checkbox" id="ch01" onChange={handleMyInquiry} checked={isMyInquiry === session.userId} />
|
||||||
<label htmlFor="ch01">私が書いたお問い合わせ</label>
|
<label htmlFor="ch01">私が書いたお問い合わせ</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import Image from 'next/image'
|
|||||||
import { usePopupController } from '@/store/popupController'
|
import { usePopupController } from '@/store/popupController'
|
||||||
import { useParams } from 'next/navigation'
|
import { useParams } from 'next/navigation'
|
||||||
import { useSurvey } from '@/hooks/useSurvey'
|
import { useSurvey } from '@/hooks/useSurvey'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
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'
|
||||||
@ -99,7 +99,7 @@ export default function SurveySaleSubmitPopup() {
|
|||||||
const FORM_FIELDS: FormField[] = [
|
const FORM_FIELDS: FormField[] = [
|
||||||
{ id: 'sender', name: '発送者', required: true },
|
{ id: 'sender', name: '発送者', required: true },
|
||||||
{ id: 'saleBase', name: '提出地点選択', required: session?.role === 'Admin' },
|
{ id: 'saleBase', name: '提出地点選択', required: session?.role === 'Admin' },
|
||||||
{ id: 'targetNm', name: '提出販売店', required: session?.role !== 'Admin' },
|
{ id: 'targetNm', name: '提出販売店', required: session?.role !== 'Admin' && session?.role !== 'T01' },
|
||||||
{ id: 'receiver', name: '受信者', required: true },
|
{ id: 'receiver', name: '受信者', required: true },
|
||||||
{ id: 'reference', name: '参考', required: false },
|
{ id: 'reference', name: '参考', required: false },
|
||||||
{ id: 'title', name: 'タイトル', required: true },
|
{ id: 'title', name: 'タイトル', required: true },
|
||||||
@ -176,7 +176,7 @@ export default function SurveySaleSubmitPopup() {
|
|||||||
</p>
|
</p>
|
||||||
<p style="font-size: 13px; font-weight: 400; color: #2e3a59; margin-bottom: 15px;">
|
<p style="font-size: 13px; font-weight: 400; color: #2e3a59; margin-bottom: 15px;">
|
||||||
-施工店名:
|
-施工店名:
|
||||||
<span style="color: #417DDC;">${surveyDetail?.constructionPoint}</span>
|
<span style="color: #417DDC;">${surveyDetail?.constructionPoint ?? ' - '}</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
@ -230,7 +230,12 @@ export default function SurveySaleSubmitPopup() {
|
|||||||
if (selectedOffice) {
|
if (selectedOffice) {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const receiver = selectedOffice.REF_CHR1.split(';')
|
const receiver = selectedOffice.REF_CHR1.split(';')
|
||||||
setSubmitData((prev) => ({ ...prev, receiver: receiver, saleBase: e.target.value }))
|
setSubmitData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
receiver: receiver,
|
||||||
|
saleBase: e.target.value,
|
||||||
|
targetNm: selectedOffice.codeJp ?? '',
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import type { Mode, SurveyBasicRequest, SurveyDetailInfo, SurveyDetailRequest } from '@/types/Survey'
|
import type { Mode, SurveyBasicRequest, SurveyDetailInfo, SurveyDetailRequest } from '@/types/Survey'
|
||||||
import { useSessionStore } from '@/store/session'
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import { useParams, useRouter } from 'next/navigation'
|
|
||||||
import { requiredFields, useSurvey } from '@/hooks/useSurvey'
|
|
||||||
import { usePopupController } from '@/store/popupController'
|
|
||||||
import { CONFIRM_MESSAGE, SUCCESS_MESSAGE, useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
import { CONFIRM_MESSAGE, SUCCESS_MESSAGE, useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
||||||
|
import { useSessionStore } from '@/store/session'
|
||||||
|
import { useParams, useRouter } from 'next/navigation'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { usePopupController } from '@/store/popupController'
|
||||||
|
import { requiredFields, useSurvey } from '@/hooks/useSurvey'
|
||||||
|
|
||||||
interface ButtonFormProps {
|
interface ButtonFormProps {
|
||||||
mode: Mode
|
mode: Mode
|
||||||
@ -68,7 +68,10 @@ export default function ButtonForm({ mode, setMode, data }: ButtonFormProps) {
|
|||||||
const calculatePermissions = (session: any, basicData: SurveyBasicRequest): PermissionState => {
|
const calculatePermissions = (session: any, basicData: SurveyBasicRequest): PermissionState => {
|
||||||
const isSubmiter = calculateSubmitPermission(session, basicData)
|
const isSubmiter = calculateSubmitPermission(session, basicData)
|
||||||
const isWriter = session.userId === basicData.representativeId
|
const isWriter = session.userId === basicData.representativeId
|
||||||
const isReceiver = session?.storeId === basicData.submissionTargetId || session?.storeNm === basicData.submissionTargetNm
|
const isReceiver =
|
||||||
|
session?.storeId === basicData.submissionTargetId ||
|
||||||
|
session?.storeNm === basicData.submissionTargetNm ||
|
||||||
|
(session?.role === 'T01' && basicData.submissionStatus && basicData.submissionTargetId === null && basicData.submissionTargetNm !== null)
|
||||||
|
|
||||||
return { isSubmiter, isWriter, isReceiver }
|
return { isSubmiter, isWriter, isReceiver }
|
||||||
}
|
}
|
||||||
@ -77,10 +80,10 @@ export default function ButtonForm({ mode, setMode, data }: ButtonFormProps) {
|
|||||||
const calculateSubmitPermission = (session: any, basicData: SurveyBasicRequest): boolean => {
|
const calculateSubmitPermission = (session: any, basicData: SurveyBasicRequest): boolean => {
|
||||||
switch (session?.role) {
|
switch (session?.role) {
|
||||||
case 'T01':
|
case 'T01':
|
||||||
return false
|
|
||||||
case 'Admin':
|
case 'Admin':
|
||||||
|
return session.storeId === basicData.storeId
|
||||||
case 'Admin_Sub':
|
case 'Admin_Sub':
|
||||||
return session.storeNm === basicData.store && session.builderId === basicData.constructionPointId
|
return session.storeId === basicData.storeId && session.builderId === basicData.constructionPointId
|
||||||
case 'Builder':
|
case 'Builder':
|
||||||
case 'Partner':
|
case 'Partner':
|
||||||
return session.builderId === basicData.constructionPointId
|
return session.builderId === basicData.constructionPointId
|
||||||
@ -197,15 +200,12 @@ export default function ButtonForm({ mode, setMode, data }: ButtonFormProps) {
|
|||||||
|
|
||||||
/** 제출 로직 */
|
/** 제출 로직 */
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (data.basic.srlNo?.startsWith('一時保存') && Number.isNaN(id)) {
|
|
||||||
showErrorAlert(WARNING_MESSAGE.TEMP_CANNOT_SUBMIT)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode === 'READ') {
|
if (mode === 'READ') {
|
||||||
showConfirm(CONFIRM_MESSAGE.SUBMIT_CONFIRM, async () => {
|
if (data.basic.srlNo?.includes('一時保存')) {
|
||||||
popupController.setSurveySaleSubmitPopup(true)
|
showErrorAlert(WARNING_MESSAGE.TEMP_CANNOT_SUBMIT)
|
||||||
})
|
return
|
||||||
|
}
|
||||||
|
popupController.setSurveySaleSubmitPopup(true)
|
||||||
} else {
|
} else {
|
||||||
showConfirm(CONFIRM_MESSAGE.SAVE_AND_SUBMIT_CONFIRM, async () => {
|
showConfirm(CONFIRM_MESSAGE.SAVE_AND_SUBMIT_CONFIRM, async () => {
|
||||||
handleSave(false, true)
|
handleSave(false, true)
|
||||||
@ -216,7 +216,7 @@ export default function ButtonForm({ mode, setMode, data }: ButtonFormProps) {
|
|||||||
/** 로그인 여부 체크 */
|
/** 로그인 여부 체크 */
|
||||||
if (!session?.isLoggedIn) return null
|
if (!session?.isLoggedIn) return null
|
||||||
|
|
||||||
/** 읽기 모드, 제출 된 데이터, 제출 권한자는 리스트 버튼만 표시 */
|
/** 읽기 모드, 제출 된 데이터, 제출 권한자는 리스트 버튼만 표시, 작성자만 삭제 가능*/
|
||||||
if (mode === 'READ' && isSubmit && permissions.isSubmiter) {
|
if (mode === 'READ' && isSubmit && permissions.isSubmiter) {
|
||||||
return (
|
return (
|
||||||
<div className="sale-form-btn-wrap">
|
<div className="sale-form-btn-wrap">
|
||||||
@ -254,7 +254,7 @@ export default function ButtonForm({ mode, setMode, data }: ButtonFormProps) {
|
|||||||
<ListButton />
|
<ListButton />
|
||||||
<TempButton handleSave={() => handleSave(true, false)} />
|
<TempButton handleSave={() => handleSave(true, false)} />
|
||||||
<SaveButton handleSave={() => handleSave(false, false)} />
|
<SaveButton handleSave={() => handleSave(false, false)} />
|
||||||
{session?.role === 'T01' || isSubmit ? null : <SubmitButton handleSubmit={handleSubmit} />}
|
{!isSubmit && permissions.isSubmiter && <SubmitButton handleSubmit={handleSubmit} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,21 +1,18 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useRouter } from 'next/navigation'
|
|
||||||
import { SurveyBasicInfo } from '@/types/Survey'
|
import { SurveyBasicInfo } from '@/types/Survey'
|
||||||
import { useSurvey } from '@/hooks/useSurvey'
|
import { useSurvey } from '@/hooks/useSurvey'
|
||||||
|
|
||||||
export default function DataTable({ surveyDetail }: { surveyDetail: SurveyBasicInfo }) {
|
export default function DataTable({ surveyDetail }: { surveyDetail: SurveyBasicInfo }) {
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
/** 제출 상태 처리 */
|
/** 제출 상태 처리 */
|
||||||
const submitStatus = () => {
|
const submitStatus = () => {
|
||||||
const { submissionTargetNm, submissionTargetId } = surveyDetail ?? {}
|
const { submissionTargetNm, submissionTargetId } = surveyDetail ?? {}
|
||||||
if (!submissionTargetId && !submissionTargetNm) {
|
|
||||||
return <div>( Hanwha Japan )</div>
|
|
||||||
}
|
|
||||||
if (!submissionTargetId && submissionTargetNm) {
|
if (!submissionTargetId && submissionTargetNm) {
|
||||||
return <div>( {submissionTargetNm} )</div>
|
return <div>( {submissionTargetNm} )</div>
|
||||||
}
|
}
|
||||||
|
if (!submissionTargetId && !submissionTargetNm) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
({submissionTargetNm} - {submissionTargetId})
|
({submissionTargetNm} - {submissionTargetId})
|
||||||
@ -67,9 +64,13 @@ export default function DataTable({ surveyDetail }: { surveyDetail: SurveyBasicI
|
|||||||
<tr>
|
<tr>
|
||||||
<th>ダウンロード</th>
|
<th>ダウンロード</th>
|
||||||
<td>
|
<td>
|
||||||
<button className="data-down" onClick={() => downloadSurveyPdf(surveyDetail.id, `${surveyDetail.srlNo}.pdf`)}>
|
{surveyDetail.submissionStatus ? (
|
||||||
HWJ現地調査票確認<i className="down-icon"></i>
|
<button className="data-down" onClick={() => downloadSurveyPdf(surveyDetail.id, `${surveyDetail.srlNo}.pdf`)}>
|
||||||
</button>
|
HWJ現地調査票確認<i className="down-icon"></i>
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
'-'
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@ -262,7 +262,14 @@ export default function RoofForm(props: {
|
|||||||
id="memo"
|
id="memo"
|
||||||
value={roofInfo?.memo ?? ''}
|
value={roofInfo?.memo ?? ''}
|
||||||
disabled={mode === 'READ'}
|
disabled={mode === 'READ'}
|
||||||
onChange={(e) => setRoofInfo({ ...roofInfo, memo: e.target.value })}
|
onChange={(e) => {
|
||||||
|
if (e.target.value.length >= 2000) {
|
||||||
|
showErrorAlert(WARNING_MESSAGE.CONTENTS_MAX_LENGTH)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setRoofInfo({ ...roofInfo, memo: e.target.value })
|
||||||
|
}}
|
||||||
|
maxLength={2000}
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import LoadMoreButton from '@/components/LoadMoreButton'
|
import LoadMoreButton from '@/components/LoadMoreButton'
|
||||||
import { useSurvey } from '@/hooks/useSurvey'
|
import { useSurvey } from '@/hooks/useSurvey'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useRouter, usePathname } from 'next/navigation'
|
import { useRouter, usePathname, useSearchParams } from 'next/navigation'
|
||||||
import SearchForm from './SearchForm'
|
import SearchForm from './SearchForm'
|
||||||
import { useSurveyFilterStore } from '@/store/surveyFilterStore'
|
import { useSurveyFilterStore } from '@/store/surveyFilterStore'
|
||||||
import { useSessionStore } from '@/store/session'
|
import { useSessionStore } from '@/store/session'
|
||||||
@ -14,20 +14,32 @@ export default function ListTable() {
|
|||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
|
|
||||||
const { surveyList, isLoadingSurveyList } = useSurvey()
|
const { surveyList, isLoadingSurveyList } = useSurvey()
|
||||||
const { offset, setOffset } = useSurveyFilterStore()
|
const { offset, setOffset, setIsMySurvey, reset } = useSurveyFilterStore()
|
||||||
|
|
||||||
const { session } = useSessionStore()
|
const { session } = useSessionStore()
|
||||||
|
|
||||||
const [heldSurveyList, setHeldSurveyList] = useState<SurveyBasicInfo[]>([])
|
const [heldSurveyList, setHeldSurveyList] = useState<SurveyBasicInfo[]>([])
|
||||||
const [hasMore, setHasMore] = useState(false)
|
const [hasMore, setHasMore] = useState(false)
|
||||||
|
|
||||||
|
const searchParams = useSearchParams()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setOffset(0)
|
setOffset(0)
|
||||||
setHeldSurveyList([])
|
setHeldSurveyList([])
|
||||||
}, [pathname])
|
}, [pathname, searchParams])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoadingSurveyList) return
|
if (searchParams.get('isMySurvey') === 'true') {
|
||||||
|
setIsMySurvey(session.userId)
|
||||||
|
router.replace('/survey-sale')
|
||||||
|
} else if (searchParams.get('isMySurvey') === 'false') {
|
||||||
|
reset()
|
||||||
|
router.replace('/survey-sale')
|
||||||
|
}
|
||||||
|
}, [searchParams])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isLoadingSurveyList || !session.isLoggedIn) return
|
||||||
|
|
||||||
if ('count' in surveyList && surveyList.count > 0) {
|
if ('count' in surveyList && surveyList.count > 0) {
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
setHeldSurveyList((prev) => [...prev, ...surveyList.data])
|
setHeldSurveyList((prev) => [...prev, ...surveyList.data])
|
||||||
@ -39,7 +51,7 @@ export default function ListTable() {
|
|||||||
setHeldSurveyList([])
|
setHeldSurveyList([])
|
||||||
setHasMore(false)
|
setHasMore(false)
|
||||||
}
|
}
|
||||||
}, [surveyList, offset, isLoadingSurveyList])
|
}, [surveyList, offset, isLoadingSurveyList, searchParams])
|
||||||
|
|
||||||
const handleDetailClick = (id: number) => {
|
const handleDetailClick = (id: number) => {
|
||||||
router.push(`/survey-sale/${id}`)
|
router.push(`/survey-sale/${id}`)
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { SEARCH_OPTIONS, SEARCH_OPTIONS_ENUM, SEARCH_OPTIONS_PARTNERS, useSurveyFilterStore } from '@/store/surveyFilterStore'
|
import { SEARCH_OPTIONS, SEARCH_OPTIONS_ENUM, SEARCH_OPTIONS_PARTNERS, useSurveyFilterStore } from '@/store/surveyFilterStore'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
import { useAlertMsg, WARNING_MESSAGE } from '@/hooks/useAlertMsg'
|
||||||
|
|
||||||
export default function SearchForm({ memberRole, userId }: { memberRole: string; userId: string }) {
|
export default function SearchForm({ memberRole, userId }: { memberRole: string; userId: string }) {
|
||||||
@ -11,6 +11,13 @@ export default function SearchForm({ memberRole, userId }: { memberRole: string;
|
|||||||
const { setSearchOption, setSort, setIsMySurvey, setKeyword, isMySurvey, keyword, searchOption, sort, setOffset } = useSurveyFilterStore()
|
const { setSearchOption, setSort, setIsMySurvey, setKeyword, isMySurvey, keyword, searchOption, sort, setOffset } = useSurveyFilterStore()
|
||||||
const [searchKeyword, setSearchKeyword] = useState(keyword)
|
const [searchKeyword, setSearchKeyword] = useState(keyword)
|
||||||
const [option, setOption] = useState(searchOption)
|
const [option, setOption] = useState(searchOption)
|
||||||
|
const searchParams = useSearchParams()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (searchParams.get('isMySurvey') === 'false') {
|
||||||
|
setSearchKeyword('')
|
||||||
|
}
|
||||||
|
}, [searchParams])
|
||||||
|
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
if (option !== 'id' && searchKeyword.trim().length < 2) {
|
if (option !== 'id' && searchKeyword.trim().length < 2) {
|
||||||
@ -39,8 +46,6 @@ export default function SearchForm({ memberRole, userId }: { memberRole: string;
|
|||||||
value={option}
|
value={option}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (e.target.value === 'all') {
|
if (e.target.value === 'all') {
|
||||||
setKeyword('')
|
|
||||||
setSearchKeyword('')
|
|
||||||
setSearchOption('all')
|
setSearchOption('all')
|
||||||
setOption('all')
|
setOption('all')
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export default function Main() {
|
|||||||
<div className="main-bx-icon">
|
<div className="main-bx-icon">
|
||||||
<img src="/assets/images/main/main_icon01.svg" alt="" />
|
<img src="/assets/images/main/main_icon01.svg" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<button className="main-bx-arr" onClick={() => router.push('/survey-sale')}></button>
|
<button className="main-bx-arr" onClick={() => router.push('/survey-sale?isMySurvey=false')}></button>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-bx-body">
|
<div className="grid-bx-body">
|
||||||
<div className="grid-bx-body-tit">調査物件一覧</div>
|
<div className="grid-bx-body-tit">調査物件一覧</div>
|
||||||
@ -46,7 +46,7 @@ export default function Main() {
|
|||||||
<div className="main-bx-icon">
|
<div className="main-bx-icon">
|
||||||
<img src="/assets/images/main/main_icon03.svg" alt="" />
|
<img src="/assets/images/main/main_icon03.svg" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<button className="main-bx-arr" onClick={() => router.push('/inquiry/list')}></button>
|
<button className="main-bx-arr" onClick={() => router.push('/inquiry/list?isMyInquiry=false')}></button>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-bx-body">
|
<div className="grid-bx-body">
|
||||||
<div className="grid-bx-body-tit">1:1お問い合わせ リスト</div>
|
<div className="grid-bx-body-tit">1:1お問い合わせ リスト</div>
|
||||||
|
|||||||
@ -11,8 +11,6 @@ import { useSideNavState } from '@/store/sideNavState'
|
|||||||
import { useHeaderStore } from '@/store/header'
|
import { useHeaderStore } from '@/store/header'
|
||||||
import { useSessionStore } from '@/store/session'
|
import { useSessionStore } from '@/store/session'
|
||||||
import { usePopupController } from '@/store/popupController'
|
import { usePopupController } from '@/store/popupController'
|
||||||
import { useSurveyFilterStore } from '@/store/surveyFilterStore'
|
|
||||||
import { useInquiryFilterStore } from '@/store/inquiryFilterStore'
|
|
||||||
|
|
||||||
import { useTitle } from '@/hooks/useTitle'
|
import { useTitle } from '@/hooks/useTitle'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
@ -32,9 +30,6 @@ export default function Header() {
|
|||||||
|
|
||||||
const popupController = usePopupController()
|
const popupController = usePopupController()
|
||||||
|
|
||||||
const { setIsMySurvey } = useSurveyFilterStore()
|
|
||||||
const { setInquiryListRequest, inquiryListRequest } = useInquiryFilterStore()
|
|
||||||
|
|
||||||
if (pathname === '/login') {
|
if (pathname === '/login') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -88,8 +83,7 @@ export default function Header() {
|
|||||||
<div
|
<div
|
||||||
className="side-swiper-card"
|
className="side-swiper-card"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsMySurvey(session?.userId)
|
router.push('/survey-sale?isMySurvey=true')
|
||||||
router.push('/survey-sale')
|
|
||||||
setSideNavIsOpen(false)
|
setSideNavIsOpen(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -101,8 +95,7 @@ export default function Header() {
|
|||||||
<div
|
<div
|
||||||
className="side-swiper-card"
|
className="side-swiper-card"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setInquiryListRequest({ ...inquiryListRequest, schRegId: session?.userId })
|
router.push('/inquiry/list?isMyInquiry=true')
|
||||||
router.push('/inquiry/list')
|
|
||||||
setSideNavIsOpen(false)
|
setSideNavIsOpen(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -28,8 +28,8 @@ export const SUCCESS_MESSAGE = {
|
|||||||
* @description 확인 메세지 상수 객체
|
* @description 확인 메세지 상수 객체
|
||||||
*/
|
*/
|
||||||
export const CONFIRM_MESSAGE = {
|
export const CONFIRM_MESSAGE = {
|
||||||
/** 제출 확인 - "제출하시겠습니까?" */
|
/** 제출 확인 - "전송하시겠습니까? 전송 후에는 수정/삭제 할 수 없습니다." */
|
||||||
SUBMIT_CONFIRM: '提出しますか?',
|
SUBMIT_CONFIRM: '送信しますか? 送信後は変更・修正することはできません。',
|
||||||
|
|
||||||
/** 저장 확인 - "저장하시겠습니까?" */
|
/** 저장 확인 - "저장하시겠습니까?" */
|
||||||
SAVE_CONFIRM: '保存しますか?',
|
SAVE_CONFIRM: '保存しますか?',
|
||||||
@ -56,7 +56,7 @@ export const WARNING_MESSAGE = {
|
|||||||
EMAIL_PREFIX_IS_INVALID: '有効なメールアドレスを入力してください。',
|
EMAIL_PREFIX_IS_INVALID: '有効なメールアドレスを入力してください。',
|
||||||
|
|
||||||
/** 최소값 오류 - "2자 이상 입력하세요" */
|
/** 최소값 오류 - "2자 이상 입력하세요" */
|
||||||
KEYWORD_MINIMUM_LENGTH: '2文字以上入力してください',
|
KEYWORD_MINIMUM_LENGTH: 'タイトルを入力してください(2文字以上)。',
|
||||||
|
|
||||||
/** 최대값 오류 - "30자 이내로 입력하세요" */
|
/** 최대값 오류 - "30자 이내로 입력하세요" */
|
||||||
KEYWORD_MAX_LENGTH: '30文字以内で入力してください',
|
KEYWORD_MAX_LENGTH: '30文字以内で入力してください',
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export function useInquiry(
|
|||||||
commonCodeList: CommonCode[]
|
commonCodeList: CommonCode[]
|
||||||
} {
|
} {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const { inquiryListRequest, offset } = useInquiryFilterStore()
|
const { inquiryListRequest, offset, isMyInquiry } = useInquiryFilterStore()
|
||||||
const { axiosInstance } = useAxios()
|
const { axiosInstance } = useAxios()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { showErrorAlert } = useAlertMsg()
|
const { showErrorAlert } = useAlertMsg()
|
||||||
@ -104,7 +104,7 @@ export function useInquiry(
|
|||||||
* @returns {boolean} isLoading - 문의사항 목록 로딩 상태
|
* @returns {boolean} isLoading - 문의사항 목록 로딩 상태
|
||||||
*/
|
*/
|
||||||
const { data: inquiryList, isLoading: isLoadingInquiryList } = useQuery({
|
const { data: inquiryList, isLoading: isLoadingInquiryList } = useQuery({
|
||||||
queryKey: ['inquiryList', inquiryListRequest, offset],
|
queryKey: ['inquiryList', inquiryListRequest.loginId, inquiryListRequest.schTitle, inquiryListRequest.schAnswerYn, offset, isMyInquiry],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const isListQuery = true
|
const isListQuery = true
|
||||||
const shouldThrowError = false
|
const shouldThrowError = false
|
||||||
@ -112,7 +112,7 @@ export function useInquiry(
|
|||||||
const resp = await tryFunction(
|
const resp = await tryFunction(
|
||||||
() =>
|
() =>
|
||||||
axiosInstance(null).get<{ data: InquiryList[] }>(`/api/qna/list`, {
|
axiosInstance(null).get<{ data: InquiryList[] }>(`/api/qna/list`, {
|
||||||
params: { inquiryListRequest, startRow: offset, endRow: offset + 9 },
|
params: { inquiryListRequest, startRow: offset, endRow: offset + 9, schRegId: isMyInquiry },
|
||||||
}),
|
}),
|
||||||
isListQuery,
|
isListQuery,
|
||||||
shouldThrowError,
|
shouldThrowError,
|
||||||
|
|||||||
@ -253,7 +253,6 @@ export function useSurvey(
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
console.log(resp)
|
|
||||||
const blob = await resp.blob()
|
const blob = await resp.blob()
|
||||||
|
|
||||||
if (!blob || blob.size === 0) {
|
if (!blob || blob.size === 0) {
|
||||||
@ -264,7 +263,7 @@ export function useSurvey(
|
|||||||
const url = window.URL.createObjectURL(blob)
|
const url = window.URL.createObjectURL(blob)
|
||||||
const a = document.createElement('a')
|
const a = document.createElement('a')
|
||||||
a.href = url
|
a.href = url
|
||||||
a.download = `${filename}.pdf`
|
a.download = `${filename}`
|
||||||
a.click()
|
a.click()
|
||||||
window.URL.revokeObjectURL(url)
|
window.URL.revokeObjectURL(url)
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,8 @@ type InquiryFilterState = {
|
|||||||
reset: () => void
|
reset: () => void
|
||||||
offset: number
|
offset: number
|
||||||
setOffset: (offset: number) => void
|
setOffset: (offset: number) => void
|
||||||
|
isMyInquiry: string | null
|
||||||
|
setIsMyInquiry: (isMyInquiry: string | null) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,7 +30,6 @@ export const useInquiryFilterStore = create<InquiryFilterState>((set) => ({
|
|||||||
storeId: '',
|
storeId: '',
|
||||||
siteTpCd: 'QC',
|
siteTpCd: 'QC',
|
||||||
schTitle: null,
|
schTitle: null,
|
||||||
schRegId: null,
|
|
||||||
schFromDt: null,
|
schFromDt: null,
|
||||||
schToDt: null,
|
schToDt: null,
|
||||||
schAnswerYn: null,
|
schAnswerYn: null,
|
||||||
@ -42,15 +43,17 @@ export const useInquiryFilterStore = create<InquiryFilterState>((set) => ({
|
|||||||
langCd: 'JA',
|
langCd: 'JA',
|
||||||
storeId: '',
|
storeId: '',
|
||||||
siteTpCd: 'QC',
|
siteTpCd: 'QC',
|
||||||
schTitle: '',
|
schTitle: null,
|
||||||
schRegId: '',
|
schFromDt: null,
|
||||||
schFromDt: '',
|
schToDt: null,
|
||||||
schToDt: '',
|
|
||||||
schAnswerYn: null,
|
schAnswerYn: null,
|
||||||
loginId: '',
|
loginId: '',
|
||||||
},
|
},
|
||||||
offset: 1,
|
offset: 1,
|
||||||
|
isMyInquiry: null,
|
||||||
}),
|
}),
|
||||||
offset: 1,
|
offset: 1,
|
||||||
setOffset: (offset) => set({ offset }),
|
setOffset: (offset) => set({ offset }),
|
||||||
|
isMyInquiry: null,
|
||||||
|
setIsMyInquiry: (isMyInquiry) => set({ isMyInquiry }),
|
||||||
}))
|
}))
|
||||||
|
|||||||
@ -12,8 +12,6 @@ export type InquiryListRequest = {
|
|||||||
siteTpCd: string
|
siteTpCd: string
|
||||||
/* 검색 제목 */
|
/* 검색 제목 */
|
||||||
schTitle: string | null
|
schTitle: string | null
|
||||||
/* 검색 등록자 ID */
|
|
||||||
schRegId: string | null
|
|
||||||
/* 검색 시작 일자 */
|
/* 검색 시작 일자 */
|
||||||
schFromDt: string | null
|
schFromDt: string | null
|
||||||
/* 검색 종료 일자 */
|
/* 검색 종료 일자 */
|
||||||
|
|||||||
@ -324,7 +324,6 @@ export type SurveySearchParams = {
|
|||||||
builderId?: string | null
|
builderId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type RadioEtcKeys =
|
type RadioEtcKeys =
|
||||||
| 'structureOrder'
|
| 'structureOrder'
|
||||||
| 'houseStructure'
|
| 'houseStructure'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user