diff --git a/src/app/layout.js b/src/app/layout.js index 4f7acb9d..b77e75d0 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -31,6 +31,28 @@ export default async function RootLayout({ children }) { // const isLoggedIn = await checkSession() const session = await getSession() console.log('session[layout]:', session) + + let sessionProps = {} + + if (session.isLoggedIn) { + sessionProps = { + userId: session.userId, + saleStoreId: session.saleStoreId, + name: session.name, + mail: session.mail, + tel: session.tel, + storeId: session.storeId, + userNm: session.userNm, + userNmKana: session.userNmKana, + category: session.category, + telNo: session.telNo, + fax: session.fax, + email: session.email, + pwdInitYn: session.pwdInitYn, + isLoggedIn: session.isLoggedIn, + } + } + if (!headerPathname.includes('/login') && !session.isLoggedIn) { redirect('/login') } @@ -41,7 +63,7 @@ export default async function RootLayout({ children }) { {/*{headerPathname !== '/login' && }*/}
-
+
diff --git a/src/common/common.js b/src/common/common.js index 9de60c9a..157a01b5 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -4,19 +4,27 @@ export const MENU = { ROOF_COVERING: { EXTERIOR_WALL_LINE: 'exteriorWallLine', // 외벽선 그리기 ROOF_SHAPE_SETTINGS: 'roofShapeSettings', // 지붕형상 설정 + ROOF_SHAPE_PASSIVITY_SETTINGS: 'roofShapePassivitySettings', // 지붕형상 수동설정 ROOF_SHAPE_EDITING: 'roofShapeEditing', // 지붕형상 편집 HELP_LINE_DRAWING: 'helpLineDrawing', // 보조선 그리기 + EAVES_KERAVA_EDIT: 'eavesKeravaEdit', // 처마.케라마 변경 + MOVEMENT_SHAPE_UPDOWN: 'movementShapeUpdown', // 동선이동.형올림내림 + OUTLINE_EDIT_OFFSET: 'outlineEditOffset', // 외벽선 편집 및 오프셋 + ROOF_SHAPE_ALLOC: 'rootShapeAlloc', // 지붕면 항당 DEFAULT: 'roofCoveringDefault', // 아무것도 선택 안할 경우 }, // 지붕덮개 BATCH_CANVAS: { + SLOPE_SETTING: 'slopeSetting', // 경사 설정 BATCH_DRAWING: 'batchDrawing', // 배치면 그리기 SURFACE_SHAPE_BATCH: 'surfaceShapeBatch', // 면형상 배치 OBJECT_BATCH: 'objectBatch', // 오브젝트 배치 + ALL_REMOVE: 'allRemove', // 전체 삭제 DEFAULT: 'batchCanvasDefault', // default }, // 배치면 MODULE_CIRCUIT_SETTING: { BASIC_SETTING: 'basicSetting', // 기본설정 CIRCUIT_TRESTLE_SETTING: 'circuitTrestleSetting', // 회로가대설정 + PLAN_ORIENTATION: 'planOrientation', // 도면 방위적용 DEFAULT: 'moduleCircuitSettingDefault', }, // 모듈회로구성 ESTIMATE: 'estimate', // todo 견적서 diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 98c4cba6..d0719d7f 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -119,17 +119,17 @@ export default function CanvasMenu(props) {
{menuNumber !== 6 && menuNumber !== 5 && ( <> + { +
+ {getMessage('plan.mode.vertical.horizontal')} + +
+ }
- {menuNumber !== 4 && ( -
- {getMessage('plan.mode.vertical.horizontal')} - -
- )}
diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index 5db7e3d5..a6b12877 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -1,6 +1,5 @@ 'use client' -import { ToggleonMouse } from '@/components/header/Header' import { useMessage } from '@/hooks/useMessage' import { useEffect, useState } from 'react' import { MENU } from '@/common/common' @@ -30,23 +29,39 @@ export default function MenuDepth01(props) { // 지붕덮개 { id: 0, name: 'plan.menu.roof.cover.outline.drawing', menu: MENU.ROOF_COVERING.EXTERIOR_WALL_LINE }, { id: 1, name: 'plan.menu.roof.cover.roof.shape.setting', menu: MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS }, - { id: 2, name: 'plan.menu.roof.cover.roof.shape.edit', menu: MENU.ROOF_COVERING.ROOF_SHAPE_EDITING }, + { + id: 2, + name: 'plan.menu.roof.cover.roof.shape.passivity.setting', + menu: MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS, + }, { id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing', menu: MENU.ROOF_COVERING.HELP_LINE_DRAWING }, + { id: 4, name: 'plan.menu.roof.cover.eaves.kerava.edit', menu: MENU.ROOF_COVERING.EAVES_KERAVA_EDIT }, + { id: 5, name: 'plan.menu.roof.cover.movement.shape.updown', menu: MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN }, + { id: 6, name: 'plan.menu.roof.cover.outline.edit.offset', menu: MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET }, + { id: 7, name: 'plan.menu.roof.cover.roof.surface.alloc', menu: MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC }, ], surface: [ // 배치면 - { id: 0, name: 'plan.menu.placement.surface.drawing', menu: MENU.BATCH_CANVAS.BATCH_DRAWING }, - { id: 1, name: 'plan.menu.placement.surface.surface', menu: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH }, - { id: 2, name: 'plan.menu.placement.surface.object', menu: MENU.BATCH_CANVAS.OBJECT_BATCH }, + { id: 0, name: 'plan.menu.placement.surface.slope.setting', menu: MENU.BATCH_CANVAS.SLOPE_SETTING }, + { id: 1, name: 'plan.menu.placement.surface.drawing', menu: MENU.BATCH_CANVAS.BATCH_DRAWING }, + { id: 2, name: 'plan.menu.placement.surface.arrangement', menu: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH }, + { id: 3, name: 'plan.menu.placement.surface.object', menu: MENU.BATCH_CANVAS.OBJECT_BATCH }, + { id: 4, name: 'plan.menu.placement.surface.all.remove', menu: MENU.BATCH_CANVAS.ALL_REMOVE }, ], module: [ // 모듈, 회로 구성 + { id: 0, name: 'plan.menu.module.circuit.setting.default', menu: MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING }, { id: 1, name: 'plan.menu.module.circuit.setting.circuit.trestle.setting', menu: MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING, }, + { + id: 2, + name: 'plan.menu.module.circuit.setting.plan.orientation', + menu: MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION, + }, ], } return ( @@ -60,17 +75,6 @@ export default function MenuDepth01(props) { ) })} -
    -
  • ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}> - -
  • -
  • ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}> - -
  • -
  • ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}> - -
  • -
) } diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index a8828b81..9494a6e6 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -2,21 +2,225 @@ import WithDraggable from '@/components/common/draggable/withDraggable' import QSelectBox from '@/components/common/select/QSelectBox' import { useState } from 'react' import { useMessage } from '@/hooks/useMessage' +import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom' +import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' +import { onlyNumberInputChange } from '@/util/input-utils' +import { fabric } from 'fabric' + +const TYPE = { + DOT: 'DOT', + LINE: 'LINE', +} export default function DotLineGrid(props) { // const [modalOption, setModalOption] = useRecoilState(modalState); //modal 열림닫힘 state const [close, setClose] = useState(false) const { setShowDotLineGridModal } = props + const canvas = useRecoilValue(canvasState) + + const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState) + const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState) + const interval = useRecoilValue(dotLineIntervalSelector) + const { getMessage } = useMessage() const SelectOption = [ - { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin') }, - { id: 2, name: '1/2' }, + { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, + { id: 2, name: '1/2', value: 1 / 2 }, { id: 3, name: '1/4', + value: 1 / 4, }, - { id: 4, name: '1/10' }, + { id: 4, name: '1/10', value: 1 / 10 }, ] + const [selectOption, setSelectOption] = useState(SelectOption[0]) + + const HandleClickClose = () => { + // setClose(true) + // setTimeout(() => { + // setModalOption({ ...modalOption, gridoption: false }) + // setClose(false) + // }, 180) + } + + const handleCheckBoxChange = (e) => { + const { value, checked } = e.target + setDotLineGridSettingState((prev) => { + return { + ...prev, + [value]: checked, + } + }) + } + + const handleSave = () => { + // 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거 + canvas + ?.getObjects() + .filter((obj) => obj.name === 'lineGrid') + .forEach((obj) => canvas?.remove(obj)) + canvas + ?.getObjects() + .filter((obj) => obj.name === 'dotGrid') + .forEach((obj) => canvas?.remove(obj)) + + const horizontalInterval = interval.horizontalInterval + const verticalInterval = interval.verticalInterval + + if (dotLineGridSetting.DOT) { + const circle = new fabric.Circle({ + radius: 2, + fill: 'red', + 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: horizontalInterval, + height: verticalInterval, + }) + + 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: canvas.width, y: 0 }, + { x: canvas.width, y: canvas.height }, + { x: 0, y: canvas.height }, + ], + { + fill: pattern, + selectable: false, + name: 'dotGrid', + }, + ) + + canvas.add(backgroundPolygon) + backgroundPolygon.sendToBack() + canvas.renderAll() + } + + if (dotLineGridSetting.LINE) { + for (let i = 0; i < canvas.height / verticalInterval + 1; i++) { + const horizontalLine = new fabric.Line( + [0, i * verticalInterval - verticalInterval / 2, canvas.width, i * verticalInterval - verticalInterval / 2], + { + stroke: 'black', + strokeWidth: 1, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: 'lineGrid', + strokeDashArray: [5, 2], + opacity: 0.3, + direction: 'horizontal', + }, + ) + canvas.add(horizontalLine) + } + + for (let i = 0; i < canvas.width / horizontalInterval + 1; i++) { + const verticalLine = new fabric.Line( + [i * horizontalInterval - horizontalInterval / 2, 0, i * horizontalInterval - horizontalInterval / 2, canvas.height], + { + stroke: 'black', + strokeWidth: 1, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: 'lineGrid', + strokeDashArray: [5, 2], + opacity: 0.3, + direction: 'vertical', + }, + ) + canvas.add(verticalLine) + } + } + + canvas.renderAll() + } + + const handleRadioChange = (e) => { + const { value, name, checked, selected } = e.target + + setDotLineGridSettingState((prev) => { + return { + ...prev, + INTERVAL: { + ...prev.INTERVAL, + type: Number(value), + }, + } + }) + } + + const changeInput = (value, e) => { + const { name } = e.target + setDotLineGridSettingState((prev) => { + return { + ...prev, + INTERVAL: { + ...prev.INTERVAL, + [name]: value, + }, + } + }) + } + + const changeDimension = (result) => { + const { value } = result + setDotLineGridSettingState((prev) => { + return { + ...prev, + INTERVAL: { + ...prev.INTERVAL, + dimension: value, + }, + } + }) + } + + // 초기화 + const reset = () => { + canvas + ?.getObjects() + .filter((obj) => obj.name === 'lineGrid') + .forEach((obj) => canvas?.remove(obj)) + canvas + ?.getObjects() + .filter((obj) => obj.name === 'dotGrid') + .forEach((obj) => canvas?.remove(obj)) + resetDotLineGridSetting() + setSelectOption(SelectOption[0]) + } + return (
@@ -29,55 +233,91 @@ export default function DotLineGrid(props) {
- +
- +
- +
{getMessage('modal.canvas.setting.grid.dot.line.setting.horizon')}
- + onlyNumberInputChange(e, changeInput)} + />
mm
{getMessage('modal.canvas.setting.grid.dot.line.setting.vertical')}
- + onlyNumberInputChange(e, changeInput)} + />
mm
- +
{getMessage('modal.canvas.setting.grid.dot.line.setting.ratio')}
- + onlyNumberInputChange(e, changeInput)} + />
mm
- +
- - + +
diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index 386e98cd..7d389540 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -8,8 +8,10 @@ import { useEvent } from '@/hooks/useEvent' import { adsorptionPointAddModeState, adsorptionPointModeState, + adsorptionRangeState, canvasHistoryState, canvasState, + dotLineIntervalSelector, verticalHorizontalModeState, } from '@/store/canvasAtom' import { @@ -27,22 +29,22 @@ import { distanceBetweenPoints } from '@/util/canvas-util' import { calculateAngle } from '@/util/qpolygon-utils' import { usePolygon } from '@/hooks/usePolygon' import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' +import { useMouse } from '@/hooks/useMouse' export default function OuterLineWall(props) { const { setShowOutlineModal } = props const { getMessage } = useMessage() - const { - addCanvasMouseEventListener, - addDocumentEventListener, - removeAllMouseEventListeners, - removeAllDocumentEventListeners, - removeMouseEvent, - getIntersectMousePoint, - } = useEvent() + const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } = + useEvent() + const { getIntersectMousePoint } = useMouse() const { addLine, removeLine } = useLine() + const { addPolygonByLines } = usePolygon() const verticalHorizontalMode = useRecoilValue(verticalHorizontalModeState) const adsorptionPointAddMode = useRecoilValue(adsorptionPointAddModeState) + const adsorptionPointMode = useRecoilValue(adsorptionPointModeState) + const adsorptionRange = useRecoilValue(adsorptionRangeState) + const interval = useRecoilValue(dotLineIntervalSelector) // 가로 세로 간격 const length1Ref = useRef(null) const length2Ref = useRef(null) @@ -72,7 +74,7 @@ export default function OuterLineWall(props) { return () => { removeAllMouseEventListeners() } - }, [verticalHorizontalMode, points, adsorptionPointAddMode]) + }, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval]) useEffect(() => { arrow1Ref.current = arrow1 diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx index e850f403..3aa2567d 100644 --- a/src/components/floor-plan/modal/setting01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -113,11 +113,11 @@ export default function SecondOption() { // HTTP POST 요청 보내기 await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }).then((res) => { toastUp({ message: getMessage(res.returnMessage), type: 'success' }) - setAdsorptionRange(option.range) }) } catch (error) { toastUp({ message: getMessage(res.returnMessage), type: 'error' }) } + setAdsorptionRange(option.range) } return ( <> diff --git a/src/components/floor-plan/modal/setting01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx index 88f3a972..293d29df 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -14,7 +14,7 @@ export default function SettingModal01(props) { return ( -
+

{getMessage('modal.canvas.setting')}

- +