'use client' import { useContext, useEffect, useState } from 'react' import { usePathname, useRouter } from 'next/navigation' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { v4 as uuidv4 } from 'uuid' import MenuDepth01 from './MenuDepth01' import QSelectBox from '@/components/common/select/QSelectBox' import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01' import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting' import EstimateCopyPop from '../estimate/popup/EstimateCopyPop' import DocDownOptionPop from '../estimate/popup/DocDownOptionPop' import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider' import { useMessage } from '@/hooks/useMessage' import { usePlan } from '@/hooks/usePlan' import { useSwal } from '@/hooks/useSwal' import { useEvent } from '@/hooks/useEvent' import { usePopup } from '@/hooks/usePopup' import { useCanvasEvent } from '@/hooks/useCanvasEvent' import { useCommonUtils } from '@/hooks/common/useCommonUtils' import useMenu from '@/hooks/common/useMenu' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' import { useAxios } from '@/hooks/useAxios' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom' import { sessionStore } from '@/store/commonAtom' import { outerLinePointsState } from '@/store/outerLineAtom' import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' import { commonUtilsState } from '@/store/commonUtilsAtom' import { menusState, menuTypeState } from '@/store/menuAtom' import { estimateState } from '@/store/floorPlanObjectAtom' import { pwrGnrSimTypeState } from '@/store/simulatorAtom' import { isObjectNotEmpty } from '@/util/common-utils' import { useSearchParams } from 'next/navigation' import KO from '@/locales/ko.json' import JA from '@/locales/ja.json' import { MENU } from '@/common/common' export default function CanvasMenu(props) { const { menuNumber, setMenuNumber } = props const pathname = usePathname() const router = useRouter() const { addPopup } = usePopup() const canvasMenus = useRecoilValue(menusState) const [type, setType] = useRecoilState(menuTypeState) const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState) const setAppMessageState = useSetRecoilState(appMessageStore) const setCurrentMenu = useSetRecoilState(currentMenuState) const setOuterLinePoints = useSetRecoilState(outerLinePointsState) const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState) const canvasSetting = useRecoilValue(canvasSettingState) const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const sessionState = useRecoilValue(sessionStore) const globalLocale = useRecoilValue(globalLocaleStore) const canvas = useRecoilValue(canvasState) const { handleZoomClear, handleZoom } = useCanvasEvent() const { handleMenu } = useMenu() const { handleEstimateSubmit } = useEstimateController() const estimateRecoilState = useRecoilValue(estimateState) const [estimatePopupOpen, setEstimatePopupOpen] = useState(false) const [estimateCopyPopupOpen, setEstimateCopyPopupOpen] = useState(false) const { getMessage } = useMessage() const { saveCanvas } = usePlan() const { swalFire } = useSwal() const { initEvent, addCanvasMouseEventListener, addDocumentEventListener } = useEvent() // const { initEvent, addCanvasMouseEventListener, addDocumentEventListener } = useContext(EventContext) const commonUtils = useRecoilValue(commonUtilsState) const { commonFunctions } = useCommonUtils() const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext) const { restoreModuleInstArea } = useModuleBasicSetting() const [addedRoofs, setAddedRoofsState] = useRecoilState(addedRoofsState) const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState) const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) //견적서버튼 노출용 const [buttonStyle, setButtonStyle] = useState('') // 발전시뮬레이션 메뉴 이동 const searchParams = useSearchParams() const objectNo = searchParams.get('objectNo') const pid = searchParams.get('pid') // 발전시물레이션 Excel/PDF 다운 const { promiseGet, promisePost } = useAxios(globalLocale) const pwrGnrSimTypeRecoil = useRecoilValue(pwrGnrSimTypeState) const handleExcelPdfFileDown = async (donwloadType, drawingFlg) => { const url = '/api/estimate/excel-download' const params = { objectNo: objectNo, planNo: pid, schDownload: donwloadType, schDrawingFlg: drawingFlg, pwrGnrSimType: pwrGnrSimTypeRecoil.type, } const options = { responseType: 'blob' } await promisePost({ url: url, data: params, option: options }) .then((resultData) => { if (resultData) { let fileName = 'unknow' const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' }) const fileUrl = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = fileUrl //서버에서 내려오는 파일명 const contentDisposition = resultData.headers['content-disposition'] if (contentDisposition) { fileName = contentDisposition.split('filename=')[1].replace(/['"]/g, '') } link.download = fileName document.body.appendChild(link) link.click() link.remove() window.URL.revokeObjectURL(fileUrl) } }) .catch((error) => { alert('File does not exist.') }) } const onClickNav = (menu) => { switch (menu.index) { case 1: setType('placementShape') onClickPlacementInitialMenu() break case 2: setType('outline') break case 3: if (type === 'module') { restoreModuleInstArea() } setType('surface') break case 4: setType('module') break case 6: promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => { if (res.status === 200) { const planList = res.data.planList const objectPlanDetail = planList.filter((row) => row.objectNo === objectNo && row.planNo === pid) if (objectPlanDetail) { if (objectPlanDetail[0].estimateDate) { router.push(`/floor-plan/simulator/${menu.index}?pid=${pid}&objectNo=${objectNo}`) setMenuNumber(menu.index) setCurrentMenu(menu.title) } else { alert(getMessage('simulator.menu.move.valid1')) } } } }) break } if (menu.index !== 6) { setMenuNumber(menu.index) setCurrentMenu(menu.title) } if (pathname !== '/floor-plan') router.push(`/floor-plan?pid=${pid}&objectNo=${objectNo}`) } const changeSelectedRoofMaterial = (e) => { setBasicSetting({ ...basicSetting, selectedRoofMaterial: e }) const newAddedRoofs = addedRoofs.map((roof) => { if (roof.index === e.index) { return { ...roof, selected: true } } else { return { ...roof, selected: false } } }) setAddedRoofsState(newAddedRoofs) } const settingsModalOptions = useRecoilState(settingModalFirstOptionsState) useEffect(() => { if (menuNumber === 1) { onClickPlacementInitialMenu() } }, [menuNumber, type]) // 저장버튼(btn08) 클릭 시 호출되는 함수 const handleSaveCanvas = async () => { await saveCanvas() } const [placementInitialId, setPlacementInitialId] = useState(uuidv4()) const placementInitialProps = { id: placementInitialId, pos: { x: 50, y: 180, }, } const onClickPlacementInitialMenu = () => { addPopup(placementInitialId, 1, ) } const handleClear = () => { setOuterLinePoints([]) setPlacementPoints([]) canvas?.clear() } // // const handleZoomClear = () => { // setCanvasZoom(100) // canvas.set({ zoom: 1 }) // canvas.viewportTransform = [1, 0, 0, 1, 0, 0] // canvas.renderAll() // } const handlePopup = () => { const id = uuidv4() addPopup(id, 1, , true) } // 견적서 초기화 버튼 const handleEstimateReset = () => { // console.log('estimateRecoilState::', estimateRecoilState) //objectNo, planNo swalFire({ //저장된 견적서 정보가 초기화되고, 도면정보가 반영됩니다. 정말로 초기화 하시겠습니까? //물건정보 text: getMessage('estimate.detail.reset.confirmMsg'), type: 'confirm', confirmFn: () => { console.log('내용초기화 및 변경일시 갱신') }, denyFn: () => { console.log('초기화하지 않음. 변경일시 갱신안함') }, }) } useEffect(() => { if (globalLocale === 'ko') { setAppMessageState(KO) } else { setAppMessageState(JA) } }, [type, globalLocale]) useEffect(() => { if ([2, 3].some((num) => num === canvasSetting?.roofSizeSet)) { setMenuNumber(3) setType('surface') setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) } else { setMenuNumber(2) setType('outline') setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) } }, [canvasSetting]) const checkMenuState = (menu) => { return (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.index === 2) || (menuNumber === 4 && menu.index === 2) } useEffect(() => { if (isObjectNotEmpty(estimateRecoilState)) { if (estimateRecoilState?.createUser === 'T01') { if (sessionState.userId !== 'T01') { setButtonStyle('none') } } } }, [estimateRecoilState]) return (
num === menuNumber) ? 'active' : ''}`}>
    {canvasMenus.map((menu) => { return (
  • { if (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.index === 2) return if (menuNumber === 4 && menu.index === 2) return onClickNav(menu) }} >
  • ) })}
{![5, 6].some((num) => num === menuNumber) && ( <> {
{getMessage('plan.mode.vertical.horizontal')}
}
{isObjectNotEmpty(selectedRoofMaterial) && addedRoofs.length > 0 && (
{ }
)}
{/**/}
{canvasZoom}%
)} {menuNumber === 5 && ( <>
{estimateRecoilState?.docNo !== null && (sessionState.storeId === 'T01' || sessionState.storeLvl === '1') && ( )}
)} {menuNumber === 6 && ( <>
)}
num === menuNumber) ? 'active' : ''}`}> {[2, 3, 4].some((num) => num === menuNumber) && }
{/* 견적서(menuNumber=== 5) 상세화면인경우 문서다운로드 팝업 */} {estimatePopupOpen && } {/* 견적서(menuNumber ===5)복사 팝업 */} {estimateCopyPopupOpen && }
) }