From aab9084f1b6d42dd4e62361086ccbd9cc021f9ff Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 17 Oct 2024 09:54:15 +0900 Subject: [PATCH 1/9] refactor: modify QPagination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 그룹 변경 이벤트 수정 - 외부 함수 주입 추가 --- src/components/Playground.jsx | 3 +++ .../common/pagination/QPagination.jsx | 18 ++++++++++++------ src/hooks/usePagination.js | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/components/Playground.jsx b/src/components/Playground.jsx index a882bdd9..6393158d 100644 --- a/src/components/Playground.jsx +++ b/src/components/Playground.jsx @@ -137,6 +137,9 @@ export default function Playground() { pageSize: 10, pagePerBlock: 10, totalCount: 501, + handleChangePage: (page) => { + console.log('page', page) + }, } return ( diff --git a/src/components/common/pagination/QPagination.jsx b/src/components/common/pagination/QPagination.jsx index 4175036b..54a61541 100644 --- a/src/components/common/pagination/QPagination.jsx +++ b/src/components/common/pagination/QPagination.jsx @@ -1,36 +1,42 @@ import usePagination from '@/hooks/usePagination' export default function QPagination(props) { - const { currentPage, pageRange, changePage, totalPages } = usePagination(props) + const { handleChangePage, pagePerBlock = 10 } = props + const { currentPage, changePage, pageGroup, totalPages, pages, startPage, endPage, pageRange } = usePagination(props) + + const handlePage = (page) => { + handleChangePage(page) + changePage(page) + } return (
  1. - +
  2. {pageRange.map((page) => (
  3. - +
  4. ))}
  5. - +
) diff --git a/src/hooks/usePagination.js b/src/hooks/usePagination.js index 818275e1..4fc3a959 100644 --- a/src/hooks/usePagination.js +++ b/src/hooks/usePagination.js @@ -24,7 +24,7 @@ const usePagination = ({ pageNo = 1, pageSize = 10, pagePerBlock = 10, totalCoun return i + startPage }) - return { currentPage, pageRange, changePage, totalPages } + return { currentPage, changePage, pageGroup, totalPages, pages, startPage, endPage, pageRange } } export default usePagination From e7d988bba6b83abf75cb98144ffb5ca55f5cc92c Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 17 Oct 2024 09:58:06 +0900 Subject: [PATCH 2/9] refactor: QPagination component to modify handleChangePage default value --- src/components/common/pagination/QPagination.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/pagination/QPagination.jsx b/src/components/common/pagination/QPagination.jsx index 54a61541..7eb6638a 100644 --- a/src/components/common/pagination/QPagination.jsx +++ b/src/components/common/pagination/QPagination.jsx @@ -1,7 +1,7 @@ import usePagination from '@/hooks/usePagination' export default function QPagination(props) { - const { handleChangePage, pagePerBlock = 10 } = props + const { handleChangePage = () => {}, pagePerBlock = 10 } = props const { currentPage, changePage, pageGroup, totalPages, pages, startPage, endPage, pageRange } = usePagination(props) const handlePage = (page) => { From 6d6a44698a8174e408a3e454172aa2b61607bc3d Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 17 Oct 2024 10:31:29 +0900 Subject: [PATCH 3/9] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=88=B4=ED=8C=81=20=EB=A9=94=EC=84=B8?= =?UTF-8?q?=EC=A7=80=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 24 +++++++------------ .../management/popup/FindAddressPopQGrid.jsx | 6 +---- .../management/popup/PlanRequestPopQGrid.jsx | 6 +---- src/locales/ja.json | 1 + src/locales/ko.json | 1 + 5 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 9b8bfd4a..7167fc63 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -488,7 +488,7 @@ export default function StuffDetail() { - 물건구분/물건명 * + {getMessage('stuff.detail.objectStatusId')} *
@@ -529,7 +529,9 @@ export default function StuffDetail() { {getMessage('stuff.detail.saleStoreId')} *
-
+
+ {getMessage('stuff.detail.tooltip.saleStoreId')} +
@@ -553,7 +555,9 @@ export default function StuffDetail() {
{getMessage('stuff.detail.otherSaleStoreId')}
-
+
+ {getMessage('stuff.detail.tooltip.saleStoreId')} +
@@ -568,18 +572,6 @@ export default function StuffDetail() { isDisabled={form.watch('saleStoreId') !== '' ? false : true} isClearable={true} /> - {/* */}
-
+
{/*
diff --git a/src/components/management/popup/FindAddressPopQGrid.jsx b/src/components/management/popup/FindAddressPopQGrid.jsx index 83544a5a..b9d1bb90 100644 --- a/src/components/management/popup/FindAddressPopQGrid.jsx +++ b/src/components/management/popup/FindAddressPopQGrid.jsx @@ -31,10 +31,6 @@ export default function FindAddressPopGrid(props) { gridData ? setRowData(gridData) : '' }, [gridData]) - const rowSelection = useMemo(() => { - return { mode: 'singleRow', enableClickSelection: true } - }, []) - const onGridReady = useCallback( (params) => { setGridApi(params.api) @@ -57,7 +53,7 @@ export default function FindAddressPopGrid(props) { rowData={rowData} columnDefs={colDefs} defaultColDef={defaultColDef} - rowSelection={rowSelection} + rowSelection={'singleRow'} pagination={isPageable} onSelectionChanged={onSelectionChanged} /> diff --git a/src/components/management/popup/PlanRequestPopQGrid.jsx b/src/components/management/popup/PlanRequestPopQGrid.jsx index 8f29cdbe..b7dca164 100644 --- a/src/components/management/popup/PlanRequestPopQGrid.jsx +++ b/src/components/management/popup/PlanRequestPopQGrid.jsx @@ -31,10 +31,6 @@ export default function PlanRequestPopQGrid(props) { gridData ? setRowData(gridData) : '' }, [gridData]) - const rowSelection = useMemo(() => { - return { mode: 'singleRow', enableClickSelection: true } - }, []) - const onGridReady = useCallback( (params) => { setGridApi(params.api) @@ -51,7 +47,7 @@ export default function PlanRequestPopQGrid(props) { rowData={rowData} columnDefs={colDefs} defaultColDef={defaultColDef} - rowSelection={rowSelection} + rowSelection={'singleRow'} pagination={isPageable} // onSelectionChanged={onSelectionChanged} /> diff --git a/src/locales/ja.json b/src/locales/ja.json index 8d1319b6..2603d356 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -471,6 +471,7 @@ "stuff.detail.conType0": "余剰", "stuff.detail.conType1": "全量", "stuff.detail.remarks": "メモ", + "stuff.detail.tooltip.saleStoreId": "販売代理店または販売代理店IDを1文字以上入力してください", "stuff.planReqPopup.popTitle": "設計依頼検索", "stuff.planReqPopup.btn1": "検索", "stuff.planReqPopup.btn2": "初期化", diff --git a/src/locales/ko.json b/src/locales/ko.json index 884a8772..2741f5e1 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -476,6 +476,7 @@ "stuff.detail.conType0": "잉여", "stuff.detail.conType1": "전량", "stuff.detail.remarks": "메모", + "stuff.detail.tooltip.saleStoreId": "판매대리점 또는 판매대리점ID를 1자 이상 입력하세요", "stuff.planReqPopup.popTitle": "설계 요청 검색", "stuff.planReqPopup.btn1": "검색", "stuff.planReqPopup.btn2": "초기화", From ee34bd549c6f40f1215456b3dd638fd17e8dd0bc Mon Sep 17 00:00:00 2001 From: leeyongjae Date: Thu, 17 Oct 2024 10:32:55 +0900 Subject: [PATCH 4/9] =?UTF-8?q?Q.CAST=20=EC=9E=90=EB=8F=99=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B9=84?= =?UTF-8?q?=EB=B0=80=EB=B2=88=ED=98=B8=20=EB=B3=80=EA=B2=BD=20=ED=8C=9D?= =?UTF-8?q?=EC=97=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/auth/Login.jsx | 71 +++++++++---------------- src/components/myInfo/UserInfoModal.jsx | 49 ++++++++++++++--- src/locales/ja.json | 2 + src/locales/ko.json | 2 + 4 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index c43341e3..28416284 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -16,8 +16,7 @@ import Cookies from 'js-cookie' import { useSearchParams } from 'next/navigation' export default function Login() { - //////////////////////////////////////////////////////////////////////////////// - // 자동 로그인 작업진행중 + // 자동 로그인 const initParams = useSearchParams() const autoLoginParam = initParams.get('autoLoginParam1') useEffect(() => { @@ -26,45 +25,27 @@ export default function Login() { } }, []) const autoLoginProcess = async (autoLoginParam) => { - setSession({ - userId: autoLoginParam, - saleStoreId: null, - name: null, - mail: null, - tel: null, - storeId: 'TEMP02', - userNm: 'ㅇㅇ6610', - userNmKana: '신규사용자 16610', - category: '인상6610', - telNo: '336610', - fax: null, - email: 't10t@naver.com', - pwdInitYn: 'Y', - storeLvl: '2', - groupId: '70000', - }) - - setSessionState({ - userId: autoLoginParam, - saleStoreId: null, - name: null, - mail: null, - tel: null, - storeId: 'TEMP02', - userNm: 'ㅇㅇ6610', - userNmKana: '신규사용자 16610', - category: '인상6610', - telNo: '336610', - fax: null, - email: 't10t@naver.com', - pwdInitYn: 'Y', - storeLvl: '2', - groupId: '70000', - }) - - router.push('/') + await promisePost({ url: '/api/login/v1.0/user/login/autoLoginDecryptData', data: { loginId: autoLoginParam } }) + .then((res) => { + if (res) { + if (res.data) { + post({ url: '/api/login/v1.0/user', data: { loginId: res.data } }).then((response) => { + if (response) { + const result = { ...response, storeLvl: response.groupId === '60000' ? '1' : '2', pwdInitYn: 'Y' } + setSession(result) + setSessionState(result) + router.push('/') + } else { + router.push('/login') + } + }) + } + } + }) + .catch((error) => { + router.push('/login') + }) } - //////////////////////////////////////////////////////////////////////////////// const [userId, setUserId] = useState('') const [checkId, setCheckId] = useState('') @@ -86,12 +67,14 @@ export default function Login() { const [passwordReset, setPasswordReset] = useState(1) - const { promisePost, promisePatch } = useAxios(globalLocaleState) + const { promisePost, promisePatch, post } = useAxios(globalLocaleState) // login process const loginProcess = async (e) => { e.preventDefault() const formData = new FormData(e.target) + + /////////////////////////////////////////////////////////// // 임시 로그인 처리 setSession({ userId: 'NEW016610', @@ -110,7 +93,6 @@ export default function Login() { storeLvl: '1', groupId: '60000', }) - setSessionState({ userId: 'NEW016610', saleStoreId: null, @@ -128,16 +110,14 @@ export default function Login() { storeLvl: '1', groupId: '60000', }) - - // ID SAVE 체크되어 있는 경우, 쿠키 저장 if (chkLoginId) { Cookies.set('chkLoginId', formData.get('id'), { expires: 7 }) } else { Cookies.remove('chkLoginId') } - router.push('/') // 임시 로그인 처리 끝 + /////////////////////////////////////////////////////////// // 로그인 처리 시작 - ** 상단 임시 로그인 추후 삭제 필요 ** // const param = { @@ -173,7 +153,6 @@ export default function Login() { loginId: checkId, email: checkEmail, } - await promisePatch({ url: '/api/login/v1.0/user/init-password', data: param, diff --git a/src/components/myInfo/UserInfoModal.jsx b/src/components/myInfo/UserInfoModal.jsx index 9f8b0721..7643913c 100644 --- a/src/components/myInfo/UserInfoModal.jsx +++ b/src/components/myInfo/UserInfoModal.jsx @@ -8,7 +8,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal const { getMessage } = useMessage() // api 조회 관련 - const { get, promisePatch } = useAxios() + const { get, promisePatch, promisePost } = useAxios() const [info, setInfo] = useState({ userId: '', name: '', @@ -25,6 +25,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal const [showPwd, setShowPwd] = useState(false) const [chkChgPwd, setChkChgPwd] = useState(false) const [chgPwd, setChgPwd] = useState('') + const pwdInput = useRef() const chgPwdInput = useRef() useEffect(() => { @@ -54,7 +55,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal const handleChangePassword = async () => { if (chgPwd === '') { chgPwdInput.current.focus() - return alert(getMessage('myinfo.message.validation.password1')) + return alert(getMessage('myinfo.message.validation.password4')) } if (password === chgPwd) { chgPwdInput.current.focus() @@ -73,6 +74,8 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal if (res.data.result.resultCode === 'S') { alert(getMessage('myinfo.message.save')) setChkChgPwd(false) + setPassword(chgPwd) + setChgPwd('') } else { alert(res.data.result.resultMsg) } @@ -83,6 +86,40 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal }) } + // 비밀번호 변경 버튼 클릭 시, + const checkPasswordProcess = async (e) => { + if (password === '') { + pwdInput.current.focus() + return alert(getMessage('myinfo.message.validation.password1')) + } + + const param = { + loginId: userId, + pwd: password, + } + await promisePost({ url: '/api/login/v1.0/login', data: param }) + .then((res) => { + if (res) { + if (res.data.result.resultCode === 'S') { + setChkChgPwd(true) + setTimeout(() => { + chgPwdInput.current.focus() + }, 10) + } else { + alert(getMessage('myinfo.message.password.error')) + setChkChgPwd(false) + setChgPwd('') + setTimeout(() => { + pwdInput.current.focus() + }, 10) + } + } + }) + .catch((error) => { + alert(error.response.data.message) + }) + } + return ( <>
@@ -141,6 +178,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal { setPassword(e.target.value) }} @@ -151,11 +189,8 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
- - - + + + +
) -} +}) + +export default TriangleDormer diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx index d2c3022a..e667667e 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -4,17 +4,29 @@ import { useEffect, useState, useRef } from 'react' import Image from 'next/image' import PlacementSurface from '@/components/floor-plan/modal/placementSurface/PlacementSurface' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' +import { useRecoilValue } from 'recoil' +import { canvasState } from '@/store/canvasAtom' +import { POLYGON_TYPE } from '@/common/common' export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSettingModal }) { const { getMessage } = useMessage() - const [selectedType, setSelectedType] = useState() const [rotate, setRotate] = useState(0) const [xInversion, setXInversion] = useState(false) const [yInversion, setYInversion] = useState(false) + const canvas = useRecoilValue(canvasState) const { applySurfaceShape } = useSurfaceShapeBatch() + const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + + //오브젝트 배치에서 넘어오면 면형상 선택 가능 + useEffect(() => { + surfaceShapePolygons.forEach((obj) => { + obj.set({ selectable: true }) + }) + }, []) + const surfaceRefs = { length1: useRef(null), length2: useRef(null), diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index 33b393b8..7229f470 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -4,9 +4,18 @@ import { useRecoilState, useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { INPUT_TYPE, BATCH_TYPE } from '@/common/common' import { useEvent } from '@/hooks/useEvent' -import { polygonToTurfPolygon, rectToPolygon, pointsToTurfPolygon } from '@/util/canvas-util' +import { + polygonToTurfPolygon, + rectToPolygon, + triangleToPolygon, + pointsToTurfPolygon, + splitDormerTriangle, + setSurfaceShapePattern, +} from '@/util/canvas-util' import { useSwal } from '@/hooks/useSwal' import * as turf from '@turf/turf' +import { QPolygon } from '@/components/fabric/QPolygon' +import { drawDirectionArrow } from '@/util/qpolygon-utils' export function useObjectBatch() { const { getMessage } = useMessage() @@ -14,11 +23,11 @@ export function useObjectBatch() { const { addCanvasMouseEventListener, initEvent } = useEvent() const { swalFire } = useSwal() - const applyOpeningAndShadow = (objectPlacement, buttonAct, surfaceShapePolygons, setShowObjectSettingModal) => { + const applyOpeningAndShadow = (objectPlacement, buttonAct, surfaceShapePolygons) => { const selectedType = objectPlacement.typeRef.current.find((radio) => radio.checked).value const isCrossChecked = buttonAct === 1 ? objectPlacement.isCrossRef.current.checked : false - const objTempName = buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP const objName = buttonAct === 1 ? BATCH_TYPE.OPENING : BATCH_TYPE.SHADOW + const objTempName = buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP let rect, isDown, origX, origY let selectedSurface @@ -94,7 +103,7 @@ export function useObjectBatch() { if (!turf.booleanWithin(rectPolygon, selectedSurfacePolygon)) { swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' }) //일단 지워 - deleteTempObjects(setShowObjectSettingModal) + deleteTempObjects() return } @@ -105,7 +114,7 @@ export function useObjectBatch() { if (isCross) { swalFire({ text: '겹치기 불가요...', icon: 'error' }) - deleteTempObjects(setShowObjectSettingModal) + deleteTempObjects() return } } @@ -173,7 +182,7 @@ export function useObjectBatch() { if (!turf.booleanWithin(rectPolygon, selectedSurfacePolygon)) { swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' }) //일단 지워 - deleteTempObjects(setShowObjectSettingModal) + deleteTempObjects() return } @@ -184,7 +193,7 @@ export function useObjectBatch() { if (isCross) { swalFire({ text: '겹치기 불가요...', icon: 'error' }) - deleteTempObjects(setShowObjectSettingModal) + deleteTempObjects() return } } @@ -198,13 +207,209 @@ export function useObjectBatch() { } } - const deleteTempObjects = (setShowObjectSettingModal) => { - const deleteTarget = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING_TEMP || obj.name === BATCH_TYPE.SHADOW_TEMP) + const applyDormers = (dormerPlacement, buttonAct, surfaceShapePolygons) => { + const dormerName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER : BATCH_TYPE.PENTAGON_DORMER + const dormerTempName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER_TEMP : BATCH_TYPE.PENTAGON_DORMER_TEMP + const height = dormerPlacement.heightRef.current.value / 10 + const pitch = dormerPlacement.pitchRef.current.value + const directionRef = dormerPlacement.directionRef.current + const offsetRef = dormerPlacement.offsetRef.current.value === '' ? 0 : parseInt(dormerPlacement.offsetRef.current.value) / 10 + + let dormer, dormerOffset, isDown, selectedSurface + + console.log('dormerPlacement', dormerPlacement) + + if (height === '' || pitch === '' || height <= 0 || pitch <= 0) { + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) + return + } + + //삼각형 도머 + if (buttonAct === 3) { + const bottomLength = height / (pitch * 0.25) + const bottomOffsetLength = (height + offsetRef) / (pitch * 0.25) + + console.log(bottomOffsetLength) + + addCanvasMouseEventListener('mouse:move', (e) => { + isDown = true + if (!isDown) return + + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === dormerTempName)) //움직일때 일단 지워가면서 움직임 + const pointer = canvas.getPointer(e.e) + + surfaceShapePolygons.forEach((surface) => { + if (surface.inPolygon({ x: pointer.x, y: pointer.y })) { + selectedSurface = surface + } + }) + + let angle = 0 + if (directionRef === 'left') { + //서 + angle = 90 + } else if (directionRef === 'right') { + //동 + angle = 270 + } else if (directionRef === 'up') { + //북 + angle = 180 + } + + dormer = new fabric.Triangle({ + fill: 'white', + stroke: 'red', + strokeDashArray: [5, 5], + strokeWidth: 1, + width: bottomLength * 2, + height: height, + left: pointer.x, + top: pointer.y, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: dormerTempName, + originX: 'center', + originY: 'top', + angle: angle, + }) + canvas?.add(dormer) + + if (offsetRef > 0) { + dormerOffset = new fabric.Triangle({ + fill: 'gray', + stroke: 'red', + strokeDashArray: [5, 5], + strokeWidth: 1, + width: bottomOffsetLength * 2, + height: height + offsetRef, + left: pointer.x, + top: pointer.y, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: dormerTempName, + originX: 'center', + originY: 'top', + angle: angle, + }) + canvas?.add(dormerOffset) + } + }) + + addCanvasMouseEventListener('mouse:up', (e) => { + if (dormer) { + // const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer)) + // const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface) + + // //지붕 밖으로 그렸을때 + // if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) { + // swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' }) + // //일단 지워 + // deleteTempObjects() + // return + // } + + //각도 추가 + let originAngle = 0 //기본 남쪽 + let direction = 'south' + + if (directionRef === 'left') { + //서 + originAngle = 90 + direction = 'west' + } else if (directionRef === 'right') { + //동 + originAngle = 270 + direction = 'east' + } else if (directionRef === 'up') { + //북 + originAngle = 180 + direction = 'north' + } + + let splitedTriangle = offsetRef > 0 ? splitDormerTriangle(dormerOffset, directionRef) : splitDormerTriangle(dormer, directionRef) + canvas?.remove(offsetRef > 0 ? dormerOffset : dormer) + + if (offsetRef > 0) + dormer.set({ + name: dormerName, + stroke: 'black', + strokeWidth: 1, + strokeDashArray: [0], + }) //오프셋이 있을땐 같이 도머로 만든다 + + const leftTriangle = new QPolygon(splitedTriangle[0], { + fill: 'transparent', + stroke: 'black', + strokeWidth: 1, + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + viewLengthText: true, + fontSize: 14, + direction: direction, + originX: 'center', + originY: 'center', + name: dormerName, + }) + + const rightTriangle = new QPolygon(splitedTriangle[1], { + fill: 'transparent', + stroke: 'black', + strokeWidth: 1, + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + viewLengthText: true, + fontSize: 14, + direction: direction, + originX: 'center', + originY: 'center', + name: dormerName, + }) + + canvas?.add(leftTriangle) + canvas?.add(rightTriangle) + + //패턴 + setSurfaceShapePattern(leftTriangle) + setSurfaceShapePattern(rightTriangle) + //방향 + drawDirectionArrow(leftTriangle) + drawDirectionArrow(rightTriangle) + + isDown = false + initEvent() + } + }) + } + } + + const deleteTempObjects = () => { + const deleteTarget = canvas + ?.getObjects() + .filter( + (obj) => + obj.name === BATCH_TYPE.OPENING_TEMP || + obj.name === BATCH_TYPE.SHADOW_TEMP || + obj.name === BATCH_TYPE.TRIANGLE_DORMER_TEMP || + obj.name === BATCH_TYPE.PENTAGON_DORMER_TEMP, + ) canvas?.remove(...deleteTarget) initEvent() //이벤트 초기화 } return { applyOpeningAndShadow, + applyDormers, } } diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index bcffeba4..7eb421cc 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -2,11 +2,10 @@ import { useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' -import { MENU, BATCH_TYPE } from '@/common/common' +import { MENU, BATCH_TYPE, POLYGON_TYPE } from '@/common/common' import { getIntersectionPoint, setSurfaceShapePattern } from '@/util/canvas-util' import { degreesToRadians } from '@turf/turf' import { QPolygon } from '@/components/fabric/QPolygon' -import { fabric } from 'fabric' import { useSwal } from '@/hooks/useSwal' import { useMessage } from '@/hooks/useMessage' import { useEvent } from '@/hooks/useEvent' @@ -116,7 +115,7 @@ export function useSurfaceShapeBatch() { addCanvasMouseEventListener('mouse:down', (e) => { isDrawing = false - obj.set('name', MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH) + obj.set('name', POLYGON_TYPE.ROOF) initEvent() setSurfaceShapePattern(obj) setShowPlacementSurfaceSettingModal(true) @@ -567,19 +566,25 @@ export function useSurfaceShapeBatch() { const deleteAllSurfacesAndObjects = () => { swalFire({ - text: '삭제 ㄱㄱ?', + text: '배치면 내용을 전부 삭제하시겠습니까?', type: 'confirm', confirmFn: () => { canvas?.getObjects().forEach((obj) => { - if (obj.name === MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH || obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.SHADOW) { + if ( + obj.name === POLYGON_TYPE.ROOF || + obj.name === BATCH_TYPE.OPENING || + obj.name === BATCH_TYPE.SHADOW || + obj.name === BATCH_TYPE.TRIANGLE_DORMER || + obj.name === BATCH_TYPE.PENTAGON_DORMER + ) { canvas?.remove(obj) } }) swalFire({ text: '삭제 완료 되었습니다.' }) }, - denyFn: () => { - swalFire({ text: '취소되었습니다.' }) - }, + // denyFn: () => { + // swalFire({ text: '취소되었습니다.', icon: 'error' }) + // }, }) } diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js index 6b232b95..17c30f07 100644 --- a/src/util/canvas-util.js +++ b/src/util/canvas-util.js @@ -744,6 +744,79 @@ export const polygonToTurfPolygon = (polygon) => { ) } +export const splitDormerTriangle = (triangle, direction) => { + const halfWidth = triangle.width / 2 + + let leftPoints = [] + let rightPoints = [] + let leftPointOffset = [] + let rightPointOffset = [] + + if (direction === 'down') { + leftPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left - halfWidth, y: triangle.top + triangle.height }, + { x: triangle.left, y: triangle.top + triangle.height }, + ] + + rightPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left, y: triangle.top + triangle.height }, + { x: triangle.left + halfWidth, y: triangle.top + triangle.height }, + ] + } else if (direction === 'up') { + leftPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left - halfWidth, y: triangle.top - triangle.height }, + { x: triangle.left, y: triangle.top - triangle.height }, + ] + + rightPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left, y: triangle.top - triangle.height }, + { x: triangle.left + halfWidth, y: triangle.top - triangle.height }, + ] + } else if (direction === 'left') { + leftPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left - triangle.height, y: triangle.top - halfWidth }, + { x: triangle.left - triangle.height, y: triangle.top }, + ] + + rightPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left - triangle.height, y: triangle.top }, + { x: triangle.left - triangle.height, y: triangle.top + halfWidth }, + ] + } else if (direction === 'right') { + leftPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top + triangle.height }, + ] + + rightPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top - triangle.height }, + ] + } + + return [leftPoints, rightPoints] +} + +export const triangleToPolygon = (triangle) => { + const points = [] + const halfWidth = triangle.width / 2 + const height = triangle.height + + points.push({ x: triangle.left + halfWidth, y: triangle.top }) + points.push({ x: triangle.left, y: triangle.top + height }) + points.push({ x: triangle.left + triangle.width, y: triangle.top + height }) + + return points +} + export const rectToPolygon = (rect) => { const points = [] const left = rect.left From 07e11f3148fa52883aeac0b34def2c45e49c15e3 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 17 Oct 2024 10:50:23 +0900 Subject: [PATCH 6/9] =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index d1e4a864..f165bde0 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -4,7 +4,6 @@ import PowerConditionalSelect from '@/components/floor-plan/modal/circuitTrestle import CircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation' import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp' import { useMessage } from '@/hooks/useMessage' -import WithDraggable from '@/components/common/draggable/withDraggable' export default function CircuitTrestleSetting({ setShowCircuitTrestleSettingModal }) { const { getMessage } = useMessage() From 63b500e0c0a5469c3ee3bb7cae899d1aefb13f60 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 17 Oct 2024 13:18:50 +0900 Subject: [PATCH 7/9] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=ED=98=84=ED=99=A9=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/Stuff.jsx | 165 ++++++++---------- .../management/StuffSearchCondition.jsx | 2 +- 2 files changed, 78 insertions(+), 89 deletions(-) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 9a0a73c5..cedf1975 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -15,6 +15,7 @@ import { convertNumberToPriceDecimal } from '@/util/common-utils' import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' import KO from '@/locales/ko.json' import JA from '@/locales/ja.json' +import QPagination from '../common/pagination/QPagination' import '@/styles/grid.scss' import { sessionStore } from '@/store/commonAtom' @@ -24,9 +25,9 @@ export default function Stuff() { const stuffSearchParams = useRecoilValue(stuffSearchState) const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) const { getMessage } = useMessage() - const [curPage, setCurPage] = useState(1) //현재 페이지 번호 - const [defaultSize, setDefaultSize] = useState(100) //페이지 당 게시물 수 - const [gridCount, setGridCount] = useState(0) //총 갯수 + const [pageNo, setPageNo] = useState(1) //현재 페이지 번호 + const [pageSize, setPageSize] = useState(100) //페이지 당 게시물 수 + const [totalCount, setTotalCount] = useState(0) //총 갯수 const [defaultSortType, setDefaultSortType] = useState('R') const globalLocaleState = useRecoilValue(globalLocaleStore) @@ -62,10 +63,6 @@ export default function Stuff() { const [gridProps, setGridProps] = useState({ gridData: [], isPageable: false, - // sets 10 rows per page (default is 100) - // paginationPageSize: 100, - // allows the user to select the page size from a predefined list of page sizes - // paginationPageSizeSelector: [100, 200, 300, 400], gridColumns: [ { field: 'lastEditDatetime', @@ -228,56 +225,42 @@ export default function Stuff() { // 진입시 그리드 데이터 조회 useEffect(() => { if (isObjectNotEmpty(sessionState)) { + //물건 메뉴 눌러서 최초 진입 sessionState if (stuffSearchParams?.code === 'S') { const params = { - schObjectNo: '', - schAddress: '', - schObjectName: '', - schSaleStoreName: '', - schReceiveUser: '', - schDispCompanyName: '', - schDateType: 'U', + schObjectNo: stuffSearchParams?.schObjectNo, + schAddress: stuffSearchParams?.schAddress, + schObjectName: stuffSearchParams?.schObjectName, + schSaleStoreName: stuffSearchParams?.schSaleStoreName, + schReceiveUser: stuffSearchParams?.schReceiveUser, + schDispCompanyName: stuffSearchParams?.schDispCompanyName, + schDateType: stuffSearchParams.schDateType, 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, + startRow: (pageNo - 1) * pageSize + 1, + endRow: pageNo * pageSize, schSelSaleStoreId: '', - schSortType: 'R', + schSortType: stuffSearchParams.schSortType, } 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)}` + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}` + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(params)}` await get({ url: apiUrl, }).then((res) => { if (!isEmptyArray(res)) { setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) - setGridCount(res[0].totCnt) + setTotalCount(res[0].totCnt) } }) } fetchData() } else { + //메인화면에서 진입 const params = { - schObjectNo: '', + schObjectNo: stuffSearchParams.schObjectNo, schAddress: '', schObjectName: '', schSaleStoreName: '', @@ -286,30 +269,13 @@ export default function Stuff() { 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, + startRow: (pageNo - 1) * pageSize + 1, + endRow: pageNo * pageSize, 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({ @@ -317,34 +283,36 @@ export default function Stuff() { }).then((res) => { if (!isEmptyArray(res)) { setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) - setGridCount(res[0].totCnt) + setTotalCount(res[0].totCnt) } }) } fetchData() } } - }, [sessionState]) + }, [pageNo, sessionState]) useEffect(() => { if (stuffSearchParams?.code === 'E') { - //console.log('조회누름::::::::', stuffSearchParams) - stuffSearchParams.startRow = (curPage - 1) * defaultSize + 1 - stuffSearchParams.endRow = curPage * defaultSize + //console.log('조회누름::::::::', stuffSearchParams, sessionState) + // stuffSearchParams.startRow = (pageNo - 1) * pageSize + 1 + // stuffSearchParams.endRow = pageNo * pageSize + stuffSearchParams.startRow = 1 + stuffSearchParams.endRow = 1 * pageSize stuffSearchParams.schSortType = defaultSortType + + setPageNo(1) + async function fetchData() { - // console.log('조회누름 세션정보:::::::::::::', sessionState) - // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` await get({ url: apiUrl }).then((res) => { - // console.log('검색조건 변경 조회 API결과:::::::', res) if (!isEmptyArray(res)) { setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) - setGridCount(res[0].totCnt) + setTotalCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) - setGridCount(0) + setTotalCount(0) } }) } @@ -354,53 +322,58 @@ export default function Stuff() { //페이지 갯수 변경 이벤트 const onChangePerPage = (e) => { - let startRow = (curPage - 1) * e.target.value + 1 + let startRow = (1 - 1) * e.target.value + 1 stuffSearchParams.startRow = startRow - stuffSearchParams.endRow = curPage * e.target.value - setDefaultSize(e.target.value) + stuffSearchParams.endRow = 1 * e.target.value + setPageSize(e.target.value) setStuffSearch({ ...stuffSearch, code: 'S', startRow: startRow, - endRow: curPage * e.target.value, + endRow: 1 * e.target.value, }) - // console.log('페이지 갯수 변경 때 셋팅된 검색조건:::', stuffSearchParams) - // console.log('페이지 갯수 변경 때 sessionState:::', sessionState) - // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` + + setPageNo(1) + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}` get({ url: apiUrl }).then((res) => { if (!isEmptyArray(res)) { setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) - setGridCount(res[0].totCnt) + setTotalCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) - setGridCount(0) + setTotalCount(0) } }) } //최근 등록일 수정일 정렬 이벤트 const onChangeSortType = (e) => { + let startRow = (1 - 1) * pageSize + 1 + stuffSearchParams.startRow = startRow + stuffSearchParams.endRow = 1 * pageSize + stuffSearchParams.schSortType = e.target.value - // console.log('셋팅된 검색조건:::', stuffSearchParams) setDefaultSortType(e.target.value) setStuffSearch({ ...stuffSearch, code: 'S', + startRow: startRow, + endRow: 1 * pageSize, schSortType: e.target.value, }) - // console.log('정렬 변경시 세션정보::::::::::::', sessionState) - // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` + + setPageNo(1) + + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` get({ url: apiUrl }).then((res) => { if (!isEmptyArray(res)) { setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) - setGridCount(res[0].totCnt) + setTotalCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) - setGridCount(0) + setTotalCount(0) } }) } @@ -413,6 +386,20 @@ export default function Stuff() { } }, [globalLocaleState]) + // 페이징 현재페이지 변경 + const handleChangePage = (page) => { + stuffSearchParams.code = 'S' + + setStuffSearch({ + ...stuffSearch, + code: 'S', + startRow: (page - 1) * pageSize + 1, + endRow: page * pageSize, + }) + + setPageNo(page) + } + return ( <> {/* 퍼블시작 */} @@ -423,7 +410,7 @@ export default function Stuff() {
  • 전체 - {convertNumberToPriceDecimal(gridCount)} + {convertNumberToPriceDecimal(totalCount)}
  • 선택 @@ -450,7 +437,9 @@ export default function Stuff() {
    -
    페이징 컴포넌트예정
    +
    + +
diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 8bd739b4..a8f86718 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -323,7 +323,7 @@ export default function StuffSearchCondition() { setStuffSearch({ ...stuffSearch, code: 'S', schDateType: e.target.value }) }} /> - +
From 429832b8b7a09e44dc7ee061114516bae083d82b Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 17 Oct 2024 13:34:11 +0900 Subject: [PATCH 8/9] refactor: Refactor usePagination hook to include useEffect --- src/hooks/usePagination.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hooks/usePagination.js b/src/hooks/usePagination.js index 4fc3a959..7d76d293 100644 --- a/src/hooks/usePagination.js +++ b/src/hooks/usePagination.js @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useEffect, useState } from 'react' /** * 페이지네이션 훅 @@ -14,6 +14,10 @@ const usePagination = ({ pageNo = 1, pageSize = 10, pagePerBlock = 10, totalCoun setCurrentPage(page) } + useEffect(() => { + setCurrentPage(pageNo) + }, [pageNo]) + const pageGroup = Math.floor((currentPage - 1) / pagePerBlock) + 1 const totalPages = Math.ceil(totalCount / pageSize) const pages = Array.from({ length: totalPages }, (_, i) => i + 1) From b57c6d47a9268aabe920e271a9f3fd355397b2e0 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 17 Oct 2024 13:42:55 +0900 Subject: [PATCH 9/9] refactor: Refactor useAxios hook in Settings component --- src/components/Settings.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Settings.jsx b/src/components/Settings.jsx index 43288dbe..51680711 100644 --- a/src/components/Settings.jsx +++ b/src/components/Settings.jsx @@ -3,7 +3,8 @@ import React, { useEffect, useState } from 'react' import { Button } from '@nextui-org/react' -import { get, post } from '@/lib/Axios' +import { useAxios } from '@/hooks/useAxios' + import { useRecoilState } from 'recoil' import { customSettingsState } from '@/store/canvasAtom' import { modalContent, modalState } from '@/store/modalAtom' @@ -20,6 +21,8 @@ export default function Settings() { const [open, setOpen] = useRecoilState(modalState) const [contents, setContent] = useRecoilState(modalContent) + const { get, post } = useAxios() + const handleSavePopup = () => { console.log('color ', color) }