fix: fix rendering issue
- 매물 수정/작성 시 담당자명, 판매점명, 시공점명 랜더링 안되는 문제 해결 - T01 계정 수정 버튼 랜더링 안되는 문제 해결
This commit is contained in:
parent
0c27c19341
commit
50617c7b7f
@ -1,7 +1,6 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@/libs/prisma'
|
||||
import { convertToSnakeCase } from '@/utils/common-utils'
|
||||
import { SessionData } from '@/types/Auth'
|
||||
|
||||
interface Survey {
|
||||
SRL_NO: string
|
||||
|
||||
@ -8,45 +8,34 @@ import { usePopupController } from '@/store/popupController'
|
||||
import { useAddressStore } from '@/store/addressStore'
|
||||
import { SessionData } from '@/types/Auth'
|
||||
|
||||
export default function BasicForm(props: {
|
||||
interface BasicFormProps {
|
||||
basicInfo: SurveyBasicRequest
|
||||
setBasicInfo: (basicInfo: SurveyBasicRequest) => void
|
||||
mode: Mode
|
||||
session: SessionData
|
||||
}) {
|
||||
const { basicInfo, setBasicInfo, mode, session } = props
|
||||
}
|
||||
|
||||
export default function BasicForm({ basicInfo, setBasicInfo, mode, session }: BasicFormProps) {
|
||||
const { setBasicInfoSelected } = useSurveySaleTabState()
|
||||
const [isFlip, setIsFlip] = useState<boolean>(true)
|
||||
|
||||
const { addressData } = useAddressStore()
|
||||
const popupController = usePopupController()
|
||||
|
||||
useEffect(() => {
|
||||
setBasicInfoSelected()
|
||||
}, [])
|
||||
|
||||
// 주소 데이터가 변경될 때만 업데이트
|
||||
useEffect(() => {
|
||||
if (session?.isLoggedIn) {
|
||||
setBasicInfo({
|
||||
...basicInfo,
|
||||
representative: session.userNm ?? '',
|
||||
representativeId: session.userId ?? null,
|
||||
store: session.storeNm ?? null,
|
||||
storeId: session.storeId ?? null,
|
||||
constructionPoint: session.builderNm ?? null,
|
||||
constructionPointId: session.builderNo ?? null,
|
||||
})
|
||||
}
|
||||
if (addressData) {
|
||||
if (!addressData) return
|
||||
|
||||
setBasicInfo({
|
||||
...basicInfo,
|
||||
postCode: addressData.post_code,
|
||||
address: addressData.address,
|
||||
addressDetail: addressData.address_detail,
|
||||
})
|
||||
}
|
||||
}, [session, addressData])
|
||||
|
||||
const popupController = usePopupController()
|
||||
}, [addressData])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -7,79 +7,88 @@ import { useParams, useRouter, useSearchParams } from 'next/navigation'
|
||||
import { requiredFields, useSurvey } from '@/hooks/useSurvey'
|
||||
import { usePopupController } from '@/store/popupController'
|
||||
|
||||
export default function ButtonForm(props: {
|
||||
interface ButtonFormProps {
|
||||
mode: Mode
|
||||
setMode: (mode: Mode) => void
|
||||
data: { basic: SurveyBasicRequest; roof: SurveyDetailRequest }
|
||||
}) {
|
||||
// 라우터
|
||||
const router = useRouter()
|
||||
const { mode, setMode } = props
|
||||
const { session } = useSessionStore()
|
||||
data: {
|
||||
basic: SurveyBasicRequest
|
||||
roof: SurveyDetailRequest
|
||||
}
|
||||
}
|
||||
|
||||
interface PermissionState {
|
||||
isSubmiter: boolean
|
||||
isWriter: boolean
|
||||
isReceiver: boolean
|
||||
}
|
||||
|
||||
interface SaveData extends SurveyBasicRequest {
|
||||
detailInfo: SurveyDetailRequest
|
||||
}
|
||||
|
||||
export default function ButtonForm({ mode, setMode, data }: ButtonFormProps) {
|
||||
const router = useRouter()
|
||||
const { session } = useSessionStore()
|
||||
const searchParams = useSearchParams()
|
||||
const idParam = searchParams.get('id')
|
||||
|
||||
const params = useParams()
|
||||
const routeId = params.id
|
||||
|
||||
const popupController = usePopupController()
|
||||
// ------------------------------------------------------------
|
||||
const [saveData, setSaveData] = useState({
|
||||
...props.data.basic,
|
||||
detailInfo: props.data.roof,
|
||||
|
||||
const [saveData, setSaveData] = useState<SaveData>({
|
||||
...data.basic,
|
||||
detailInfo: data.roof,
|
||||
})
|
||||
// --------------------------------------------------------------
|
||||
// 권한
|
||||
|
||||
// 제출권한 있는 회원
|
||||
const [isSubmiter, setIsSubmiter] = useState(false)
|
||||
// 작성자
|
||||
const [isWriter, setIsWriter] = useState(false)
|
||||
// 제출받은 대상자
|
||||
const [isReceiver, setIsReceiver] = useState(false)
|
||||
const isSubmit = props.data.basic.submissionStatus
|
||||
|
||||
useEffect(() => {
|
||||
if (session?.isLoggedIn) {
|
||||
switch (session?.role) {
|
||||
// T01 제출권한 없음
|
||||
case 'T01':
|
||||
setIsSubmiter(false)
|
||||
setIsReceiver(!props.data.basic.submissionTargetId && !props.data.basic.submissionTargetNm)
|
||||
break
|
||||
// 1차 판매점(Order) + 2차 판매점(Musubi) => 같은 판매점 제출권한
|
||||
case 'Admin':
|
||||
case 'Admin_Sub':
|
||||
setIsSubmiter(session.storeNm === props.data.basic.store && session.builderNo === props.data.basic.constructionPointId)
|
||||
setIsReceiver(session?.storeId === props.data.basic.submissionTargetId)
|
||||
break
|
||||
// 시공권한 User(Musubi) + Partner => 같은 시공ID 제출권한
|
||||
case 'Builder':
|
||||
case 'Partner':
|
||||
setIsSubmiter(session.builderNo === props.data.basic.constructionPointId)
|
||||
break
|
||||
default:
|
||||
setIsSubmiter(false)
|
||||
break
|
||||
}
|
||||
setIsWriter(session.userNm === props.data.basic.representative)
|
||||
}
|
||||
setSaveData({
|
||||
...props.data.basic,
|
||||
detailInfo: props.data.roof,
|
||||
const [permissions, setPermissions] = useState<PermissionState>({
|
||||
isSubmiter: false,
|
||||
isWriter: false,
|
||||
isReceiver: false,
|
||||
})
|
||||
}, [session, props.data])
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 저장/임시저장/수정
|
||||
const isSubmit = data.basic.submissionStatus
|
||||
const id = Number(routeId) ? Number(routeId) : Number(idParam)
|
||||
|
||||
const { deleteSurvey, updateSurvey, isDeletingSurvey, isUpdatingSurvey } = useSurvey(Number(id))
|
||||
const { deleteSurvey, updateSurvey, isDeletingSurvey, isUpdatingSurvey } = useSurvey(id)
|
||||
const { validateSurveyDetail, createSurvey, isCreatingSurvey } = useSurvey()
|
||||
|
||||
useEffect(() => {
|
||||
if (!session?.isLoggedIn) return
|
||||
|
||||
const newPermissions = calculatePermissions(session, data.basic)
|
||||
setPermissions(newPermissions)
|
||||
|
||||
setSaveData({
|
||||
...data.basic,
|
||||
detailInfo: data.roof,
|
||||
})
|
||||
}, [session, data])
|
||||
|
||||
const calculatePermissions = (session: any, basicData: SurveyBasicRequest): PermissionState => {
|
||||
const isSubmiter = calculateSubmitPermission(session, basicData)
|
||||
const isWriter = session.userNm === basicData.representative
|
||||
const isReceiver = session?.storeId === basicData.submissionTargetId
|
||||
|
||||
return { isSubmiter, isWriter, isReceiver }
|
||||
}
|
||||
|
||||
const calculateSubmitPermission = (session: any, basicData: SurveyBasicRequest): boolean => {
|
||||
switch (session?.role) {
|
||||
case 'T01':
|
||||
return false
|
||||
case 'Admin':
|
||||
case 'Admin_Sub':
|
||||
return session.storeNm === basicData.store && session.builderNo === basicData.constructionPointId
|
||||
case 'Builder':
|
||||
case 'Partner':
|
||||
return session.builderNo === basicData.constructionPointId
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSave = (isTemporary: boolean, isSubmitProcess: boolean) => {
|
||||
const emptyField = validateSurveyDetail(props.data.roof)
|
||||
const emptyField = validateSurveyDetail(data.roof)
|
||||
const hasEmptyField = emptyField?.trim() !== ''
|
||||
|
||||
if (isTemporary) {
|
||||
@ -110,13 +119,18 @@ export default function ButtonForm(props: {
|
||||
|
||||
const focusInput = (field: keyof SurveyDetailInfo) => {
|
||||
const input = document.getElementById(field)
|
||||
if (input) {
|
||||
input.focus()
|
||||
}
|
||||
input?.focus()
|
||||
}
|
||||
|
||||
const saveProcess = async (emptyField: string | null, isSubmitProcess?: boolean) => {
|
||||
if (emptyField?.trim() === '') {
|
||||
await handleSuccessfulSave(isSubmitProcess)
|
||||
} else {
|
||||
handleFailedSave(emptyField)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSuccessfulSave = async (isSubmitProcess?: boolean) => {
|
||||
if (idParam) {
|
||||
await updateSurvey({ survey: saveData, isTemporary: false, storeId: session.storeId ?? '' })
|
||||
if (!isUpdatingSurvey) {
|
||||
@ -128,6 +142,7 @@ export default function ButtonForm(props: {
|
||||
router.push(`/survey-sale/${id}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (isSubmitProcess) {
|
||||
if (!isCreatingSurvey && !isUpdatingSurvey) {
|
||||
await popupController.setSurveySaleSubmitPopup(true)
|
||||
@ -135,18 +150,16 @@ export default function ButtonForm(props: {
|
||||
} else {
|
||||
alert('保存されました。')
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
const handleFailedSave = (emptyField: string | null) => {
|
||||
if (emptyField?.includes('Unit')) {
|
||||
alert('電気契約容量の単位を入力してください。')
|
||||
focusInput(emptyField as keyof SurveyDetailInfo)
|
||||
} else {
|
||||
alert(requiredFields.find((field) => field.field === emptyField)?.name + ' 項目が空です。')
|
||||
}
|
||||
focusInput(emptyField as keyof SurveyDetailInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------
|
||||
// 삭제/제출
|
||||
|
||||
const handleDelete = async () => {
|
||||
if (routeId) {
|
||||
@ -161,10 +174,11 @@ export default function ButtonForm(props: {
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (props.data.basic.srlNo?.startsWith('一時保存') && Number(routeId)) {
|
||||
if (data.basic.srlNo?.startsWith('一時保存') && Number(routeId)) {
|
||||
alert('一時保存されたデータは提出できません。')
|
||||
return
|
||||
}
|
||||
|
||||
if (Number(routeId)) {
|
||||
window.neoConfirm('提出しますか?', async () => {
|
||||
popupController.setSurveySaleSubmitPopup(true)
|
||||
@ -176,21 +190,15 @@ export default function ButtonForm(props: {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
if (!session?.isLoggedIn) return null
|
||||
|
||||
if (!session?.isLoggedIn) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
if (mode === 'READ' && isSubmit && isSubmiter) {
|
||||
if (mode === 'READ' && isSubmit && permissions.isSubmiter) {
|
||||
return (
|
||||
<>
|
||||
<div className="sale-form-btn-wrap">
|
||||
<div className="btn-flex-wrap">
|
||||
<ListButton />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -200,9 +208,11 @@ export default function ButtonForm(props: {
|
||||
<div className="sale-form-btn-wrap">
|
||||
<div className="btn-flex-wrap">
|
||||
<ListButton />
|
||||
{(isSubmiter || (isReceiver && isSubmit)) && <EditButton setMode={setMode} id={id.toString()} mode={mode} />}
|
||||
{(isWriter || (isReceiver && isSubmit)) && <DeleteButton handleDelete={handleDelete} />}
|
||||
{!isSubmit && isSubmiter && <SubmitButton handleSubmit={handleSubmit} />}
|
||||
{(permissions.isWriter || permissions.isSubmiter || (permissions.isReceiver && isSubmit)) && (
|
||||
<EditButton setMode={setMode} id={id.toString()} />
|
||||
)}
|
||||
{(permissions.isWriter || (permissions.isReceiver && isSubmit)) && <DeleteButton handleDelete={handleDelete} />}
|
||||
{!isSubmit && permissions.isSubmiter && <SubmitButton handleSubmit={handleSubmit} />}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@ -211,9 +221,9 @@ export default function ButtonForm(props: {
|
||||
<div className="sale-form-btn-wrap">
|
||||
<div className="btn-flex-wrap">
|
||||
<ListButton />
|
||||
<TempButton setMode={setMode} handleSave={() => handleSave(true, false)} />
|
||||
<TempButton handleSave={() => handleSave(true, false)} />
|
||||
<SaveButton handleSave={() => handleSave(false, false)} />
|
||||
{session?.role === 'T01' || isSubmit ? <></> : <SubmitButton handleSubmit={handleSubmit} />}
|
||||
{session?.role === 'T01' || isSubmit ? null : <SubmitButton handleSubmit={handleSubmit} />}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@ -221,12 +231,11 @@ export default function ButtonForm(props: {
|
||||
)
|
||||
}
|
||||
|
||||
// 목록 버튼
|
||||
function ListButton() {
|
||||
// Button Components
|
||||
const ListButton = () => {
|
||||
const router = useRouter()
|
||||
return (
|
||||
<div className="btn-bx">
|
||||
{/* 목록 */}
|
||||
<button className="btn-frame n-blue icon" onClick={() => router.push('/survey-sale')}>
|
||||
リスト<i className="btn-arr"></i>
|
||||
</button>
|
||||
@ -234,12 +243,10 @@ function ListButton() {
|
||||
)
|
||||
}
|
||||
|
||||
function EditButton(props: { setMode: (mode: Mode) => void; id: string; mode: Mode }) {
|
||||
const { setMode, id, mode } = props
|
||||
const EditButton = ({ setMode, id }: { setMode: (mode: Mode) => void; id: string }) => {
|
||||
const router = useRouter()
|
||||
return (
|
||||
<div className="btn-bx">
|
||||
{/* 수정 */}
|
||||
<button
|
||||
className="btn-frame n-blue icon"
|
||||
onClick={() => {
|
||||
@ -253,59 +260,34 @@ function EditButton(props: { setMode: (mode: Mode) => void; id: string; mode: Mo
|
||||
)
|
||||
}
|
||||
|
||||
function SubmitButton(props: { handleSubmit: () => void }) {
|
||||
const { handleSubmit } = props
|
||||
return (
|
||||
<>
|
||||
const SubmitButton = ({ handleSubmit }: { handleSubmit: () => void }) => (
|
||||
<div className="btn-bx">
|
||||
{/* 제출 */}
|
||||
<button className="btn-frame red icon" onClick={handleSubmit}>
|
||||
提出<i className="btn-arr"></i>
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function DeleteButton(props: { handleDelete: () => void }) {
|
||||
const { handleDelete } = props
|
||||
return (
|
||||
const DeleteButton = ({ handleDelete }: { handleDelete: () => void }) => (
|
||||
<div className="btn-bx">
|
||||
{/* 삭제 */}
|
||||
<button className="btn-frame n-blue icon" onClick={handleDelete}>
|
||||
削除<i className="btn-arr"></i>
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function SaveButton(props: { handleSave: (isTemporary: boolean) => void }) {
|
||||
const { handleSave } = props
|
||||
return (
|
||||
const SaveButton = ({ handleSave }: { handleSave: () => void }) => (
|
||||
<div className="btn-bx">
|
||||
{/* 저장 */}
|
||||
<button className="btn-frame n-blue icon" onClick={() => handleSave(false)}>
|
||||
<button className="btn-frame n-blue icon" onClick={handleSave}>
|
||||
保存<i className="btn-arr"></i>
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function TempButton(props: { setMode: (mode: Mode) => void; handleSave: (isTemporary: boolean) => void }) {
|
||||
const { setMode, handleSave } = props
|
||||
const router = useRouter()
|
||||
|
||||
return (
|
||||
const TempButton = ({ handleSave }: { handleSave: () => void }) => (
|
||||
<div className="btn-bx">
|
||||
{/* 임시저장 */}
|
||||
<button
|
||||
className="btn-frame n-blue icon"
|
||||
onClick={() => {
|
||||
handleSave(true)
|
||||
}}
|
||||
>
|
||||
<button className="btn-frame n-blue icon" onClick={handleSave}>
|
||||
一時保存<i className="btn-arr"></i>
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -70,7 +70,6 @@ const basicInfoForm: SurveyBasicRequest = {
|
||||
export default function DetailForm() {
|
||||
const idParam = useSearchParams().get('id')
|
||||
const routeId = useParams().id
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const modeset = Number(routeId) ? 'READ' : idParam ? 'EDIT' : 'CREATE'
|
||||
@ -80,26 +79,57 @@ export default function DetailForm() {
|
||||
const { session } = useSessionStore()
|
||||
|
||||
const [mode, setMode] = useState<Mode>(modeset)
|
||||
const [basicInfoData, setBasicInfoData] = useState<SurveyBasicRequest>(basicInfoForm)
|
||||
const [basicInfoData, setBasicInfoData] = useState<SurveyBasicRequest>(() => ({
|
||||
...basicInfoForm,
|
||||
representative: session?.userNm ?? '',
|
||||
representativeId: session?.userId ?? null,
|
||||
store: session?.storeNm ?? null,
|
||||
storeId: session?.storeId ?? null,
|
||||
constructionPoint: session?.builderNm ?? null,
|
||||
constructionPointId: session?.builderNo ?? null,
|
||||
}))
|
||||
const [roofInfoData, setRoofInfoData] = useState<SurveyDetailRequest>(roofInfoForm)
|
||||
|
||||
// 세션 데이터가 변경될 때 기본 정보 업데이트
|
||||
useEffect(() => {
|
||||
if (isLoadingSurveyDetail) return
|
||||
if (surveyDetail === null) {
|
||||
if (!session?.isLoggedIn) return
|
||||
setBasicInfoData((prev) => ({
|
||||
...prev,
|
||||
representative: session.userNm ?? '',
|
||||
representativeId: session.userId ?? null,
|
||||
store: session.storeNm ?? null,
|
||||
storeId: session.storeId ?? null,
|
||||
constructionPoint: session.builderNm ?? null,
|
||||
constructionPointId: session.builderNo ?? null,
|
||||
}))
|
||||
}, [session])
|
||||
|
||||
// 설문 데이터 로딩 및 업데이트
|
||||
useEffect(() => {
|
||||
if (isLoadingSurveyDetail || !session?.isLoggedIn) return
|
||||
|
||||
if (surveyDetail === null && mode !== 'CREATE') {
|
||||
alert('権限がありません。')
|
||||
router.replace('/survey-sale')
|
||||
return
|
||||
}
|
||||
|
||||
if (surveyDetail && (mode === 'EDIT' || mode === 'READ')) {
|
||||
const { id, uptDt, regDt, detailInfo, ...rest } = surveyDetail
|
||||
setBasicInfoData(rest)
|
||||
setBasicInfoData((prev) => ({
|
||||
...prev,
|
||||
...rest,
|
||||
}))
|
||||
|
||||
if (detailInfo) {
|
||||
const { id, uptDt, regDt, basicInfoId, ...rest } = detailInfo
|
||||
setRoofInfoData(rest)
|
||||
if (validateSurveyDetail(rest).trim() !== '') {
|
||||
// validation logic here if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [surveyDetail, id, mode, session])
|
||||
}, [surveyDetail, mode, session?.isLoggedIn, isLoadingSurveyDetail])
|
||||
|
||||
const data = {
|
||||
basic: basicInfoData,
|
||||
@ -111,9 +141,7 @@ export default function DetailForm() {
|
||||
return (
|
||||
<>
|
||||
<div className="sale-detail-toggle-wrap">
|
||||
{/* 기본정보 */}
|
||||
<BasicForm basicInfo={basicInfoData} setBasicInfo={setBasicInfoData} mode={mode} session={session} />
|
||||
{/* 전기/지붕정보 */}
|
||||
<RoofForm roofInfo={roofInfoData} setRoofInfo={setRoofInfoData} mode={mode} />
|
||||
<ButtonForm {...buttonFormProps} />
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user