diff --git a/public/static/images/main/login_email.svg b/public/static/images/main/login_email.svg new file mode 100644 index 00000000..1ea1a274 --- /dev/null +++ b/public/static/images/main/login_email.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/images/sub/address_search.svg b/public/static/images/sub/address_search.svg new file mode 100644 index 00000000..4c0e2d1e --- /dev/null +++ b/public/static/images/sub/address_search.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/static/images/sub/information_help.svg b/public/static/images/sub/information_help.svg new file mode 100644 index 00000000..9eb16941 --- /dev/null +++ b/public/static/images/sub/information_help.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/app/layout.js b/src/app/layout.js index 6c04bbec..f7aafcd0 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -75,7 +75,7 @@ export default async function RootLayout({ children }) { {children} )} - + {/* */} diff --git a/src/components/Main.jsx b/src/components/Main.jsx index 4546f32d..69c90071 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -1,9 +1,169 @@ 'use client' +import React, { useEffect, useState } from 'react' + +import { useRouter } from 'next/navigation' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { modalContent, modalState, modalProps } from '@/store/modalAtom' +import { sessionStore } from '@/store/commonAtom' +import { useAxios } from '@/hooks/useAxios' +import { globalLocaleStore } from '@/store/localeAtom' +import MainContents from './main/MainContents' +import { useMessage } from '@/hooks/useMessage' +import { stuffSearchState } from '@/store/stuffAtom' +import { useForm } from 'react-hook-form' +import '@/styles/contents.scss' +import ChangePasswordPop from './main/ChangePasswordPop' +export default function MainPage() { + const [sessionState, setSessionState] = useRecoilState(sessionStore) + + const globalLocaleState = useRecoilValue(globalLocaleStore) + + const { get } = useAxios(globalLocaleState) + const router = useRouter() + const { getMessage } = useMessage() + + const [searchTxt, setSearchTxt] = useState('') + + const [searchRadioType, setSearchRadioType] = useState('object') + //컨텐츠 관련 + const [saleStoreId, setSaleStoreId] = useState('') + const [saleStoreName, setSaleStoreName] = useState('') + + const [objectList, setObjectList] = useState([]) + const [businessCharger, setBusinessCharger] = useState('') + const [businessChargerMail, setBusinessChargerMail] = useState('') + const [businessChargerTel, setBusinessChargerTel] = useState('') + + const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) + + useEffect(() => { + if (sessionState.pwdInitYn === 'Y') { + fetchObjectList() + } + }, [sessionState]) + + const fetchObjectList = async () => { + try { + // const apiUrl = `/api/main-page/object/X167/list` + const apiUrl = `/api/main-page/object/${sessionState?.storeId}/list` + const res = await get({ url: apiUrl }) + if (res) { + setSaleStoreId(res.saleStoreId) + setSaleStoreName(res.saleStoreName) + setObjectList(res.objectList) + setBusinessCharger(res.businessCharger) + setBusinessChargerMail(res.businessChargerMail) + setBusinessChargerTel(res.businessChargerTel) + } + } catch (error) { + console.error('MAIN API fetching error:', error) + } + } + + // 엔터 이벤트 + const handleByOnKeyUp = (e) => { + if (e.key === 'Enter') { + //물건번호 일떄 + if (searchRadioType === 'object') { + setStuffSearch({ + ...stuffSearch, + schObjectNo: searchTxt, + code: 'M', + }) + router.push('/management/stuff') + } else { + alert('작업중') + return + + //FAQ일떄 + //faq리코일에 + //searchValue= e.target.value + //mainFlag:'Y' + // router.push('/community/faq') + } + } + } + + // 라디오 변경 이벤트 + const handleOnChangeRadio = (e) => { + setSearchRadioType(e.target.value) + } + + // 돋보기 클릭 + const handleOnSubmit = () => { + if (searchRadioType === 'object') { + setStuffSearch({ + ...stuffSearch, + schObjectNo: searchTxt, + code: 'M', + }) + + router.push('/management/stuff') + } else { + alert('작업중') + return + //FAQ일떄 + //faq리코일에 + //searchValue= e.target.value + //mainFlag:'Y' + // router.push('/community/faq') + } + } -export default function MainPage(props) { return ( <> -

Main page

+ {(sessionState?.pwdInitYn !== 'N' && ( + <> +
+
+
+
+
+ {getMessage('main.storeId')}/ {getMessage('main.storeName')} +
+
+ +
+ {saleStoreId} / {saleStoreName} +
+
+
+
+
+ + +
+
+ + +
+
+
+ { + setSearchTxt(e.target.value) + }} + /> + +
+
+ +
+ + )) || ( + <> + + + )} ) } diff --git a/src/components/common/context-menu/QContextMenu.jsx b/src/components/common/context-menu/QContextMenu.jsx index 9654c514..bb721810 100644 --- a/src/components/common/context-menu/QContextMenu.jsx +++ b/src/components/common/context-menu/QContextMenu.jsx @@ -1,5 +1,6 @@ 'use client' -import { Children, useEffect, useState } from 'react' +import { useEffect, useState } from 'react' +import '@/styles/contents.scss' export default function QContextMenu(props) { const { contextRef, canvasProps } = props @@ -7,7 +8,7 @@ export default function QContextMenu(props) { // const children = useRecoilValue(modalContent) const [contextMenu, setContextMenu] = useState({ visible: false, x: 0, y: 0 }) - const activeObject = canvasProps.getActiveObject() //액티브된 객체를 가져옴 + const activeObject = canvasProps?.getActiveObject() //액티브된 객체를 가져옴 let contextType = '' @@ -26,7 +27,8 @@ export default function QContextMenu(props) { const handleContextMenu = (e) => { e.preventDefault() //기존 contextmenu 막고 setContextMenu({ visible: true, x: e.pageX, y: e.pageY }) - canvasProps.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제 + console.log(111, canvasProps) + canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제 } const handleClick = (e) => { @@ -41,7 +43,7 @@ export default function QContextMenu(props) { } } - canvasProps.upperCanvasEl.addEventListener('contextmenu', handleContextMenu) + canvasProps?.upperCanvasEl.addEventListener('contextmenu', handleContextMenu) document.addEventListener('click', handleClick) document.addEventListener('click', handleOutsideClick) @@ -57,7 +59,7 @@ export default function QContextMenu(props) { lockMovementY: false, // Y 축 이동 잠금 }) - canvasProps.on('object:modified', function (e) { + canvasProps?.on('object:modified', function (e) { activeObject.set({ lockMovementX: true, // X 축 이동 잠금 lockMovementY: true, // Y 축 이동 잠금 @@ -89,19 +91,19 @@ export default function QContextMenu(props) { return ( <> {contextMenu.visible && ( -
-
    -
  • handleObjectMove()}> - 이동 -
  • -
  • handleObjectDelete()}> - 삭제 -
  • -
  • handleObjectCopy()}> - 복사 -
  • - {props.children} -
+
+ {/*
    */} + {/*
  • handleObjectMove()}>*/} + {/* 이동*/} + {/*
  • */} + {/*
  • handleObjectDelete()}>*/} + {/* 삭제*/} + {/*
  • */} + {/*
  • handleObjectCopy()}>*/} + {/* 복사*/} + {/*
  • */} + {/*
*/} + {props.children}
)} diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 9c8c9d38..3b823460 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -1,13 +1,19 @@ 'use client' -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' import { useCanvas } from '@/hooks/useCanvas' import { useEvent } from '@/hooks/useEvent' +import QContextMenu from '@/components/common/context-menu/QContextMenu' +import { useRecoilValue } from 'recoil' +import { currentMenuState } from '@/store/canvasAtom' +import { MENU } from '@/common/common' export default function CanvasFrame({ plan }) { const canvasRef = useRef(null) const { canvas } = useCanvas('canvas') + const currentMenu = useRecoilValue(currentMenuState) + const [contextMenu, setContextMenu] = useState([[]]) useEvent() const loadCanvas = () => { @@ -25,9 +31,142 @@ export default function CanvasFrame({ plan }) { loadCanvas() }, [plan]) + useEffect(() => { + switch (currentMenu) { + case MENU.PLAN_DRAWING: + setContextMenu([ + [ + { + name: '그리드 이동', + }, + { + name: '그리드 복사', + }, + { + name: '그리드 색 변경', + }, + { + name: '삭제', + }, + { + name: '전체 삭제', + }, + ], + ]) + break + case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE: + case MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS: + case MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS: + case MENU.ROOF_COVERING.ROOF_SHAPE_EDITING: + case MENU.ROOF_COVERING.HELP_LINE_DRAWING: + case MENU.ROOF_COVERING.EAVES_KERAVA_EDIT: + case MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN: + case MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET: + case MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC: + case MENU.ROOF_COVERING.DEFAULT: + console.log('지붕덮개') + setContextMenu([ + [ + { + name: '지붕재 배치', + }, + { + name: '지붕재 삭제', + }, + { + name: '지붕재 전체 삭제', + }, + { + name: '선택・이동', + }, + { + name: '외벽선 삭제', + }, + ], + [ + { + name: '사이즈 변경', + }, + { + name: '보조선 이동(M)', + }, + { + name: '보조선 복사(C)', + }, + { + name: '보조선 삭제(D)', + }, + { + name: '보조선 수직이등분선', + }, + { + name: '보조선 절삭', + }, + { + name: '보조선 전체 삭제', + }, + ], + ]) + break + case MENU.BATCH_CANVAS.SLOPE_SETTING: + case MENU.BATCH_CANVAS.BATCH_DRAWING: + case MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH: + case MENU.BATCH_CANVAS.OBJECT_BATCH: + case MENU.BATCH_CANVAS.ALL_REMOVE: + case MENU.BATCH_CANVAS.DEFAULT: + console.log('배치면') + setContextMenu([ + [ + { + name: '사이즈 변경', + }, + { + name: '삭제(D)', + }, + { + name: '이동(M)', + }, + { + name: '복사(C)', + }, + ], + [ + { + name: '지붕재 변경', + }, + { + name: '각 변 속성 변경', + }, + { + name: '흐름 방향 변경', + }, + ], + ]) + break + default: + console.log('default') + setContextMenu([]) + break + } + }, [currentMenu]) + + useEffect(() => { + console.log('currentMenu', currentMenu) + console.log('contextMenu', contextMenu) + }, [contextMenu]) + return (
+ + {contextMenu.map((menus, index) => ( +
    + {menus.map((menu) => ( +
  • {menu.name}
  • + ))} +
+ ))} +
) } diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index ba9abb92..d8b7510c 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -44,7 +44,9 @@ export default function CanvasMenu(props) { setShowRoofShapePassivitySettingModal, setShowAuxiliaryModal, setShowEavesGableEditModal, + setShowMovementModal, setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, } = props const [menuNumber, setMenuNumber] = useState(null) @@ -93,10 +95,12 @@ export default function CanvasMenu(props) { setShowRoofShapePassivitySettingModal, setShowAuxiliaryModal, setShowEavesGableEditModal, + setShowMovementModal, setShowSlopeSettingModal, setShowPlacementSurfaceSettingModal, setShowPlaceShapeDrawingModal, setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, setShowObjectSettingModal, type, } @@ -125,6 +129,7 @@ export default function CanvasMenu(props) { setShowOutlineModal(false) setShowCanvasSettingModal(false) setShowEavesGableEditModal(false) + setShowMovementModal(false) setShowPlaceShapeModal(true) } diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index dc032ab0..2902fcf0 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -23,6 +23,9 @@ import EavesGableEdit from '@/components/floor-plan/modal/eavesGable/EavesGableE import WallLineOffsetSetting from '@/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting' import ObjectSetting from '@/components/floor-plan/modal/object/ObjectSetting' import PlacementSurfaceSetting from '@/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting' +import RoofShapePassivitySetting from '@/components/floor-plan/modal/roofShape/RoofShapePassivitySetting' +import MovementSetting from '@/components/floor-plan/modal/movement/MovementSetting' +import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting' export default function FloorPlan() { const [showCanvasSettingModal, setShowCanvasSettingModal] = useState(false) @@ -37,7 +40,9 @@ export default function FloorPlan() { const [showPlaceShapeDrawingModal, setShowPlaceShapeDrawingModal] = useState(false) const [showObjectSettingModal, setShowObjectSettingModal] = useState(false) const [showEavesGableEditModal, setShowEavesGableEditModal] = useState(false) + const [showMovementModal, setShowMovementModal] = useState(false) const [showWallLineOffsetSettingModal, setShowWallLineOffsetSettingModal] = useState(false) + const [showRoofAllocationSettingModal, setShowRoofAllocationSettingModal] = useState(false) const globalLocaleState = useRecoilValue(globalLocaleStore) const { get } = useAxios(globalLocaleState) @@ -73,7 +78,9 @@ export default function FloorPlan() { setShowRoofShapePassivitySettingModal, setShowAuxiliaryModal, setShowEavesGableEditModal, + setShowMovementModal, setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, } useEffect(() => { @@ -132,13 +139,18 @@ export default function FloorPlan() { {showDotLineGridModal && } {showColorPickerModal && } {showPropertiesSettingModal && } + {showPlaceShapeModal && } {showRoofShapeSettingModal && } + {showRoofShapePassivitySettingModal && ( + + )} {showAuxiliaryModal && } {showSlopeSettingModal && } {showPlaceShapeDrawingModal && } {showEavesGableEditModal && } - {/**/} + {showMovementModal && } + {showRoofAllocationSettingModal && } {showWallLineOffsetSettingModal && } {showObjectSettingModal && } {showPlacementSurfaceSettingModal && } diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index e5394610..8cb10b38 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -15,10 +15,12 @@ export default function MenuDepth01(props) { setShowRoofShapePassivitySettingModal, setShowAuxiliaryModal, setShowEavesGableEditModal, + setShowMovementModal, setShowSlopeSettingModal, setShowPlacementSurfaceSettingModal, setShowPlaceShapeDrawingModal, setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, setShowObjectSettingModal, } = props const { getMessage } = useMessage() @@ -28,19 +30,29 @@ export default function MenuDepth01(props) { setActiveMenu(menu) setShowOutlineModal(menu === MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) setCurrentMenu(menu) - + setShowPlaceShapeModal(false) if (type === 'outline') { - setShowPlaceShapeModal(false) setShowOutlineModal(id === 0) setShowRoofShapeSettingModal(id === 1) setShowRoofShapePassivitySettingModal(id === 2) setShowAuxiliaryModal(id === 3) setShowEavesGableEditModal(id === 4) + setShowMovementModal(id === 5) setShowWallLineOffsetSettingModal(id === 6) + setShowRoofAllocationSettingModal(id === 7) setShowPlaceShapeDrawingModal(false) } if (type === 'surface') { + setShowOutlineModal(false) + setShowRoofShapeSettingModal(false) + setShowRoofShapePassivitySettingModal(false) + setShowAuxiliaryModal(false) + setShowEavesGableEditModal(false) + setShowMovementModal(false) + setShowWallLineOffsetSettingModal(false) + setShowRoofAllocationSettingModal(false) + setShowSlopeSettingModal(id === 0) setShowPlaceShapeDrawingModal(id === 1) setShowPlacementSurfaceSettingModal(id === 2) diff --git a/src/components/floor-plan/modal/movement/Movement.jsx b/src/components/floor-plan/modal/movement/MovementSetting.jsx similarity index 53% rename from src/components/floor-plan/modal/movement/Movement.jsx rename to src/components/floor-plan/modal/movement/MovementSetting.jsx index a8a7cde4..569249d6 100644 --- a/src/components/floor-plan/modal/movement/Movement.jsx +++ b/src/components/floor-plan/modal/movement/MovementSetting.jsx @@ -1,21 +1,25 @@ import { useMessage } from '@/hooks/useMessage' import WithDraggable from '@/components/common/draggable/WithDraggable' import { useState } from 'react' +import FlowLine from '@/components/floor-plan/modal/movement/type/FlowLine' +import Updown from '@/components/floor-plan/modal/movement/type/Updown' -export default function Movement({}) { +export default function MovementSetting({ setShowMovementModal }) { const { getMessage } = useMessage() const [buttonAct, setButtonAct] = useState(1) const buttonMenu = [ - { id: 1, name: '銅線の移動軒' }, - { id: 2, name: '型上げ・降り' }, + { id: 1, name: getMessage('modal.movement.flow.line.move') }, + { id: 2, name: getMessage('modal.movement.flow.line.updown') }, ] return (
-

軒・ケラバ変更

- +

{getMessage('plan.menu.roof.cover.movement.shape.updown')}

+
@@ -26,12 +30,12 @@ export default function Movement({}) { ))}
-
設定
- {/*{buttonAct === 1 && }*/} - {/*{buttonAct === 2 && }*/} +
{getMessage('setting')}
+ {buttonAct === 1 && } + {buttonAct === 2 && }
- +
diff --git a/src/components/floor-plan/modal/movement/type/FlowLine.jsx b/src/components/floor-plan/modal/movement/type/FlowLine.jsx new file mode 100644 index 00000000..d1bf8023 --- /dev/null +++ b/src/components/floor-plan/modal/movement/type/FlowLine.jsx @@ -0,0 +1,46 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function FlowLine({}) { + const { getMessage } = useMessage() + + return ( + <> +
+
{getMessage('modal.movement.flow.line.info')}
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
+ +
+ mm +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/movement/type/Updown.jsx b/src/components/floor-plan/modal/movement/type/Updown.jsx new file mode 100644 index 00000000..2650ca4a --- /dev/null +++ b/src/components/floor-plan/modal/movement/type/Updown.jsx @@ -0,0 +1,46 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Updown({}) { + const { getMessage } = useMessage() + + return ( + <> +
+
{getMessage('modal.movement.flow.line.updown.info')}
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
+ +
+ mm +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx new file mode 100644 index 00000000..d42f7fb2 --- /dev/null +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -0,0 +1,222 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import QSelectBox from '@/components/common/select/QSelectBox' + +export default function RoofAllocationSetting({ setShowRoofAllocationSettingModal }) { + const { getMessage } = useMessage() + const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(null) + const [values, setValues] = useState([ + { + id: '1', + type: 'A', + roofMaterial: { name: '기와1' }, + width: { name: '200' }, + length: { name: '250' }, + rafter: { name: '300' }, + alignType: 'stairs', + }, + ]) + + const roofMaterials = [ + { + id: 'A', + name: '기와1', + type: 'A', + width: '200', + length: '200', + alignType: 'parallel', + }, + { + id: 'B', + name: '기와2', + type: 'B', + rafter: '200', + alignType: 'parallel', + }, + { + id: 'C', + name: '기와3', + type: 'C', + hajebichi: '200', + alignType: 'stairs', + }, + { + id: 'D', + name: '기와4', + type: 'D', + length: '200', + alignType: 'stairs', + }, + ] + const widths = [ + { name: '200', id: 'q' }, + { name: '250', id: 'q1' }, + { name: '300', id: 'q2' }, + ] + const lengths = [ + { name: '200', id: 'w' }, + { name: '250', id: 'w1' }, + { name: '300', id: 'w2' }, + ] + const rafters = [ + { name: '200', id: 'e' }, + { name: '250', id: 'e1' }, + { name: '300', id: 'e2' }, + ] + + const onAddRoofMaterial = () => { + setValues([...values, selectedRoofMaterial]) + } + + const onDeleteRoofMaterial = (id) => { + setValues(values.filter((value) => value.id !== id)) + } + + return ( + +
+
+

{getMessage('plan.menu.estimate.roof.alloc')}

+ +
+
+
{getMessage('modal.roof.alloc.info')}
+
+ {getMessage('modal.roof.alloc.select.roof.material')} +
+ setSelectedRoofMaterial(e)} /> +
+ +
+
+ {values.map((value, index) => ( +
+
+ + +
+
+
+
+
+ +
+ {index === 0 && 基本屋根材} + {index !== 0 && } +
+
+
+ {value.type === 'A' ? ( + <> +
+ W +
+ +
+
+
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : value.type === 'B' ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : value.type === 'C' ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+ + ) : value.type === 'D' ? ( + <> +
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : ( + '' + )} +
+
+
+ + +
+
+
+
+ ))} +
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx index ccab2321..ebdc6bb9 100644 --- a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx +++ b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx @@ -25,7 +25,7 @@ export default function RoofShapePassivitySetting({ setShowRoofShapePassivitySet
{buttons.map((button) => ( - ))} diff --git a/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx b/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx index 963cfa63..22e15a34 100644 --- a/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx +++ b/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx @@ -22,24 +22,6 @@ export default function Eaves() {
mm
-
- - {getMessage('gable.offset')} - -
- -
- mm -
-
- - {getMessage('shed.width')} - -
- -
- mm -
) } diff --git a/src/components/main/ChangePasswordPop.jsx b/src/components/main/ChangePasswordPop.jsx new file mode 100644 index 00000000..45685c26 --- /dev/null +++ b/src/components/main/ChangePasswordPop.jsx @@ -0,0 +1,168 @@ +import React from 'react' +import { useMessage } from '@/hooks/useMessage' +import { useForm } from 'react-hook-form' +import { sessionStore } from '@/store/commonAtom' +import { useRecoilValue, useRecoilState } from 'recoil' +import { useAxios } from '@/hooks/useAxios' +import { globalLocaleStore } from '@/store/localeAtom' + +export default function ChangePasswordPop() { + const globalLocaleState = useRecoilValue(globalLocaleStore) + + const { patch } = useAxios(globalLocaleState) + const { getMessage } = useMessage() + const [sessionState, setSessionState] = useRecoilState(sessionStore) + + const formInitValue = { + password1: '', + password2: '', + } + const { register, setValue, getValues, handleSubmit, resetField, control, watch } = useForm({ + defaultValues: formInitValue, + }) + + const form = { register, setValue, getValues, handleSubmit, resetField, control, watch } + + //자리수체크 + const checkLength = (pwd1) => { + let str = new String(pwd1) + let _byte = 0 + if (str.length !== 0) { + for (let i = 0; i < str.length; i++) { + let str2 = str.charAt(i) + if (encodeURIComponent(str2).length > 4) { + _byte += 2 + } else { + _byte++ + } + } + } + return _byte + } + + //공백제거 + const checkValue = (e) => { + let spaceChk = /\s/ + if (spaceChk.exec(e.target.value)) { + e.target.value = e.target.value.replace(/\s|/gi, '') + return false + } + } + + //비밀번호 변경 + const updateProcess = async () => { + const _password1 = form.watch('password1') + const _password2 = form.watch('password2') + + if (_password1 !== _password2) { + alert(getMessage('main.popup.login.validate1')) + return false + } + + //패스워드 길이수 체크 + if (checkLength(_password1) > 10) { + alert(getMessage('main.popup.login.validate2')) + } + + const param = { + loginId: sessionState.userId, + chgType: 'I', + chgPwd: _password1, + } + await patch({ url: '/api/login/v1.0/user/change-password', data: param }).then((res) => { + if (res) { + if (res.result.resultCode === 'S') { + alert(getMessage('main.popup.login.success')) + setSessionState({ ...sessionState, pwdInitYn: 'Y' }) + } else { + alert(res.result.resultMsg) + } + } + }) + } + + return ( +
+
+
+
+

{getMessage('main.popup.login.popupTitle')}

+
+
+
+
+
+
+
+
+
+ {getMessage('main.popup.login.newPassword1')} + * +
+
{getMessage('main.popup.login.placeholder')}
+
+
+
+
+ +
+
+
+
+
+
+
+ {getMessage('main.popup.login.newPassword2')} + * +
+
{getMessage('main.popup.login.placeholder')}
+
+
+
+
+ +
+
+
+
+
+
+ {getMessage('main.popup.login.guide1')} + {getMessage('main.popup.login.guide2')} +
+
+
+ + +
+
+
+
+
+ ) +} diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx new file mode 100644 index 00000000..ba9a8d77 --- /dev/null +++ b/src/components/main/MainContents.jsx @@ -0,0 +1,174 @@ +import React, { useEffect, useState } from 'react' +import ProductItem from './ProductItem' +import { useMessage } from '@/hooks/useMessage' +import Image from 'next/image' +import dayjs from 'dayjs' +import { useAxios } from '@/hooks/useAxios' +import { useRecoilValue } from 'recoil' +import { useRouter } from 'next/navigation' +import { globalLocaleStore } from '@/store/localeAtom' +import { queryStringFormatter } from '@/util/common-utils' +export default function MainContents({ objectList, businessCharger, businessChargerMail, businessChargerTel }) { + const { getMessage } = useMessage() + const router = useRouter() + const globalLocaleState = useRecoilValue(globalLocaleStore) + const { get } = useAxios(globalLocaleState) + + //공지사항 + const [recentNoticeList, setRecentNoticeList] = useState([]) + + //FAQ + const [recentFaqList, setRecentFaqList] = useState([]) + + useEffect(() => { + fetchNoticeList() + fetchFaqList() + }, []) + + //공지사항 호출 + const fetchNoticeList = async () => { + try { + const param = { + schNoticeTpCd: 'QC', + schNoticeClsCd: 'NOTICE', + startRow: 1, + endRow: 1, + } + // const noticeApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=NOTICE&schTitle=&startRow=1&endRow=1` + const noticeApiUrl = `api/board/list?${queryStringFormatter(param)}` + const res = await get({ url: noticeApiUrl }) + //console.log('공지res::', res) + if (res) { + if (res.data.length > 0) { + setRecentNoticeList(res.data) + } + } + } catch (error) { + console.error('NOTICE fetching error:', error) + } + } + + //FAQ 호출 + const fetchFaqList = async () => { + try { + const param = { + schNoticeTpCd: 'QC', + schNoticeClsCd: 'FAQ', + startRow: 1, + endRow: 3, + } + // const faqApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=FAQ&schTitle=&startRow=1&endRow=1` + const faqApiUrl = `api/board/list?${queryStringFormatter(param)}` + const res = await get({ url: faqApiUrl }) + //console.log('FAQres::', res) + if (res) { + if (res.data.length > 0) { + setRecentFaqList(res.data) + } + } + } catch (error) { + console.error('FAQ fetching error:', error) + } + } + + return ( +
+
+ +
    + {objectList?.length > 0 ? ( + <> + {objectList.map((row) => { + return ( +
  • { + if (row.objectNo.substring(0, 1) === 'R') { + router.push(`/management/stuff/detail?objectNo=${row.objectNo.toString()}`) + } else { + router.push(`/management/stuff/tempdetail?objectNo=${row.objectNo.toString()}`) + } + }} + > +
    + {dayjs(row.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')} + {row.objectNo} + {row.objectName} + {row.saleStoreName} +
    +
  • + ) + })} + + ) : ( + <> +
  • +
    최근 갱신 물건이 없습니다
    +
  • + + )} +
+
+ +
+ {recentNoticeList.length > 0 ? ( + <> +
{dayjs(recentNoticeList[0]?.regDt).format('YYYY.MM.DD')}
+
{recentNoticeList[0]?.title}
+
{recentNoticeList[0]?.contents}
+ + ) : null} +
+
+
+
+ +
    + {recentFaqList.length > 0 ? ( + <> + {recentFaqList.map((row) => { + return ( +
  • +
    +
    FAQ {row.noticeNo}
    +
    {row.title}
    +
    {dayjs(row.regDt).format('YYYY.MM.DD')}
    +
    +
  • + ) + })} + + ) : null} +
+
+ +
+ + +
+
+ +
    +
  • +
    + react +
    +
    {businessCharger}
    +
  • +
  • +
    + react +
    +
    {businessChargerMail}
    +
  • +
+
+
+
+ ) +} diff --git a/src/components/main/ProductItem.jsx b/src/components/main/ProductItem.jsx new file mode 100644 index 00000000..928bc269 --- /dev/null +++ b/src/components/main/ProductItem.jsx @@ -0,0 +1,35 @@ +import React from 'react' +import { useRouter } from 'next/navigation' +export default function ProductItem({ num, name, children }) { + const router = useRouter() + + // 더보기 페이지 이동 + const pageMove = (num) => { + if (num === 1) { + router.push('/management/stuff') + } else if (num === 2) { + router.push('/community/notice') + } else { + router.push('/community/faq') + } + } + return ( +
+
+

+ + {name} +

+ {num !== 4 && num !== 5 && ( + + )} +
+
{children}
+
+ ) +} diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 4e899bb8..02f44561 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -278,6 +278,54 @@ export default function Stuff() { // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}` const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}` + + await get({ + url: apiUrl, + }).then((res) => { + if (!isEmptyArray(res)) { + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setGridCount(res[0].totCnt) + } + }) + } + fetchData() + } else { + const params = { + schObjectNo: '', + schAddress: '', + schObjectName: '', + schSaleStoreName: '', + schReceiveUser: '', + schDispCompanyName: '', + schDateType: 'U', + schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), + schToDt: dayjs(new Date()).format('YYYY-MM-DD'), + startRow: (curPage - 1) * defaultSize + 1, + endRow: curPage * defaultSize, + schSelSaleStoreId: '', + schSortType: 'R', + } + + async function fetchData() { + //api에 넘길값 startRow, endRow + // let startRow + // let endRow + // startRow = (curPage - 1) * size + 1 + // endRow = curPage * size + // console.log('startrow::', startRow) + // console.log('endRow::', endRow) + + // let curPage + // let totalpage + // let totalCount + // let size + // let pageCount + + // console.log('화면진입 세션정보::::::::::', sessionState) + // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` + // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}` + const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}` + await get({ url: apiUrl, }).then((res) => { @@ -294,10 +342,10 @@ export default function Stuff() { useEffect(() => { if (stuffSearchParams?.code === 'E') { + //console.log('조회누름::::::::', stuffSearchParams) stuffSearchParams.startRow = (curPage - 1) * defaultSize + 1 stuffSearchParams.endRow = curPage * defaultSize stuffSearchParams.schSortType = defaultSortType - // console.log('조회누름::::::::', stuffSearchParams) async function fetchData() { // console.log('조회누름 세션정보:::::::::::::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` @@ -378,6 +426,7 @@ export default function Stuff() { setAppMessageState(JA) } }, [globalLocaleState]) + return ( <> {/* 퍼블시작 */} diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 97de5079..21b84dd8 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -182,7 +182,7 @@ export default function StuffSearchCondition() { type="text" className="input-light" placeholder="물건번호 입력" - value={stuffSearch?.code === 'E' ? stuffSearch.schObjectNo : objectNo} + value={stuffSearch?.code === 'E' || stuffSearch?.code === 'M' ? stuffSearch.schObjectNo : objectNo} onChange={(e) => { setObjectNo(e.target.value) setStuffSearch({ ...stuffSearch, code: 'S', schObjectNo: e.target.value }) @@ -255,9 +255,6 @@ export default function StuffSearchCondition() { 판매대리점 선택 - {/*
- -
*/} {schSelSaleStoreList?.length > 0 && (