From 6ecdc1bf971f23d6116b4f0189421b0ca4bf5af1 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Mon, 24 Feb 2025 17:32:03 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EC=B4=88=EA=B8=B0=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placementShape/PlacementShapeSetting.jsx | 35 ++- src/hooks/option/useCanvasSetting.js | 270 +++++++----------- 2 files changed, 116 insertions(+), 189 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index ed400f95..2fed8591 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -63,20 +63,21 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla /** * 지붕재 초기값 */ - const defaultRoofSettings = { - roofSizeSet: '1', // 기본 치수 입력 방법 - roofAngleSet: 'slope', // 기본 지붕 각도 설정 + const DEFAULT_ROOF_SETTINGS = { + roofSizeSet: '1', + roofAngleSet: 'slope', angle: 21.8, - hajebichi: '', + hajebichi: null, id: 'ROOF_ID_WA_53A', index: 0, layout: ROOF_MATERIAL_LAYOUT.PARALLEL, lenAuth: 'R', lenBase: '235.000', - length: '235', + length: 235, name: '일본기와 A', nameJp: '和瓦A', pitch: 4, + planNo: planNo, raft: '', raftAuth: 'C', raftBaseCd: 'HEI_455', @@ -89,12 +90,12 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla selected: true, widAuth: 'R', widBase: '265.000', - width: '265', + width: 265, } useEffect(() => { /** - * 메뉴에서 배치면초기설정 선택 시 조회 + * 메뉴에서 배치면초기설정 선택 시 조회 후 화면 오픈 */ if (openPoint && openPoint === 'canvasMenus') fetchBasicSettings(planNo, openPoint) }, []) @@ -103,18 +104,16 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla if (addedRoofs.length > 0) { const raftCodeList = findCommonCode('203800') setRaftCodes(raftCodeList) - - /** - * 데이터 설정 확인 후 데이터가 없으면 기본 데이터 설정 - */ - if (addedRoofs.length > 0) { - setCurrentRoof({ ...addedRoofs[0], planNo: basicSetting.planNo }) - } else { - setCurrentRoof(defaultRoofSettings) - } + setCurrentRoof({ ...addedRoofs[0], planNo: planNo, roofSizeSet: String(basicSetting.roofSizeSet), roofAngleSet: basicSetting.roofAngleSet }) + } else { + /** 데이터 설정 확인 후 데이터가 없으면 기본 데이터 설정 */ + setCurrentRoof({ ...DEFAULT_ROOF_SETTINGS }) } }, [addedRoofs]) + /** + * 배치면초기설정 정보 변경 시 basicSettings 설정 + */ useEffect(() => { if (!currentRoof) return setBasicSettings({ @@ -256,7 +255,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla id={item.id} name={item.name} value={item.value} - checked={currentRoof?.roofSizeSet === item.value} + checked={String(currentRoof?.roofSizeSet) === item.value} onChange={(e) => setCurrentRoof({ ...currentRoof, roofSizeSet: e.target.value })} /> @@ -279,7 +278,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla id={item.id} name={item.name} value={item.value} - checked={currentRoof?.roofAngleSet === item.value} + checked={String(currentRoof?.roofAngleSet) === item.value} onChange={(e) => setCurrentRoof({ ...currentRoof, roofAngleSet: e.target.value })} /> diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 8cdecf1c..37f53f5e 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -43,21 +43,19 @@ import { v4 as uuidv4 } from 'uuid' const defaultDotLineGridSetting = { INTERVAL: { - type: 2, // 1: 가로,세로 간격 수동, 2: 비율 간격 + type: 2 /* 1: 가로,세로 간격 수동, 2: 비율 간격 */, ratioInterval: 910, verticalInterval: 910, horizontalInterval: 910, - dimension: 1, // 치수 + dimension: 1 /* 치수 */, }, DOT: false, LINE: false, } -// let previousRoofMaterialsYn = 'N' // 지붕재 select 정보 비교 후 변경된 것이 없으면 1회만 실행 - export function useCanvasSetting() { const canvas = useRecoilValue(canvasState) - /* canvas가 null이 아닐 때에만 getObjects 호출 */ + /** canvas가 null이 아닐 때에만 getObjects 호출 */ const canvasObjects = canvas ? canvas.getObjects() : [] const [correntObjectNo, setCorrentObjectNo] = useRecoilState(correntObjectNoState) @@ -119,14 +117,14 @@ export function useCanvasSetting() { const [type, setType] = useRecoilState(menuTypeState) const setCurrentMenu = useSetRecoilState(currentMenuState) - const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 - const resetSelectedModules = useResetRecoilState(selectedModuleState) //선택된 모듈 + const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */ + const resetSelectedModules = useResetRecoilState(selectedModuleState) /* 선택된 모듈 */ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) - const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보 + const [raftCodes, setRaftCodes] = useState([]) /* 서까래 정보 */ const { findCommonCode } = useCommonCode() - const [currentRoof, setCurrentRoof] = useState(null) // 현재 선택된 지붕재 정보 + const [currentRoof, setCurrentRoof] = useState(null) /* 현재 선택된 지붕재 정보 */ const { addPopup } = usePopup() const [popupId, setPopupId] = useState(uuidv4()) @@ -144,7 +142,7 @@ export function useCanvasSetting() { useEffect(() => { const tempFetchRoofMaterials = !fetchRoofMaterials - /* 초 1회만 실행하도록 처리 */ + /** 초 1회만 실행하도록 처리 */ setFetchRoofMaterials(tempFetchRoofMaterials) if (tempFetchRoofMaterials) { addRoofMaterials() @@ -176,7 +174,23 @@ export function useCanvasSetting() { angle: item.angle ? parseInt(item.angle) : 21.8, })) setRoofMaterials(roofLists) - const selectedRoofMaterial = roofLists[0] + } + + useEffect(() => { + if (addedRoofs.length > 0 && addedRoofs[0].planNo === basicSetting.planNo) { + const raftCodeList = findCommonCode('203800') + setRaftCodes(raftCodeList) + setCurrentRoof({ + ...addedRoofs[0], + planNo: addedRoofs[0].planNo, + roofSizeSet: String(basicSetting.roofSizeSet), + roofAngleSet: basicSetting.roofAngleSet, + }) + } + }, [addedRoofs]) + + useEffect(() => { + const selectedRoofMaterial = roofMaterials[0] if (addedRoofs.length === 0) { const newAddedRoofs = [] @@ -184,19 +198,7 @@ export function useCanvasSetting() { setAddedRoofs(newAddedRoofs) } setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial }) - } - - /** - * 배치면 초기설정 화면이 열리지 않아도 데이터 set 하기 위해서 추가 - */ - useEffect(() => { - if (addedRoofs.length > 0) { - const raftCodeList = findCommonCode('203800') - setRaftCodes(raftCodeList) - - setCurrentRoof({ ...addedRoofs[0] }) - } - }, [addedRoofs]) + }, [roofMaterials]) useEffect(() => { if (!canvas) { @@ -339,7 +341,7 @@ export function useCanvasSetting() { } }) - /* 데이터 존재 시 화면 닫기(메뉴/저장 클릭 시 제외) */ + /** 데이터 존재 시 화면 닫기(메뉴/저장 클릭 시 제외) */ if (openPoint !== 'canvasMenus' && openPoint !== 'basicSettingSave') { //closePopup(popupId) closeAll() @@ -369,9 +371,9 @@ export function useCanvasSetting() { }, ] - /* 메뉴에서 배치면 초기설정 클릭 시 실행하지 않음 */ + /** 메뉴에서 배치면 초기설정 클릭 시 실행하지 않음 */ if (openPoint === null) { - /* 배치면 초기설정 미저장 상태이면 화면 열기 */ + /** 배치면 초기설정 미저장 상태이면 화면 열기 */ const placementInitialProps = { id: popupId, pos: { @@ -385,7 +387,7 @@ export function useCanvasSetting() { } } - /* 데이터 설정 */ + /** 데이터 설정 */ const addRoofs = [] for (let i = 0; i < roofsArray.length; i++) { roofMaterials?.map((material) => { @@ -440,6 +442,21 @@ export function useCanvasSetting() { // setCanvasSetting({ ...basicSetting }) } + /** + * 저장/복사저장 시 지붕 크기에 따른 메뉴 설정 + */ + const setMenuByRoofSize = (roofSizeSet) => { + if (['2', '3'].includes(String(roofSizeSet))) { + setMenuNumber(3) + setType('surface') + setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) + } else { + setMenuNumber(2) + setType('outline') + setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) + } + } + /** * 기본설정(PlacementShapeSetting) 저장 */ @@ -471,31 +488,23 @@ export function useCanvasSetting() { await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { swalFire({ text: getMessage(res.returnMessage) }) - /* BasicSettings Recoil 설정 */ + /** BasicSettings Recoil 설정 */ setBasicSettings({ ...params }) }) - /* CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ + /** CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ setCanvasSetting({ ...basicSetting, roofSizeSet: String(params.roofSizeSet), }) - /* 메뉴 설정 */ - if (['2', '3'].includes(params.roofSizeSet)) { - setMenuNumber(3) - setType('surface') - setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) - } else { - setMenuNumber(2) - setType('outline') - setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) - } + /** 메뉴 설정 */ + setMenuByRoofSize(params.roofSizeSet) - /* 배치면초기설정 조회 */ + /** 배치면초기설정 조회 */ fetchBasicSettings(params.planNo, 'basicSettingSave') - /* 모듈 선택 데이터 초기화 */ + /** 모듈 선택 데이터 초기화 */ resetModuleSelectionData() moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -536,27 +545,19 @@ export function useCanvasSetting() { swalFire({ text: getMessage(res.returnMessage) }) }) - /* CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ + /** CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ setCanvasSetting({ ...basicSetting, roofSizeSet: String(params.roofSizeSet), }) - /* 메뉴 설정 */ - if (['2', '3'].includes(params?.roofSizeSet)) { - setMenuNumber(3) - setType('surface') - setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) - } else { - setMenuNumber(2) - setType('outline') - setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) - } + /** 메뉴 설정 */ + setMenuByRoofSize(params.roofSizeSet) - /* 배치면초기설정 조회 */ + /** 배치면초기설정 조회 */ fetchBasicSettings(Number(params.planNo), 'basicSettingSave') - /* 모듈 선택 데이터 초기화 */ + /** 모듈 선택 데이터 초기화 */ resetModuleSelectionData() moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -582,24 +583,16 @@ export function useCanvasSetting() { const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] })) const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item })) - /** - * 흡착점 ON/OFF - */ + /** 흡착점 ON/OFF */ setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint }) - /** - * 치수선 설정 - */ + /** 치수선 설정 */ setDimensionLineSettings({ ...dimensionLineSettings, pixel: res.originPixel, color: res.originColor }) - /** - * 도면크기 설정 - */ + /** 도면크기 설정 */ setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: res.originHorizon, originVertical: res.originVertical }) - /** - * 데이터 설정 - */ + /** 데이터 설정 */ setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: optionData1, @@ -614,45 +607,35 @@ export function useCanvasSetting() { const fontPatternData = { commonText: { - /** - * 문자 글꼴 조회 데이터 - */ + /** 문자 글꼴 조회 데이터 */ fontFamily: getFonts(res.wordFont), fontWeight: getFontStyles(res.wordFontStyle), fontSize: getFontSizes(res.wordFontSize), fontColor: getFontColors(res.wordFontColor), }, flowText: { - /** - * 흐름방향 글꼴 조회 데이터 - */ + /** 흐름방향 글꼴 조회 데이터 */ fontFamily: getFonts(res.flowFont), fontWeight: getFontStyles(res.flowFontStyle), fontSize: getFontSizes(res.flowFontSize), fontColor: getFontColors(res.flowFontColor), }, dimensionLineText: { - /** - * 치수 글꼴 조회 데이터 - */ + /** 치수 글꼴 조회 데이터 */ fontFamily: getFonts(res.dimensioFont), fontWeight: getFontStyles(res.dimensioFontStyle), fontSize: getFontSizes(res.dimensioFontSize), fontColor: getFontColors(res.dimensioFontColor), }, circuitNumberText: { - /** - * 회로번호 글꼴 조회 데이터 - */ + /** 회로번호 글꼴 조회 데이터 */ fontFamily: getFonts(res.circuitNumFont), fontWeight: getFontStyles(res.circuitNumFontStyle), fontSize: getFontSizes(res.circuitNumFontSize), fontColor: getFontColors(res.circuitNumFontColor), }, lengthText: { - /** - * 치수선 글꼴 조회 데이터 - */ + /** 치수선 글꼴 조회 데이터 */ fontFamily: getFonts(res.lengthFont), fontWeight: getFontStyles(res.lengthFontStyle), fontSize: getFontSizes(res.lengthFontSize), @@ -660,14 +643,10 @@ export function useCanvasSetting() { }, } - /** - * 조회된 글꼴 데이터 set - */ + /** 조회된 글꼴 데이터 set */ setGlobalFont(fontPatternData) - /** - * 점/선 그리드 - */ + /** 점/선 그리드 */ const patternData = { INTERVAL: { type: res.gridType, @@ -682,47 +661,31 @@ export function useCanvasSetting() { setDotLineGridSettingState(patternData) - /** - * 그리드 색 설정 - */ + /** 그리드 색 설정 */ setGridColor(res.gridColor) } else { - //조회된 글꼴 데이터가 없는 경우 (데이터 초기화) + /** 조회된 글꼴 데이터가 없는 경우 (데이터 초기화) */ - /** - * 흡착점 ON/OFF - */ + /** 흡착점 ON/OFF */ setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false }) - /** - * 치수선 설정 - */ + /** 치수선 설정 */ resetDimensionLineSettings() - /** - * 도면크기 설정 - */ + /** 도면크기 설정 */ resetPlanSizeSettingMode() - /** - * 데이터 설정 - */ + /** 데이터 설정 */ resetSettingModalFirstOptions() resetSettingModalSecondOptions() - /** - * 데이터 초기화 - */ + /** 데이터 초기화 */ resetGlobalFont() - /** - * 점/선 그리드 - */ + /** 점/선 그리드 */ setDotLineGridSettingState({ ...defaultDotLineGridSetting }) - /** - * 그리드 색 설정 - */ + /** 그리드 색 설정 */ setGridColor('#FF0000') } @@ -736,9 +699,7 @@ export function useCanvasSetting() { * CanvasSetting 옵션 클릭 후 저장 */ const onClickOption2 = async () => { - /** - * 서버에 전송할 데이터 - */ + /** 서버에 전송할 데이터 */ const dataToSend = { firstOption1: option1.map((item) => ({ column: item.column, @@ -759,13 +720,9 @@ export function useCanvasSetting() { })), } const patternData = { - /** - * 견적서 번호 - */ + /** 견적서 번호 */ objectNo: correntObjectNo, - /** - * 디스플레이 설정(다중) - */ + /** 디스플레이 설정(다중) */ allocDisplay: dataToSend.firstOption1[0].selected, outlineDisplay: dataToSend.firstOption1[1].selected, gridDisplay: dataToSend.firstOption1[2].selected, @@ -776,85 +733,62 @@ export function useCanvasSetting() { trestleDisplay: dataToSend.firstOption1[7].selected, imageDisplay: dataToSend.firstOption1[8].selected, totalDisplay: dataToSend.firstOption1[9].selected, - /** - * 차수 표시(단 건) - */ + /** 차수 표시(단 건) */ corridorDimension: dataToSend.firstOption3[0].selected, realDimension: dataToSend.firstOption3[1].selected, noneDimension: dataToSend.firstOption3[2].selected, - /** - * 화면 표시(단 건) - */ + /** 화면 표시(단 건) */ onlyBorder: dataToSend.firstOption2[0].selected, lineHatch: dataToSend.firstOption2[1].selected, allPainted: dataToSend.firstOption2[2].selected, - /** - * 흡착범위 설정(단 건) - */ + /** 흡착범위 설정(단 건) */ adsorpRangeSmall: dataToSend.secondOption2[0].selected, adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected, adsorpRangeMedium: dataToSend.secondOption2[2].selected, adsorpRangeLarge: dataToSend.secondOption2[3].selected, - - /** - * 흡착점 ON/OFF - */ + /** 흡착점 ON/OFF */ adsorpPoint: adsorptionPointMode.adsorptionPoint, //??: adsorptionRange, 사용여부 확인 필요 - /** - * 글꼴 설정 - */ - //문자 글꼴 + /** 문자 글꼴 설정 */ wordFont: globalFont.commonText.fontFamily?.value ?? 'MS PGothic', wordFontStyle: globalFont.commonText.fontWeight?.value ?? 'normal', wordFontSize: globalFont.commonText.fontSize?.value ?? 16, wordFontColor: globalFont.commonText.fontColor?.value ?? 'black', - /** - * 흐름방향 글꼴 - */ + /** 흐름방향 글꼴 설정 */ flowFont: globalFont.flowText.fontFamily?.value ?? 'MS PGothic', flowFontStyle: globalFont.flowText.fontWeight?.value ?? 'normal', flowFontSize: globalFont.flowText.fontSize?.value ?? 16, flowFontColor: globalFont.flowText.fontColor?.value ?? 'black', - /** - * 치수 글꼴 - */ + /** 치수 글꼴 설정 */ dimensioFont: globalFont.dimensionLineText.fontFamily?.value ?? 'MS PGothic', dimensioFontStyle: globalFont.dimensionLineText.fontWeight?.value ?? 'normal', dimensioFontSize: globalFont.dimensionLineText.fontSize?.value ?? 16, dimensioFontColor: globalFont.dimensionLineText.fontColor?.value ?? 'black', - /** - * 회로번호 글꼴 - */ + /** 회로번호 글꼴 설정 */ circuitNumFont: globalFont.circuitNumberText.fontFamily?.value ?? 'MS PGothic', circuitNumFontStyle: globalFont.circuitNumberText.fontWeight?.value ?? 'normal', circuitNumFontSize: globalFont.circuitNumberText.fontSize?.value ?? 16, circuitNumFontColor: globalFont.circuitNumberText.fontColor?.value ?? 'black', - /** - * 치수선 글꼴 - */ + /** 치수선 글꼴 설정 */ lengthFont: globalFont.lengthText.fontFamily?.value ?? 'MS PGothic', lengthFontStyle: globalFont.lengthText.fontWeight?.value ?? 'normal', lengthFontSize: globalFont.lengthText.fontSize?.value ?? 16, lengthFontColor: globalFont.lengthText.fontColor?.value ?? 'black', - /** - * 치수선 설정 - */ + /** 치수선 설정 */ originPixel: dimensionLineSettings.pixel, originColor: dimensionLineSettings.color, - /** - * 도면크기 설정 - */ + /** 도면크기 설정 */ originHorizon: planSizeSettingMode.originHorizon, originVertical: planSizeSettingMode.originVertical, + /** 점/선 그리드 */ dotGridDisplay: dotLineGridSetting.DOT, lineGridDisplay: dotLineGridSetting.LINE, gridType: dotLineGridSetting.INTERVAL.type, @@ -863,6 +797,7 @@ export function useCanvasSetting() { gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10, gridDimen: dotLineGridSetting.INTERVAL.dimension, + /** 그리드 색 설정 */ gridColor: gridColor, } @@ -875,13 +810,10 @@ export function useCanvasSetting() { .then((res) => { //swalFire({ text: getMessage(res.returnMessage) }) - /** - * Canvas 디스플레이 설정 시 해당 옵션 적용 - */ + /** Canvas 디스플레이 설정 시 해당 옵션 적용 */ frontSettings() - /** - * 저장 후 재조회 - */ + + /** 저장 후 재조회 */ fetchSettings() }) .catch((error) => { @@ -912,8 +844,8 @@ export function useCanvasSetting() { */ /** - * 옵션명 - * 옵션상태 + * 옵션명 optionName + * 옵션상태 optionSelected */ let optionName let optionSelected @@ -948,15 +880,11 @@ export function useCanvasSetting() { optionName = ['backGroundImage'] break case 'totalDisplay': - /** - * 작업할 필요 없음 - */ + /** 작업할 필요 없음 */ optionName = [] break } - /** - * 표시 선택 상태(true/false) - */ + /** 표시 선택 상태(true/false)*/ optionSelected = option1[i].selected canvasObjects From 2769ac23583377ba5fd66e405556b4aa9b412030 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Mon, 24 Feb 2025 18:08:24 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=9A=A6fix:=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/html2canvas/route.js | 22 - src/app/api/image-upload/route.js | 15 - src/app/api/swr-tutorial/route.js | 25 - src/app/playground/page.jsx | 9 - src/app/roof/page.jsx | 13 - src/app/roof2/page.jsx | 11 - src/app/settings/page.jsx | 13 - src/components/GridSettingsModal.jsx | 273 ------ src/components/Headers.jsx | 21 - src/components/Hero.jsx | 7 - src/components/InitSettingsModal.jsx | 253 ------ src/components/Playground.jsx | 919 ------------------- src/components/Roof.jsx | 351 -------- src/components/Roof2.jsx | 1099 ----------------------- src/components/Settings.jsx | 324 ------- src/components/playground.module.css | 4 - src/hooks/common/useMasterController.js | 4 - 17 files changed, 3363 deletions(-) delete mode 100644 src/app/api/html2canvas/route.js delete mode 100644 src/app/api/image-upload/route.js delete mode 100644 src/app/api/swr-tutorial/route.js delete mode 100644 src/app/playground/page.jsx delete mode 100644 src/app/roof/page.jsx delete mode 100644 src/app/roof2/page.jsx delete mode 100644 src/app/settings/page.jsx delete mode 100644 src/components/GridSettingsModal.jsx delete mode 100644 src/components/Headers.jsx delete mode 100644 src/components/Hero.jsx delete mode 100644 src/components/InitSettingsModal.jsx delete mode 100644 src/components/Playground.jsx delete mode 100644 src/components/Roof.jsx delete mode 100644 src/components/Roof2.jsx delete mode 100644 src/components/Settings.jsx delete mode 100644 src/components/playground.module.css diff --git a/src/app/api/html2canvas/route.js b/src/app/api/html2canvas/route.js deleted file mode 100644 index 21f93c82..00000000 --- a/src/app/api/html2canvas/route.js +++ /dev/null @@ -1,22 +0,0 @@ -'use server' - -import fs from 'fs/promises' - -import { NextResponse } from 'next/server' -import { writeImage, writeImageBuffer } from '@/lib/fileAction' - -export async function GET(req) { - const path = 'public/plan-map-images' - const q = req.nextUrl.searchParams.get('q') - const fileNm = req.nextUrl.searchParams.get('fileNm') - const zoom = req.nextUrl.searchParams.get('zoom') - const targetUrl = `https://maps.googleapis.com/maps/api/staticmap?center=${q}&zoom=${zoom}&maptype=satellite&size=640x640&scale=1&key=AIzaSyDO7nVR1N_D2tKy60hgGFavpLaXkHpiHpc` - const decodeUrl = decodeURIComponent(targetUrl) - - const response = await fetch(decodeUrl) - const data = await response.arrayBuffer() - const buffer = Buffer.from(data) - await writeImage(fileNm, buffer) - - return NextResponse.json({ fileNm: `${fileNm}.png` }) -} diff --git a/src/app/api/image-upload/route.js b/src/app/api/image-upload/route.js deleted file mode 100644 index 219544fe..00000000 --- a/src/app/api/image-upload/route.js +++ /dev/null @@ -1,15 +0,0 @@ -'use server' - -import { NextResponse } from 'next/server' -import { writeImage } from '@/lib/fileAction' - -export async function POST(req) { - const formData = await req.formData() - const file = formData.get('file') - const fileName = formData.get('fileName') - const arrayBuffer = await file.arrayBuffer() - const buffer = Buffer.from(arrayBuffer) - await writeImage(fileName, buffer) - - return NextResponse.json({ fileNm: `${fileName}.png` }) -} diff --git a/src/app/api/swr-tutorial/route.js b/src/app/api/swr-tutorial/route.js deleted file mode 100644 index 99ebaf15..00000000 --- a/src/app/api/swr-tutorial/route.js +++ /dev/null @@ -1,25 +0,0 @@ -import { NextResponse } from 'next/server' - -const defaultData = [ - { - id: 1, - name: 'John Doe', - email: 'john.doe@example.com', - }, - { - id: 2, - name: 'Jane Lee', - email: 'jane.lee@example.com', - }, -] - -export async function GET(req, res) { - return NextResponse.json(defaultData) -} - -export const POST = async (req, res) => { - const { id, name, email } = await req.json() - const newData = { id, name, email } - console.log('🚀 ~ POST ~ newData:', newData) - return NextResponse.json([...defaultData, newData]) -} diff --git a/src/app/playground/page.jsx b/src/app/playground/page.jsx deleted file mode 100644 index 3a3ad1d1..00000000 --- a/src/app/playground/page.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import Playground from '@/components/Playground' - -export default async function PlaygroundPage() { - return ( - <> - - - ) -} diff --git a/src/app/roof/page.jsx b/src/app/roof/page.jsx deleted file mode 100644 index 960ffa89..00000000 --- a/src/app/roof/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import Roof from '@/components/Roof' - -export default async function RoofPage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/app/roof2/page.jsx b/src/app/roof2/page.jsx deleted file mode 100644 index 94e86fbe..00000000 --- a/src/app/roof2/page.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import Roof2 from '@/components/Roof2' - -export default async function Roof2Page() { - return ( - <> -
- -
- - ) -} diff --git a/src/app/settings/page.jsx b/src/app/settings/page.jsx deleted file mode 100644 index ab714682..00000000 --- a/src/app/settings/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import Settings from '@/components/Settings' - -export default async function SettingsPage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/components/GridSettingsModal.jsx b/src/components/GridSettingsModal.jsx deleted file mode 100644 index 92b2e618..00000000 --- a/src/components/GridSettingsModal.jsx +++ /dev/null @@ -1,273 +0,0 @@ -import { useEffect, useRef, useState } from 'react' -import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input } from '@nextui-org/react' -import { useRecoilState, useRecoilValue } from 'recoil' -import { modalContent, modalState } from '@/store/modalAtom' -import { guideLineState, horiGuideLinesState, vertGuideLinesState } from '@/store/canvasAtom' -import { fabric } from 'fabric' -import { ColorPicker, useColor } from 'react-color-palette' -import 'react-color-palette/css' -import { gridColorState } from '@/store/gridAtom' - -export default function GridSettingsModal(props) { - const { canvasProps } = props - const [isCustomGridSetting, setIsCustomGridSetting] = useState(true) - const [gridCheckedValue, setGridCheckValue] = useState([]) - const [ratioValue, setRatioValue] = useState('1') - const moduleLength = useRef(null) //모듈 mm 길이 입력 - const customModuleHoriLength = useRef(null) - const customModuleVertLength = useRef(null) - - const [open, setOpen] = useRecoilState(modalState) - const [guideLine, setGuideLine] = useRecoilState(guideLineState) - const [horiGuideLines, setHoriGuideLines] = useRecoilState(horiGuideLinesState) - const [vertGuideLines, setVertGuideLines] = useRecoilState(vertGuideLinesState) - - const gridSettingArray = [] - - const gridColor = useRecoilValue(gridColorState) - const [colorPickerShow, setColorPickerShow] = useState(false) - - const boxStyle = { - width: '50px', - height: '30px', - border: '1px solid black', - backgroundColor: guideColor.hex, - } - useEffect(() => { - moduleLength.current.value = 90 - customModuleHoriLength.current.value = 90 - customModuleVertLength.current.value = 90 - }, []) - - useEffect(() => { - setIsCustomGridSetting(ratioValue !== 'custom') - }, [ratioValue]) - - const drawGridSettings = () => { - //기존에 선택된 데이터가 있으면 그 데이터를 포함한다 - if (!(Object.keys(guideLine).length === 0 && guideLine.constructor === Object)) { - gridSettingArray.push(...guideLine) - } - - let moduleHoriLength = moduleLength.current.value //가로 간격 - let moduleVertLength = moduleLength.current.value //새로 간격 - - if (ratioValue === 'custom') { - moduleHoriLength = customModuleHoriLength.current.value - moduleVertLength = customModuleVertLength.current.value - } else { - moduleHoriLength = moduleHoriLength / ratioValue - moduleVertLength = moduleVertLength / ratioValue - } - - if (gridCheckedValue.includes('line')) { - const horizontalLineArray = [] - const verticalLineArray = [] - - for (let i = 0; i < canvasProps.height / moduleVertLength + 1; i++) { - const horizontalLine = new fabric.Line( - [0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2], - { - stroke: gridColor, - strokeWidth: 1, - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: 'guideLine', - strokeDashArray: [5, 2], - opacity: 0.3, - direction: 'horizontal', - }, - ) - canvasProps.add(horizontalLine) - horizontalLineArray.push(horizontalLine) - } - - for (let i = 0; i < canvasProps.width / moduleHoriLength + 1; i++) { - const verticalLine = new fabric.Line( - [i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height], - { - stroke: gridColor, - strokeWidth: 1, - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: 'guideLine', - strokeDashArray: [5, 2], - opacity: 0.3, - direction: 'vertical', - }, - ) - canvasProps.add(verticalLine) - verticalLineArray.push(verticalLine) - } - canvasProps.renderAll() - - const snapDistance = 10 - - const recoilObj = { - guideMode: 'guideLine', - horizontalLineArray, - verticalLineArray, - moduleVertLength: moduleVertLength, - moduleHoriLength: moduleHoriLength, - } - gridSettingArray.push(recoilObj) - const newHoriGuideLines = [...horiGuideLines] - horizontalLineArray.forEach((line) => { - newHoriGuideLines.push(line) - }) - const newVertGuideLines = [...vertGuideLines] - verticalLineArray.forEach((line) => { - newVertGuideLines.push(line) - }) - setHoriGuideLines(newHoriGuideLines) - setVertGuideLines(newVertGuideLines) - } - - if (gridCheckedValue.includes('dot')) { - const circle = new fabric.Circle({ - radius: 2, - fill: 'white', - stroke: guideColor.hex, - strokeWidth: 0.7, - originX: 'center', - originY: 'center', - selectable: false, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - }) - - const patternSourceCanvas = new fabric.StaticCanvas(null, { - width: moduleHoriLength, - height: moduleVertLength, - }) - - patternSourceCanvas.add(circle) - - circle.set({ - left: patternSourceCanvas.width / 2, - top: patternSourceCanvas.height / 2, - }) - - patternSourceCanvas.renderAll() - - const pattern = new fabric.Pattern({ - source: patternSourceCanvas.getElement(), - repeat: 'repeat', - }) - - const backgroundPolygon = new fabric.Polygon( - [ - { x: 0, y: 0 }, - { x: canvasProps.width, y: 0 }, - { x: canvasProps.width, y: canvasProps.height }, - { x: 0, y: canvasProps.height }, - ], - { - fill: pattern, - selectable: false, - name: 'guideDot', - }, - ) - - canvasProps.add(backgroundPolygon) - backgroundPolygon.sendToBack() - canvasProps.renderAll() - - const recoilObj = { - guideMode: 'guideDot', - moduleVertLength: moduleVertLength, - moduleHoriLength: moduleHoriLength, - } - - gridSettingArray.push(recoilObj) - } - canvasProps.renderAll() - setGuideLine(gridSettingArray) - } - - const removeGuideLines = () => { - if (!(Object.keys(guideLine).length === 0 && guideLine.constructor === Object)) { - const guideLines = canvasProps._objects.filter((obj) => obj.name === 'guideLine' || obj.name === 'guideDot') - guideLines?.forEach((item) => canvasProps.remove(item)) - canvasProps.renderAll() - setGuideLine([]) - setHoriGuideLines([]) - setVertGuideLines([]) - } else { - alert('그리드가 없습니다.') - return - } - } - - return ( - <> -
-
- -
-
- - mm -
-
- - 원치수 - 1/2 - 1/4 - 1/10 - 임의간격 - -
-
- 가이드컬러
setColorPickerShow(!colorPickerShow)}>
-
- {colorPickerShow && ( - - )} - -
- - 종횡연동 - -
-
-
- - mm -
-
- - mm -
- -
- - - - -
- - ) -} diff --git a/src/components/Headers.jsx b/src/components/Headers.jsx deleted file mode 100644 index 02859c96..00000000 --- a/src/components/Headers.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import Link from 'next/link' - -export default function Headers() { - return ( -
- -
- ) -} diff --git a/src/components/Hero.jsx b/src/components/Hero.jsx deleted file mode 100644 index a6e7761f..00000000 --- a/src/components/Hero.jsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Hero(props) { - return ( -
-

{props.title}

-
- ) -} diff --git a/src/components/InitSettingsModal.jsx b/src/components/InitSettingsModal.jsx deleted file mode 100644 index 4cfc483d..00000000 --- a/src/components/InitSettingsModal.jsx +++ /dev/null @@ -1,253 +0,0 @@ -'use client' - -import { useEffect, useState, memo, useCallback } from 'react' -import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input, Select, SelectItem } from '@nextui-org/react' -import { useRecoilState, useRecoilValue } from 'recoil' -import { modalContent, modalState } from '@/store/modalAtom' -import { canvasSettingState } from '@/store/canvasAtom' -import { useAxios } from '@/hooks/useAxios' - -export default function InitSettingsModal(props) { - const [objectNo, setObjectNo] = useState('test123240909003') // 후에 삭제 필요 - const [open, setOpen] = useRecoilState(modalState) - const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) - const [roofMaterials, setRoofMaterials] = useState([]) - const [basicSetting, setBasicSettings] = useState({ - roofDrawingSet: '1', - roofSizeSet: '1', - roofAngleSet: 'slope', - roofs: [{ roofSeq: '1', roofType: '3', roofWidth: '200', roofHeight: '200', roofGap: '0', roofLayout: 'parallel' }], - }) - - const modelProps = { - open, - setOpen, - } - - const { get, post } = useAxios() - - useEffect(() => { - get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${objectNo}` }).then((res) => { - if (res.length == 0) return - - // 'roofs' 배열을 생성하여 각 항목을 추가 - const roofsRow = res.map((item) => { - return { - roofDrawingSet: String(item.roofDrawingSet), - roofSizeSet: String(item.roofSizeSet), - roofAngleSet: item.roofAngleSet, - } - }) - - const roofsArray = res.some((item) => !item.roofSeq) - ? //최초 지붕재 추가 정보의 경우 roofsArray를 초기화 설정 - [{ roofSeq: '1', roofType: '3', roofWidth: '200', roofHeight: '200', roofGap: '0', roofLayout: 'parallel' }] - : res.map((item) => ({ - roofSeq: String(item.roofSeq), - roofType: String(item.roofType), - roofWidth: String(item.roofWidth), - roofHeight: String(item.roofHeight), - roofGap: String(item.roofGap), - roofLayout: item.roofLayout, - })) - - // 나머지 데이터와 함께 'roofs' 배열을 patternData에 넣음 - const patternData = { - roofDrawingSet: roofsRow[0].roofDrawingSet, // 첫 번째 항목의 값을 사용 - roofSizeSet: roofsRow[0].roofSizeSet, // 첫 번째 항목의 값을 사용 - roofAngleSet: roofsRow[0].roofAngleSet, // 첫 번째 항목의 값을 사용 - roofs: roofsArray, // 만들어진 roofs 배열 - } - - // 데이터 설정 - setBasicSettings({ ...patternData }) - }) - - if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { - setBasicSettings({ ...canvasSetting }) - } - }, []) - - //기본 설정값 변경 함수 - const handleBasicSetting = (event) => { - const newBasicSetting = { ...basicSetting, [event.target.name]: event.target.value } - setBasicSettings(newBasicSetting) - } - - //배열 값 변경 함수 - const handleRoofSettings = (id, event) => { - // 기본 세팅에서 roofs 배열을 복사 - const updatedRoofs = [...basicSetting.roofs] - - // roofSeq가 id와 일치하는 항목의 인덱스 찾기 - const index = updatedRoofs.findIndex((roof) => roof.roofSeq === id) - - if (index !== -1) { - // 해당 인덱스의 항목을 수정 - updatedRoofs[index] = { - ...updatedRoofs[index], - [event.target.name]: event.target.value, - } - - // 수정된 배열을 상태에 반영 - setBasicSettings((prevState) => ({ - ...prevState, - roofs: updatedRoofs, - })) - } - } - - //저장 - const submitCanvasConfig = async () => { - if (!objectNo) { - alert('object_no를 입력하세요.') - return - } - - const patternData = { - objectNo, - roofDrawingSet: basicSetting.roofDrawingSet, - roofSizeSet: basicSetting.roofSizeSet, - roofAngleSet: basicSetting.roofAngleSet, - roofMaterialsAddList: basicSetting.roofs, - } - await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }) - - //Recoil 설정 - setCanvasSetting({ ...basicSetting }) - - // 저장 후 재조회 - //await handleSelect() - } - - return ( - <> -
-
배치면 초기설정
- -
-
- - 치수 입력에 의한 물건작성 - -
-
- -
-
- - 복사도 입력 - 실측값 입력 - 육지붕 - -
-
- -
-
- - 경사 - 각도 - -
-
- - {/* Roofs Array Rendering */} - {basicSetting.roofs && - basicSetting.roofs.map((roof, index) => { - return ( -
- 타입 : - - 너비 : - handleRoofSettings(roof.roofSeq, e)} - /> - mm - 높이 : - handleRoofSettings(roof.roofSeq, e)} - /> - mm - 서까래 간격 : - handleRoofSettings(roof.roofSeq, e)} - /> - mm -
- handleRoofSettings(roof.roofSeq, e)} - > - 병렬식 - 계단식 - -
-
- ) - })} - -
- - - setObjectNo(e.target.value)} /> -
-
- - ) -} diff --git a/src/components/Playground.jsx b/src/components/Playground.jsx deleted file mode 100644 index 8a365646..00000000 --- a/src/components/Playground.jsx +++ /dev/null @@ -1,919 +0,0 @@ -'use client' - -import { useRef, useState, useEffect, useContext } from 'react' -import Image from 'next/image' -import { useRecoilState } from 'recoil' -import { v4 as uuidv4 } from 'uuid' -import { FaAnglesUp } from 'react-icons/fa6' -import { FaAnglesDown } from 'react-icons/fa6' -import { Button } from '@nextui-org/react' -import ColorPicker from './common/color-picker/ColorPicker' -import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom' - -import { useAxios } from '@/hooks/useAxios' -import { useMessage } from '@/hooks/useMessage' -import { useMasterController } from '@/hooks/common/useMasterController' -import { useSwal } from '@/hooks/useSwal' -import { convertDwgToPng } from '@/lib/cadAction' -import { GlobalDataContext } from '@/app/GlobalDataProvider' -import QInput from './common/input/Qinput' -import QSelect from './common/select/QSelect' -import QPagination from './common/pagination/QPagination' -import QSelectBox from './common/select/QSelectBox' -import SampleReducer from './sample/SampleReducer' - -import styles from './playground.module.css' -import useSWR from 'swr' -import useSWRMutation from 'swr/mutation' -import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' -import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom' -import { moduleSelectionDataPlanListState } from '@/store/selectedModuleOptions' -import { useRouter } from 'next/navigation' -import { QcastContext } from '@/app/QcastProvider' - -export default function Playground() { - const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) - const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) - const [useGoogleMapFile, setUseGoogleMapFile] = useRecoilState(useGoogleMapFileState) - const [googleMapFileName, setGoogleMapFileName] = useRecoilState(googleMapFileNameState) - const fileRef = useRef(null) - const queryRef = useRef(null) - const [zoom, setZoom] = useState(20) - const { get, promiseGet, post, promisePost, getFetcher, postFetcher } = useAxios() - const testVar = process.env.NEXT_PUBLIC_TEST - const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL - const { getMessage } = useMessage() - const { swalFire } = useSwal() - const { getRoofMaterialList, getModuleTypeItemList, getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController() - - const [color, setColor] = useState('#ff0000') - - const [textInput, setTextInput] = useState('') - const [numberInput, setNumberInput] = useState('') - const [radioInput, setRadioInput] = useState('') - const [checkboxInput, setCheckboxInput] = useState([]) - const [selectedValue, setSelectedValue] = useState('') - - const [users, setUsers] = useState([]) - - const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) - - const router = useRouter() - const { setIsGlobalLoading } = useContext(QcastContext) - - useEffect(() => { - setIsGlobalLoading(false) - }, []) - - useEffect(() => { - console.log('textInput:', textInput) - }, [textInput]) - useEffect(() => { - console.log('numberInput:', numberInput) - }, [numberInput]) - useEffect(() => { - console.log('radioInput:', radioInput) - }, [radioInput]) - useEffect(() => { - console.log('checkboxInput:', checkboxInput) - }, [checkboxInput]) - useEffect(() => { - console.log('selectedValue:', selectedValue) - }, [selectedValue]) - - const handleUsers = async () => { - // const users = await get('/api/user/find-all') - const params = { - url: '/api/user/find-all', - } - const users = await get(params) - console.log('users', users) - } - - const handleConvert = async () => { - console.log('file', fileRef.current.files[0]) - - const formData = new FormData() - formData.append('file', fileRef.current.files[0]) - - await promisePost({ url: converterUrl, data: formData }) - .then((res) => { - console.log('response: ', res) - convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData) - setUseCadFile(true) - setCadFileName(res.data.Files[0].FileName) - swalFire({ text: '파일 변환 완료' }) - }) - .catch((err) => { - console.error(err) - swalFire({ text: '파일 변환 실패' }) - }) - } - - const handleDownImage = async (fileName = '') => { - const fileNm = fileName === '' ? uuidv4() : fileName - const queryString = queryRef.current.value === '' ? '서울시 서대문구 연세로5다길 22-3 발리빌라 3층' : queryRef.current.value - const res = await get({ url: `http://localhost:3000/api/html2canvas?q=${queryString}&fileNm=${fileNm}&zoom=${zoom}` }) - console.log('res', res) - setGoogleMapFileName(res.fileNm) - swalFire({ text: '이미지 저장 완료' }) - setUseGoogleMapFile(true) - } - - const handleZoom = async (type) => { - if (type === 'up') { - setZoom((prevState) => prevState + 1) - } else { - setZoom((prevState) => prevState - 1) - } - - await handleDownImage() - } - - const data = [ - { - id: 1, - author: 'SWYOO', - contents: '버튼 정리(템플릿 적용)', - date: '2024.07.16', - }, - { - id: 2, - author: 'SWYOO', - contents: 'README.md 파일 이미지 경로 수정', - date: '2024.07.17', - }, - { - id: 3, - author: 'SWYOO', - contents: '', - date: '', - }, - ] - - const handleSwalAlert = () => { - swalFire({ - text: '알림 테스트입니다.', - }) - } - - const paginationProps = { - pageNo: 1, - pageSize: 10, - pagePerBlock: 10, - totalCount: 26, - handleChangePage: (page) => { - console.log('page', page) - }, - } - - useEffect(() => { - console.log('users:', users) - }, [users]) - - const codes = [ - { - clHeadCd: '203800', - clCode: 'HEI_455', - clCodeNm: '세로 455mm이하', - clPriority: 1, - name: '세로 455mm이하', - id: 'HEI_455', - }, - { - clHeadCd: '203800', - clCode: 'HEI_500', - clCodeNm: '세로 500mm이하', - clPriority: 2, - name: '세로 500mm이하', - id: 'HEI_500', - }, - { - clHeadCd: '203800', - clCode: 'HEI_606', - clCodeNm: '세로 606mm이하', - clPriority: 3, - name: '세로 606mm이하', - id: 'HEI_606', - }, - { - clHeadCd: '203800', - clCode: 'WID_606', - clCodeNm: '가로 606mm이하', - clPriority: 4, - name: '가로 606mm이하', - id: 'WID_606', - }, - { - clHeadCd: '203800', - clCode: 'ETC', - clCodeNm: '기타', - clPriority: 5, - name: '기타', - id: 'ETC', - }, - ] - - const [myData, setMyData] = useState({ - roofMatlCd: 'ROOF_ID_WA_53A', - roofMatlNm: '화와 A', - roofMatlNmJp: '和瓦A', - widAuth: 'R', - widBase: '265.000', - lenAuth: 'R', - lenBase: '235.000', - roofPchAuth: null, - roofPchBase: null, - raftAuth: 'C', - raftBaseCd: 'HEI_455', - id: 'ROOF_ID_WA_53A', - name: '화와 A', - selected: true, - nameJp: '和瓦A', - length: 235, - width: 265, - layout: 'P', - hajebichi: null, - }) - - const handleChangeMyData = () => { - setMyData({ ...myData, raftBaseCd: 'HEI_500' }) - } - - const [myData2, setMyData2] = useState({}) - - const handleChangeMyData2 = () => { - setMyData2({ - roofMatlCd: 'ROOF_ID_WA_53A', - roofMatlNm: '화와 A', - roofMatlNmJp: '和瓦A', - widAuth: 'R', - widBase: '265.000', - lenAuth: 'R', - lenBase: '235.000', - roofPchAuth: null, - roofPchBase: null, - raftAuth: 'C', - raftBaseCd: 'HEI_455', - id: 'ROOF_ID_WA_53A', - name: '화와 A', - selected: true, - nameJp: '和瓦A', - length: 235, - width: 265, - layout: 'P', - hajebichi: null, - }) - } - - // const [callFlag, setCallFlag] = useState(false) - // const { data: tutoData, error, isLoading } = useSWR('http://localhost:8080/api/tutorial', getFetcher) - // const { data: tutoData, error, isLoading } = useSWR(callFlag ? 'http://localhost:8080/api/tutorial' : null, getFetcher) - // const { trigger, isMutating } = useSWRMutation('http://localhost:8080/api/tutorial', postFetcher) - - // if (isLoading) { - // return
Loading...
- // } - - // if (error) { - // return
Error...
- // } - - // const [moduleSelectionDataPlanListStore, setModuleSelectionDataPlanListStore] = useRecoilState(moduleSelectionDataPlanListState) - // useEffect(() => { - // console.log('🚀 ~ Playground ~ moduleSelectionDataPlanListStore:', moduleSelectionDataPlanListStore) - // }, [moduleSelectionDataPlanListStore]) - // const { trigger: canvasPopupStatusTrigger } = useCanvasPopupStatusController({ objectNo: 'R201T01241120001', planNo: 2, popupType: 2 }) - - return ( - <> -
-
이 영역은 테스트입니다.
-
- {' '} - {' '} - {' '} - {' '} - -
- -
- - - -
- - - -
- - -
- - -
-
-
- - - - -
-
{testVar}
-
-
- -
-
-
-

Sass 테스트입니다.

-
-
test']) }}>
-
-

React ColorPicker

- -
{color}
-
-
-

캐드 파일 이미지 사용

- -
- -
-
-
-

구글 맵 이미지 사용

- -
- -
- {useGoogleMapFile && ( - <> -
-

Zoom Controller : {zoom}

- - -
-
- -
- - )} -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
- {/*
-

{managementStateLoaded?.objectNo}

-
*/} -
- -
- {/*
- {tutoData && - tutoData.map((item) => ( -
- {item.name} / {item.email} -
- ))} -
-
- -
-
- -
*/} -
- -
-
- -
-
- - ) -} diff --git a/src/components/Roof.jsx b/src/components/Roof.jsx deleted file mode 100644 index 51ba639e..00000000 --- a/src/components/Roof.jsx +++ /dev/null @@ -1,351 +0,0 @@ -'use client' - -import { useEffect } from 'react' -import { addDistanceTextToPolygon, getDistance } from '@/util/canvas-util' -import { useCanvas } from '@/hooks/useCanvas' -import { fabric } from 'fabric' -import { v4 as uuidv4 } from 'uuid' - -export default function Roof() { - const { - canvas, - addShape, - handleUndo, - handleRedo, - handleClear, - handleCopy, - handleDelete, - handleSave, - handlePaste, - handleRotate, - attachCustomControlOnPolygon, - saveImage, - handleFlip, - } = useCanvas('canvas') - - useEffect(() => { - let circle = new fabric.Circle({ - radius: 40, - fill: 'rgba(200, 0, 0, 0.3)', - originX: 'center', - originY: 'center', - }) - - let text = new fabric.Textbox('AJLoveChina', { - originX: 'center', - originY: 'center', - textAlign: 'center', - fontSize: 12, - }) - - let group = new fabric.Group([circle, text], { - left: 100, - top: 100, - originX: 'center', - originY: 'center', - }) - - group.on('mousedblclick', () => { - // textForEditing is temporary obj, - // and will be removed after editing - console.log(text.type) - let textForEditing = new fabric.Textbox(text.text, { - originX: 'center', - originY: 'center', - textAlign: text.textAlign, - fontSize: text.fontSize, - - left: group.left, - top: group.top, - }) - - // hide group inside text - text.visible = false - // note important, text cannot be hidden without this - group.addWithUpdate() - - textForEditing.visible = true - // do not give controls, do not allow move/resize/rotation on this - textForEditing.hasConstrols = false - - // now add this temporary obj to canvas - canvas.add(textForEditing) - canvas.setActiveObject(textForEditing) - // make the cursor showing - textForEditing.enterEditing() - textForEditing.selectAll() - - // editing:exited means you click outside of the textForEditing - textForEditing.on('editing:exited', () => { - let newVal = textForEditing.text - let oldVal = text.text - - // then we check if text is changed - if (newVal !== oldVal) { - text.set({ - text: newVal, - visible: true, - }) - - // comment before, you must call this - group.addWithUpdate() - - // we do not need textForEditing anymore - textForEditing.visible = false - canvas?.remove(textForEditing) - - // optional, buf for better user experience - canvas?.setActiveObject(group) - } - }) - }) - - canvas?.add(group) - }, [canvas]) - - const addRect = () => { - const rect = new fabric.Rect({ - height: 200, - width: 200, - top: 10, - left: 10, - opacity: 0.4, - fill: randomColor(), - stroke: 'red', - name: uuidv4(), - }) - - addShape(rect) - } - - const addHorizontalLine = () => { - const { x1, y1, x2, y2 } = { x1: 20, y1: 100, x2: 220, y2: 100 } - /** - * 시작X,시작Y,도착X,도착Y 좌표 - */ - const horizontalLine = new fabric.Line([x1, y1, x2, y2], { - name: uuidv4(), - stroke: 'red', - strokeWidth: 3, - selectable: true, - }) - - const text = new fabric.Text(getDistance(x1, y1, x2, y2).toString(), { - fontSize: 20, - left: (x2 - x1) / 2, - top: y1 - 20, - }) - - const group = new fabric.Group([horizontalLine, text], { - left: 20, - top: 20, - }) - - // addShape(horizontalLine) - addShape(group) - console.log(JSON.stringify(canvas)) - } - - const addVerticalLine = () => { - const verticalLine = new fabric.Line([10, 10, 10, 100], { - name: uuidv4(), - stroke: 'red', - strokeWidth: 3, - selectable: true, - }) - - addShape(verticalLine) - } - - const addTriangle = () => { - const triangle = new fabric.Triangle({ - name: uuidv4(), - top: 50, - left: 50, - width: 100, - stroke: randomColor(), - strokeWidth: 3, - }) - - addShape(triangle) - } - - const addTrapezoid = () => { - const trapezoid = new fabric.Polygon( - [ - { x: 100, y: 100 }, // 좌상단 - { x: 500, y: 100 }, // 우상단 - { x: 750, y: 700 }, // 우하단 - { x: 250, y: 400 }, // 좌하단 - ], - { - name: uuidv4(), - stroke: 'red', - opacity: 0.4, - strokeWidth: 3, - selectable: true, - objectCaching: false, - }, - ) - attachCustomControlOnPolygon(trapezoid) - const group = addDistanceTextToPolygon(trapezoid) - addGroupClickEvent(group) - canvas?.add(group) - canvas?.renderAll() - } - - // group에 클릭 이벤트를 추가하여 클릭 시 group을 제거하고 object들만 남기는 함수 - function addGroupClickEvent(group) { - group.on('selected', (e) => { - console.log(e) - }) - group.on('mousedblclick', (e) => { - // textForEditing is temporary obj, - // and will be removed after editing - const pointer = canvas?.getPointer(e.e) // 마우스 클릭 위치 가져오기 - let minDistance = Infinity - let closestTextbox = null - const groupPoint = group.getCenterPoint() - group.getObjects().forEach(function (object) { - if (object.type === 'textbox') { - // 객체가 TextBox인지 확인 - - const objectCenter = object.getCenterPoint() // TextBox 객체의 중심점 가져오기 - const dx = objectCenter.x + groupPoint.x - pointer.x - const dy = objectCenter.y + groupPoint.y - pointer.y - const distance = Math.sqrt(dx * dx + dy * dy) // 마우스 클릭 위치와 TextBox 객체 사이의 거리 계산 - - if (distance < minDistance) { - // 가장 짧은 거리를 가진 TextBox 객체 찾기 - minDistance = distance - closestTextbox = object - } - } - }) - - let textForEditing = new fabric.Textbox(closestTextbox.text, { - originX: 'center', - originY: 'center', - textAlign: closestTextbox.textAlign, - fontSize: closestTextbox.fontSize, - left: closestTextbox.left + groupPoint.x, - top: closestTextbox.top + groupPoint.y, - }) - - // hide group inside text - closestTextbox.visible = false - // note important, text cannot be hidden without this - group.addWithUpdate() - - textForEditing.visible = true - // do not give controls, do not allow move/resize/rotation on this - textForEditing.hasConstrols = false - - // now add this temporary obj to canvas - canvas?.add(textForEditing) - canvas?.setActiveObject(textForEditing) - // make the cursor showing - textForEditing?.enterEditing() - textForEditing?.selectAll() - - // editing:exited means you click outside of the textForEditing - textForEditing?.on('editing:exited', () => { - let newVal = textForEditing.text - - // then we check if text is changed - closestTextbox.set({ - text: newVal, - visible: true, - }) - - // comment before, you must call this - group.addWithUpdate() - - // we do not need textForEditing anymore - textForEditing.visible = false - canvas?.remove(textForEditing) - - // optional, buf for better user experience - canvas?.setActiveObject(group) - }) - }) - } - - // IText를 수정할 때 해당 값을 길이로 갖는 다른 polygon을 생성하고 다시 그룹화하는 함수 - function addTextModifiedEvent(text, polygon, index) { - text.on('editing:exited', function () {}) - } - - const randomColor = () => { - return '#' + Math.round(Math.random() * 0xffffff).toString(16) - } - - return ( - <> -
- - - - - - - - - - - - - - - -
- -
- -
- - ) -} diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx deleted file mode 100644 index 731fe8c6..00000000 --- a/src/components/Roof2.jsx +++ /dev/null @@ -1,1099 +0,0 @@ -'use client' - -import { useCanvas } from '@/hooks/useCanvas' -import { useEffect, useRef, useState } from 'react' -import { v4 as uuidv4 } from 'uuid' -import { useMode } from '@/hooks/useMode' -import { LINE_TYPE, Mode } from '@/common/common' -import { Button } from '@nextui-org/react' -import RangeSlider from './ui/RangeSlider' -import { useRecoilState, useRecoilValue } from 'recoil' -import { - cadFileCompleteState, - cadFileNameState, - canvasSizeState, - compassState, - currentObjectState, - fontSizeState, - globalCompassState, - googleMapFileNameState, - roofMaterialState, - roofState, - sortedPolygonArray, - templateTypeState, - useCadFileState, - useGoogleMapFileState, - wallState, -} from '@/store/canvasAtom' -import { QLine } from '@/components/fabric/QLine' -import { getCanvasState, insertCanvasState } from '@/lib/canvas' -import { calculateIntersection } from '@/util/canvas-util' -import { QPolygon } from '@/components/fabric/QPolygon' -import QContextMenu from './common/context-menu/QContextMenu' -import { modalContent, modalState } from '@/store/modalAtom' -import { useAxios } from '@/hooks/useAxios' -import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu' -import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu' -import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu' - -import InitSettingsModal from './InitSettingsModal' -import GridSettingsModal from './GridSettingsModal' -import { SurfaceShapeModal } from '@/components/ui/SurfaceShape' -import { changeCurrentRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils' -import ThumbnailList from '@/components/ui/ThumbnailLIst' -import ObjectPlacement from '@/components/ui/ObjectPlacement' -import { globalLocaleStore } from '@/store/localeAtom' - -export default function Roof2(props) { - const { name, userId, email, isLoggedIn } = props - const { - canvas, - handleRedo, - handleUndo, - setCanvasBackgroundWithDots, - saveImage, - addCanvas, - handleBackImageLoadToCanvas, - handleCadImageInit, - backImg, - setBackImg, - } = useCanvas('canvas') - - const globalLocaleState = useRecoilValue(globalLocaleStore) - - const { get } = useAxios(globalLocaleState) - - const canvasRef = useRef(null) - - //canvas 기본 사이즈 - const [canvasSize, setCanvasSize] = useRecoilState(canvasSizeState) - - //canvas 가로 사이즈 - const [verticalSize, setVerticalSize] = useState(canvasSize.vertical) - //canvas 세로 사이즈 - const [horizontalSize, setHorizontalSize] = useState(canvasSize.horizontal) - // 글자크기 - const [fontSize, setFontSize] = useRecoilState(fontSizeState) - - const [sortedArray] = useRecoilState(sortedPolygonArray) - - const [angle, setAngle] = useState(0) - - const [showControl, setShowControl] = useState(false) - - //지붕재 - const roofMaterial = useRecoilValue(roofMaterialState) - - const [templateType, setTemplateType] = useRecoilState(templateTypeState) - - const [compass, setCompass] = useRecoilState(compassState) - - const roof = useRecoilValue(roofState) - - const wall = useRecoilValue(wallState) - - const [open, setOpen] = useRecoilState(modalState) - const [contents, setContent] = useRecoilState(modalContent) - - const [scale, setScale] = useState(1) - const currentObject = useRecoilValue(currentObjectState) - - //canvas 썸네일 - const [thumbnails, setThumbnails] = useState([]) - const thumbnailProps = { - thumbnails, - canvas, - } - - let imgPath - // cad 파일 업로드 - const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) - const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) - const [cadFileComplete, setCadFileComplete] = useRecoilState(cadFileCompleteState) - useCadFile && (imgPath = `/cadImages/${cadFileName}`) - - // 구글맵 이미지 업로드 - const [useGoogleMapFile, setUseGoogleMapFile] = useRecoilState(useGoogleMapFileState) - const [googleMapFileName, setGoogleMapFileName] = useRecoilState(googleMapFileNameState) - useGoogleMapFile && (imgPath = `/mapImages/${googleMapFileName}`) - - const [globalCampass, setGlobalCampass] = useRecoilState(globalCompassState) - - const { - mode, - setMode, - changeMode, - handleClear, - zoomIn, - zoomOut, - zoom, - togglePolygonLine, - handleOuterlinesTest, - handleOuterlinesTest2, - applyTemplateB, - makeRoofPatternPolygon, - createRoofRack, - drawRoofPolygon, - drawCellInTrestle, - drawCellManualInTrestle, - setDirectionTrestles, - cutHelpLines, - } = useMode() - - // const [canvasState, setCanvasState] = useRecoilState(canvasAtom) - - useEffect(() => { - get({ url: `/api/canvas-management/canvas-statuses/by-object/test123240822001/${userId}` }).then((res) => { - // console.log(res) - - const arrangeData = res.map((item) => { - // console.log(item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '')) - const test = item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '') - const test2 = test.substring(1, test.length - 1) - return { - id: item.id, - userId: item.userId, - imageName: `/canvasState/${item.imageName}.png`, - canvasStatus: JSON.stringify(test2), - } - }) - setThumbnails(arrangeData) - }) - }, []) - - useEffect(() => { - if (!canvas) { - return - } - changeMode(canvas, mode) - - if (!cadFileComplete && useCadFile) { - // cad 파일 로드 - useCadFile && handleBackImageLoadToCanvas(imgPath, canvas) - } - - if (useGoogleMapFile) { - handleBackImageLoadToCanvas(imgPath, canvas) - } - }, [canvas, mode]) - - const makeLine = () => { - if (canvas) { - const line = new QLine([50, 50, 200, 50], { - stroke: 'black', - selectable: true, - strokeWidth: 2, - fontSize: fontSize, - }) - - canvas?.add(line) - } - } - - const makePolygon = () => { - if (canvas) { - const polygon = new QPolygon( - [ - { x: 100, y: 100 }, - { x: 600, y: 200 }, - { x: 700, y: 800 }, - { x: 100, y: 800 }, - ], - { - fill: 'transparent', - stroke: 'black', - strokeWidth: 2, - selectable: true, - fontSize: fontSize, - }, - ) - canvas?.add(polygon) - - // polygon.fillCell({ width: 50, height: 30, padding: 10 }) - } - } - - useEffect(() => { - setCanvasSize({ ...canvasSize, vertical: parseInt(verticalSize), horizontal: parseInt(horizontalSize) }) - }, [verticalSize, horizontalSize]) - - /** - * 값 변경시 - */ - // useEffect(() => { - // canvasSizeMode() - // }, [verticalSize, horizontalSize]) - useEffect(() => { - const { vertical, horizontal } = canvasSize - if (vertical !== verticalSize || horizontal !== horizontalSize) { - canvas?.setWidth(horizontalSize) - canvas?.setHeight(verticalSize) - canvas?.renderAll() - } - }, [canvasSize, canvas]) - - const makeQPolygon = () => { - const type1 = [ - { x: 100, y: 100 }, - { x: 850, y: 100 }, - { x: 850, y: 800 }, - { x: 500, y: 800 }, - { x: 500, y: 400 }, - { x: 100, y: 400 }, - ] - const type2 = [ - { x: 200, y: 100 }, - { x: 200, y: 1000 }, - { x: 1100, y: 1000 }, - { x: 1100, y: 600 }, - { x: 650, y: 600 }, - { x: 650, y: 100 }, - ] - - const type3 = [ - { x: 200, y: 100 }, - { x: 200, y: 800 }, - { x: 500, y: 800 }, - { x: 500, y: 300 }, - { x: 800, y: 300 }, - { x: 800, y: 100 }, - ] - - const type4 = [ - { x: 150, y: 450 }, - { x: 150, y: 800 }, - { x: 750, y: 800 }, - { x: 750, y: 300 }, - { x: 550, y: 300 }, - { x: 550, y: 450 }, - ] - - const type1A = [ - { x: 67, y: 81 }, - { x: 67, y: 660 }, - { x: 437, y: 660 }, - { x: 437, y: 1190 }, - { x: 858, y: 1190 }, - { x: 858, y: 81 }, - ] - - const type1B = [ - { x: 137, y: 42 }, - { x: 137, y: 621 }, - { x: 667, y: 621 }, - { x: 667, y: 991 }, - { x: 1088, y: 991 }, - { x: 1088, y: 42 }, - ] - - const eightPoint = [ - { x: 240.1111, y: 130.1111 }, - { x: 240.1111, y: 630.1111 }, - { x: 640.1111, y: 630.1111 }, - { x: 640.1111, y: 480.1111 }, - { x: 440.1111, y: 480.1111 }, - { x: 440.1111, y: 280.1111 }, - { x: 740.1111, y: 280.1111 }, - { x: 740.1111, y: 130.1111 }, - ] - - const eightPoint2 = [ - { x: 197, y: 215 }, - { x: 197, y: 815 }, - { x: 397, y: 815 }, - { x: 397, y: 1115 }, - { x: 697, y: 1115 }, - { x: 697, y: 815 }, - { x: 897, y: 815 }, - { x: 897, y: 215 }, - ] - - const eightPoint3 = [ - { x: 190, y: 147 }, - { x: 190, y: 747 }, - { x: 490, y: 747 }, - { x: 490, y: 497 }, - { x: 640, y: 497 }, - { x: 640, y: 747 }, - { x: 1090, y: 747 }, - { x: 1090, y: 147 }, - ] - - const eightPoint4 = [ - { x: 200, y: 200 }, - { x: 200, y: 400 }, - { x: 500, y: 400 }, - { x: 500, y: 700 }, - { x: 800, y: 700 }, - { x: 800, y: 400 }, - { x: 1100, y: 400 }, - { x: 1100, y: 200 }, - ] - - const eightPoint5 = [ - { x: 140, y: 101 }, - { x: 140, y: 601 }, - { x: 440, y: 601 }, - { x: 440, y: 801 }, - { x: 840, y: 801 }, - { x: 840, y: 601 }, - { x: 1140, y: 601 }, - { x: 1140, y: 101 }, - ] - - const twelvePoint = [ - { x: 195, y: 166 }, - { x: 195, y: 466 }, - { x: 395, y: 466 }, - { x: 395, y: 766 }, - { x: 545, y: 766 }, - { x: 545, y: 466 }, - { x: 695, y: 466 }, - { x: 695, y: 666 }, - { x: 845, y: 666 }, - { x: 845, y: 466 }, - { x: 995, y: 466 }, - { x: 995, y: 166 }, - ] - - const twelvePoint2 = [ - { x: 165, y: 81 }, - { x: 165, y: 1081 }, - { x: 465, y: 1081 }, - { x: 465, y: 781 }, - { x: 765, y: 781 }, - { x: 765, y: 1081 }, - { x: 1065, y: 1081 }, - { x: 1065, y: 581 }, - { x: 765, y: 581 }, - { x: 765, y: 281 }, - { x: 1065, y: 281 }, - { x: 1065, y: 81 }, - ] - - const complicatedType = [ - { x: 100, y: 100 }, - { x: 100, y: 1100 }, - { x: 400, y: 1100 }, - { x: 400, y: 800 }, - { x: 700, y: 800 }, - { x: 700, y: 1100 }, - { x: 1000, y: 1100 }, - { x: 1000, y: 600 }, - { x: 700, y: 600 }, - { x: 700, y: 300 }, - { x: 1000, y: 300 }, - { x: 1000, y: 100 }, - ] - - const testType = [ - { x: 500, y: 400 }, - { x: 650, y: 550 }, - { x: 575, y: 625 }, - { x: 325, y: 625 }, - { x: 100, y: 400 }, - ] - - const testType2 = [ - { x: 100, y: 400 }, - { x: 325, y: 625 }, - { x: 575, y: 625 }, - { x: 650, y: 550 }, - { x: 500, y: 400 }, - ] - - const triangleType = [ - { x: 100, y: 100 }, - { x: 100, y: 600 }, - { x: 600, y: 600 }, - { x: 600, y: 100 }, - ] - - const rectangleType1 = [ - { x: 500, y: 100 }, - { x: 500, y: 800 }, - { x: 900, y: 800 }, - { x: 900, y: 100 }, - ] - - const rectangleType2 = [ - { x: 100, y: 100 }, - { x: 100, y: 300 }, - { x: 600, y: 300 }, - { x: 600, y: 100 }, - ] - - const types = [type1, type2, type3, type4, type1A, type1B, eightPoint, eightPoint2, eightPoint3, eightPoint4, twelvePoint] - const newP = [ - { x: 450, y: 450 }, - { x: 650, y: 250 }, - { x: 675, y: 275 }, - { x: 450, y: 850 }, - ] - - const test1 = [ - { x: 381, y: 178 }, - { x: 381, y: 659.3 }, - { x: 773.3, y: 659.3 }, - { x: 773.3, y: 497.9 }, - { x: 1457, y: 497.9 }, - { x: 1457, y: 178 }, - ] - - const test2 = [ - { x: 113, y: 114.9 }, - { x: 113, y: 371.9 }, - { x: 762, y: 371.9 }, - { x: 762, y: 818.7 }, - { x: 1478.6, y: 818.7 }, - { x: 1478.6, y: 114.9 }, - ] - - const test3 = [ - { x: 100, y: 100 }, - { x: 100, y: 600 }, - { x: 600, y: 600 }, - { x: 600, y: 100 }, - { x: 500, y: 100 }, - { x: 500, y: 200 }, - { x: 200, y: 200 }, - { x: 200, y: 100 }, - ] - - const test4 = [ - { x: 100, y: 100 }, - { x: 100, y: 1000 }, - { x: 1100, y: 1000 }, - { x: 1100, y: 550 }, - { x: 500, y: 550 }, - { x: 500, y: 100 }, - ] - - const polygon = new QPolygon(test4, { - fill: 'transparent', - stroke: 'green', - strokeWidth: 1, - selectable: false, - fontSize: fontSize, - name: 'wall', - }) - - canvas?.add(polygon) - handleOuterlinesTest2(polygon, 50) - setTemplateType(1) - } - - const rotateShape = () => { - if (canvas) { - const activeObject = canvas?.getActiveObject() - - if (activeObject) { - activeObject.rotate(angle) - canvas?.renderAll() - } - } - } - - const makeQLine = () => { - if (canvas) { - const line = new QLine([50, 250, 900, 250], { - stroke: 'black', - strokeWidth: 5, - fontSize: fontSize, - selectable: true, - }) - - const line2 = new QLine([450, 450, 821, 78], { - stroke: 'black', - strokeWidth: 5, - fontSize: fontSize, - selectable: true, - }) - - canvas?.add(line) - canvas?.add(line2) - - const interSectionPoint = calculateIntersection(line, line2) - - if (interSectionPoint) { - const circle = new fabric.Circle({ - radius: 5, - fill: 'red', - left: interSectionPoint.x - 5, - top: interSectionPoint.y - 5, - }) - - canvas?.add(circle) - } - } - } - - const addBackgroundInPolygon = (polygon) => { - fabric.Image.fromURL('assets/img/check2.png', function (img) { - // 패턴 객체를 생성합니다. - const pattern = new fabric.Pattern({ - source: img.getElement(), - repeat: 'repeat', - }) - - polygon.fillBackground(pattern) - }) - } - - function PolygonToLine() { - const polygon = canvas?.getActiveObject() - - if (polygon.type !== 'QPolygon') { - return - } - - const lines = togglePolygonLine(polygon) - } - - /** - * canvas 내용 저장하기 - */ - const handleSaveCanvas = async () => { - // const jsonStr = JSON.stringify(canvas?.toDatalessJSON(['type', 'fontSize'])) - const jsonObj = JSON.stringify(canvas?.toDatalessJSON(['type', 'fontSize', 'lines'])) - console.log(jsonObj) - - const param = { - loginId: 'test', - canvas: jsonObj, - } - console.log(param) - - await insertCanvasState(param) - handleClear() - } - - const drawRoofMaterial = () => { - const { width, height, roofStyle } = roofMaterial - - const wallPolygon = canvas?.getObjects().find((obj) => obj.name === 'wall') - - wallPolygon.set('strokeDashArray', [10, 5, 2, 5]) - wallPolygon.set('stroke', 'blue') - wallPolygon.set('strokeWidth', 1) - - const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof') - - roofs.forEach((roof) => { - let maxLengthLine = roof.lines.reduce((acc, cur) => { - return acc.length > cur.length ? acc : cur - }) - - const roofRatio = window.devicePixelRatio || 1 - - // 패턴 소스를 위한 임시 캔버스 생성 - const patternSourceCanvas = document.createElement('canvas') - if (roofStyle === 1) { - if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') { - patternSourceCanvas.width = width * roofRatio - patternSourceCanvas.height = height * roofRatio - } else { - patternSourceCanvas.width = height * roofRatio - patternSourceCanvas.height = width * roofRatio - } - } else if (roofStyle === 2) { - if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') { - patternSourceCanvas.width = width * 2 - patternSourceCanvas.height = height * 2 - } else { - patternSourceCanvas.width = height * 2 - patternSourceCanvas.height = width * 2 - } - } - - const ctx = patternSourceCanvas.getContext('2d') - - ctx.scale(roofRatio, roofRatio) - ctx.strokeStyle = 'green' - ctx.lineWidth = 0.4 - // 벽돌 패턴 그리기 - if (roofStyle === 1) { - ctx.strokeRect(0, 0, 50, 30) - } else if (roofStyle === 2) { - // 지그재그 - ctx.strokeRect(0, 0, 200, 100) - ctx.strokeRect(100, 100, 200, 100) - } - - // 패턴 생성 - const pattern = new fabric.Pattern({ - source: patternSourceCanvas, - repeat: 'repeat', - }) - roof.set('fill', null) - - roof.set('fill', pattern) - canvas?.renderAll() - }) - } - - /** - * canvas 내용 불러오기 - */ - const handleLoadCanvas = async () => { - const canvasStates = await getCanvasState() - console.log(JSON.parse(canvasStates.canvas)) - canvas?.loadFromJSON(JSON.parse(canvasStates.canvas)) - } - - /** - * 컨트롤러 보이기/숨기기 - */ - const handleShowController = () => { - setShowControl(!showControl) - } - - const drawRoofPatterns = (roofStyle) => { - makeRoofPatternPolygon(roofStyle) - } - - const deleteCell = () => { - const selectedCells = canvas?.getObjects().filter((obj) => obj.name === 'cell' && obj.selected) - - selectedCells.forEach((cell) => { - canvas?.remove(cell) - }) - } - - const setCompassState = (degree) => { - setCompass(degree) - } - - const changeLength = (e) => { - const polygon = canvas?.getActiveObject() - - if (polygon?.type !== 'QPolygon') { - return - } - setScale(e) - polygon.setScaleX(e) - - canvas?.renderAll() - } - - const moduleConfiguration = () => { - createRoofRack() - } - - const setDirectionStringToArrow = () => { - drawDirectionStringToArrow(canvas, globalCampass) - - /** - * 나중에 유틸로 다시 구현 - */ - // const groupShapes = canvas?.getObjects().filter((obj) => obj.name === 'cellGroup') - - // console.log('groupShapes', groupShapes) - - // groupShapes.forEach((obj) => { - // let originAngle = obj._objects.find((array) => array.originAngle !== undefined).originAngle - - // console.log('originAngle', originAngle) - - // let rotateAngle = globalCampass - - // // let rotateAngle = originAngle + globalCampass - // // if (rotateAngle > 360) { - // // rotateAngle -= 360 - // // } - - // console.log('rotateAngle', rotateAngle) - - // obj.set({ angle: rotateAngle, originX: 'center', originY: 'center' }) - // obj.setCoords() - // }) - canvas?.renderAll() - } - - const setHipRoof = () => { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.EAVES - currentRoof.attributes.offset = 50 - changeCurrentRoof(currentRoof, canvas) - } - const setGableRoof = () => { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.GABLE - currentRoof.attributes.offset = 30 - changeCurrentRoof(currentRoof, canvas) - } - const setHipAndGableRoof = () => { - let offset = Number(prompt('팔작지붕 폭', '50')) - if (!isNaN(offset) && offset > 0) { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.HIPANDGABLE - currentRoof.attributes.width = offset - changeCurrentRoof(currentRoof, canvas) - } else { - alert('폭은 0 보다 커야 함') - } - } - const setJerkInHeadRoof = () => { - let offset = Number(prompt('팔작지붕 폭', '50')) - if (!isNaN(offset) && offset > 0) { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.JERKINHEAD - currentRoof.attributes.width = offset - changeCurrentRoof(currentRoof, canvas) - } else { - alert('폭은 0 보다 커야 함') - } - } - const setWallRoof = () => { - let offset = Number(prompt('소매 폭', '0')) - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.WALL - currentRoof.attributes.width = offset - changeCurrentRoof(currentRoof, canvas) - } - return ( - <> - {canvas && ( - <> -
- - - - - - - - - - - - - - - - - - - - - - - - - - { - - } - - 현재 줌 : {zoom}% - - - {/*{templateType === 0 && (*/} - {/* <>*/} - - {/* */} - {/*)}*/} - - - - - - - - - {/**/} - {/* - - */} - - {templateType === 1 && ( - <> - - - - - - )} - - - - - - - -
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - )} - - {/*
-

각도 입력(0~360) 후 방향설정 클릭

- { - const val = e.target.value.replace(/[^-0-9]/g, '') - if (val < 0 || val > 360) { - setGlobalCampass(0) - } else { - setGlobalCampass(Number(val)) - } - }} - /> - -
*/} - {/*
- Compass Circle -
- N, S, E, W Labels -
N
-
S
-
- E -
-
- W -
-
- - Compass Pointer -
- Red Upper Triangle -
-
-
*/} -
- - {!canvas ? null : mode === Mode.DRAW_LINE ? ( - - ) : currentObject?.type === 'QPolygon' ? ( - - ) : currentObject?.type === 'QLine' ? ( - - ) : ( - - )} -
- - ) -} diff --git a/src/components/Settings.jsx b/src/components/Settings.jsx deleted file mode 100644 index 51680711..00000000 --- a/src/components/Settings.jsx +++ /dev/null @@ -1,324 +0,0 @@ -'use client' - -import React, { useEffect, useState } from 'react' -import { Button } from '@nextui-org/react' - -import { useAxios } from '@/hooks/useAxios' - -import { useRecoilState } from 'recoil' -import { customSettingsState } from '@/store/canvasAtom' -import { modalContent, modalState } from '@/store/modalAtom' - -import ColorPicker from './common/color-picker/ColorPicker' - -export default function Settings() { - const [objectNo, setObjectNo] = useState('test123240829010') - const [error, setError] = useState(null) - const [customSettings, setCustomSettings] = useRecoilState(customSettingsState) - - const [color, setColor] = useState('#ff0000') - - const [open, setOpen] = useRecoilState(modalState) - const [contents, setContent] = useRecoilState(modalContent) - - const { get, post } = useAxios() - - const handleSavePopup = () => { - console.log('color ', color) - } - - const handleClosePopup = () => { - setContent('') - setOpen(false) - console.log('colorSetting ', color) - } - - const colorSetting = ( - <> -
-

React ColorPicker

- -
{color}
-
-

- -

- - ) - - const customStyles = { - overlay: { - backgroundColor: 'rgba(0,0,0,0.5)', - }, - content: { - width: '300px', - height: '400px', - margin: 'auto', - borderRadius: '4px', - boxShadow: '0 2px 4px rgba(0,0,0,0.2)', - padding: '20px', - }, - } - - // 상태를 하나의 객체로 관리 - const [settings, setSettings] = useState({ - display1: Array(11).fill(false), // 화면 표시1 - display2: Array(3).fill(false), // 화면 표시2 - rangeSetting: 0, // 흡착 범위 설정 - gridSettings: Array(5).fill(false), // 그리드 설정 - }) - - const gridItems = { - display1: [ - '할당 표시', - '도면 표시', - '그리드 표시', - '문자 표시', - '흐름방향 표시', - '복도치수 표시', - '실제치수 표시', - '치수 표시 없음', - '가대 표시', - '좌표 표시', - '도면전환 표시', - ], - display2: ['테두리만', '라인해치', 'All Painted'], - rangeSetting: ['극소', '소', '중', '대'], - gridSettings: ['임의 그리드', '실선 그리드', '점 그리드', '그리드 색 설정', '흡착점 추가'], - } - - // 초기 조회 - useEffect(() => { - if (!objectNo) { - alert('object_no를 입력하세요.') - } - }, []) - - // 클릭 시 상태 변경 함수 - const handleToggle = (type, index) => { - // '실선 그리드' 클릭 시 팝업 열기 - if (type === 'gridSettings' && gridItems.gridSettings[index] === '실선 그리드') { - //openGridPopup() - } - - // '그리드 색 설정' 클릭 시 팝업 열기 - if (type === 'gridSettings' && gridItems.gridSettings[index] === '그리드 색 설정') { - //setSelectedGridSetting(gridItems.gridSettings[index]) - //setIsPopupOpen(true) - //return prevSettings // 설정은 변경하지 않음 - - setOpen(true) - setContent({ ...colorSetting }) - } - - setSettings((prevSettings) => { - // prevSettings[type]이 배열인지 확인하고, 그렇지 않은 경우 빈 배열로 초기화 - let updated = Array.isArray(prevSettings[type]) ? [...prevSettings[type]] : [] - - if (type === 'rangeSetting') { - return { ...prevSettings, [type]: index } - } - - updated[index] = updated[index] === false ? true : false - return { ...prevSettings, [type]: updated } - }) - } - - // '실선 그리드' 클릭 시 팝업을 열기 위한 함수 - const openGridPopup = () => { - const popupWidth = 500 - const popupHeight = 300 - - // 팝업 창 위치를 화면 중앙으로 조정하기 위해 계산 - const left = window.innerWidth / 2 - popupWidth / 2 - const top = window.innerHeight / 2 - popupHeight / 2 - - // 새 창 열기 - window - .open - //'./components/intro', // 팝업으로 띄울 페이지의 URL - //'_blank', // 새 창으로 열기 - //`width=${popupWidth},height=${popupHeight},top=${top},left=${left}`, // 크기와 위치 지정 - () - } - - // Canvas Setting 조회 및 초기화 - const handleSelect = async () => { - try { - if (!objectNo) { - alert('object_no를 입력하세요.') - return - } - - const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` }) - - // 데이터가 없는 경우 - if (!res) { - console.warn('조회 결과가 없습니다.') - // 기본값을 설정하거나 사용자에게 알림 표시 - setSettings({ - display1: Array(11).fill(false), // 화면 표시1 기본값 - display2: Array(3).fill(false), // 화면 표시2 기본값 - rangeSetting: 0, // 흡착 범위 설정 기본값 - gridSettings: Array(5).fill(false), // 그리드 설정 기본값 - }) - - alert('조회된 데이터가 없습니다. 기본 설정이 적용됩니다.') - return // 이후 코드 실행을 중단 - } - - const data = { - display1: [ - res.assignDisplay, - res.drawDisplay, - res.gridDisplay, - res.charDisplay, - res.flowDisplay, - res.hallwayDimenDisplay, - res.actualDimenDisplay, - res.noDimenDisplay, - res.trestleDisplay, - res.coordiDisplay, - res.drawConverDisplay, - ], - display2: [res.onlyBorder, res.lineHatch, res.allPainted], - rangeSetting: res.adsorpRangeSetting, - gridSettings: [res.randomGrid, res.solidGrid, res.dotGrid, res.gridColorSet, res.adsorpPointAdd], - } - - // 데이터 설정 - setSettings({ - display1: data.display1, - display2: data.display2, - rangeSetting: data.rangeSetting, - gridSettings: data.gridSettings, - }) - } catch (error) { - console.error('Data fetching error:', error) - } - } - - // Canvas Setting 저장 - const handleSubmit = async () => { - if (!objectNo) { - alert('object_no를 입력하세요.') - return - } - - const patternData = { - objectNo, - assignDisplay: settings.display1[0], - drawDisplay: settings.display1[1], - gridDisplay: settings.display1[2], - charDisplay: settings.display1[3], - flowDisplay: settings.display1[4], - hallwayDimenDisplay: settings.display1[5], - actualDimenDisplay: settings.display1[6], - noDimenDisplay: settings.display1[7], - trestleDisplay: settings.display1[8], - coordiDisplay: settings.display1[9], - drawConverDisplay: settings.display1[10], - onlyBorder: settings.display2[0], - lineHatch: settings.display2[1], - allPainted: settings.display2[2], - adsorpRangeSetting: settings.rangeSetting, - randomGrid: settings.gridSettings[0], - solidGrid: settings.gridSettings[1], - dotGrid: settings.gridSettings[2], - gridColorSet: settings.gridSettings[3], - adsorpPointAdd: settings.gridSettings[4], - } - - console.log('patternData', patternData) - - await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) - - //Recoil 설정 - setCustomSettings({ ...patternData }) - - // 저장 후 재조회 - await handleSelect() - } - - return ( - <> -
-
- setObjectNo(e.target.value)} /> - - -
-
-

[디스플레이 설정]

-

* 도면에 표시할 항목을 클릭하면 적용 됩니다.

-
- {gridItems.display1.map((item, index) => ( -
handleToggle('display1', index)} - > - {settings.display1[index]} {item} -
- ))} -
-
-

* 화면 표시

-
- {gridItems.display2.map((item, index) => ( -
handleToggle('display2', index)} - > - {settings.display2[index]} {item} -
- ))} -
-

[글꼴/도면크기 설정]

-

* 글꼴 및 크기 변경

-
-
문자 글꼴 변경
-
흐름방향 글꼴 변경
-
치수 글꼴 변경
-
회로번호 글꼴 변경
-
- `` -

* 흡착 범위 설정

-
- {gridItems.rangeSetting.map((item, index) => ( -
handleToggle('rangeSetting', index)} - > - {item} -
- ))} -
-
-
치수선 설정
-
도면 크기 설정
-
흡착점 ON
-
-

[그리드 설정]

-
- -
{color}
-
-
- {gridItems.gridSettings.map((item, index) => ( -
handleToggle('gridSettings', index)} - > - {settings.gridSettings[index]} {item} -
- ))} -
-
-
- - ) -} diff --git a/src/components/playground.module.css b/src/components/playground.module.css deleted file mode 100644 index 273a4a34..00000000 --- a/src/components/playground.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.test { - @apply bg-red-500; - @apply text-2xl; -} diff --git a/src/hooks/common/useMasterController.js b/src/hooks/common/useMasterController.js index e1c37915..60aab800 100644 --- a/src/hooks/common/useMasterController.js +++ b/src/hooks/common/useMasterController.js @@ -2,10 +2,6 @@ import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' import { useSwal } from '@/hooks/useSwal' import { getQueryString } from '@/util/common-utils' -import { trestleRequest, constructionRequest, trestleDetailRequest } from '@/models/apiModels' -import { POST } from '@/app/api/image-upload/route' -import { canvasState } from '@/store/canvasAtom' -import { useRecoilValue } from 'recoil' /** * 마스터 컨트롤러 훅