From f9d1f8e2e047e53bfc802fbce29d7e8d80c9fe4c Mon Sep 17 00:00:00 2001 From: minsik Date: Wed, 11 Sep 2024 18:05:15 +0900 Subject: [PATCH 01/23] =?UTF-8?q?-=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20/=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_contents.scss | 1 + src/styles/_fonts.scss | 264 +++++++++++----------- src/styles/_layout.scss | 452 ++++++++++++++++++++------------------ src/styles/_main.scss | 0 src/styles/_modal.scss | 213 +++++++++++------- src/styles/style.scss | 4 +- 6 files changed, 511 insertions(+), 423 deletions(-) create mode 100644 src/styles/_main.scss diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss index 216df145..4513b133 100644 --- a/src/styles/_contents.scss +++ b/src/styles/_contents.scss @@ -3,6 +3,7 @@ height: calc(100vh - 47px); display: flex; flex-direction: column; + background-color: #fff; .canvas-content { flex: 1 1 auto; diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss index b1d16e89..856ee2f8 100644 --- a/src/styles/_fonts.scss +++ b/src/styles/_fonts.scss @@ -1,199 +1,199 @@ @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-ExtraBold.woff2') format('woff2'), - url('/fonts/NotoSansJP-ExtraBold.woff') format('woff'); - font-weight: bold; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-ExtraBold.woff2') format('woff2'), + url('/fonts/NotoSansJP-ExtraBold.woff') format('woff'); + font-weight: bold; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-Bold.woff2') format('woff2'), - url('/fonts/NotoSansJP-Bold.woff') format('woff'); - font-weight: bold; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-Bold.woff2') format('woff2'), + url('/fonts/NotoSansJP-Bold.woff') format('woff'); + font-weight: bold; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-Black.woff2') format('woff2'), - url('/fonts/NotoSansJP-Black.woff') format('woff'); - font-weight: 900; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-Black.woff2') format('woff2'), + url('/fonts/NotoSansJP-Black.woff') format('woff'); + font-weight: 900; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-ExtraLight.woff2') format('woff2'), - url('/fonts/NotoSansJP-ExtraLight.woff') format('woff'); - font-weight: 200; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-ExtraLight.woff2') format('woff2'), + url('/fonts/NotoSansJP-ExtraLight.woff') format('woff'); + font-weight: 200; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-Light.woff2') format('woff2'), - url('/fonts/NotoSansJP-Light.woff') format('woff'); - font-weight: 300; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-Light.woff2') format('woff2'), + url('/fonts/NotoSansJP-Light.woff') format('woff'); + font-weight: 300; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-Medium.woff2') format('woff2'), - url('/fonts/NotoSansJP-Medium.woff') format('woff'); - font-weight: 500; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-Medium.woff2') format('woff2'), + url('/fonts/NotoSansJP-Medium.woff') format('woff'); + font-weight: 500; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2'), - url('/fonts/NotoSansJP-Regular.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2'), + url('/fonts/NotoSansJP-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-SemiBold.woff2') format('woff2'), - url('/fonts/NotoSansJP-SemiBold.woff') format('woff'); - font-weight: 600; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-SemiBold.woff2') format('woff2'), + url('/fonts/NotoSansJP-SemiBold.woff') format('woff'); + font-weight: 600; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Noto Sans JP'; - src: url('/fonts/NotoSansJP-Thin.woff2') format('woff2'), - url('/fonts/NotoSansJP-Thin.woff') format('woff'); - font-weight: 100; - font-style: normal; - font-display: swap; + font-family: 'Noto Sans JP'; + src: url('/fonts/NotoSansJP-Thin.woff2') format('woff2'), + url('/fonts/NotoSansJP-Thin.woff') format('woff'); + font-weight: 100; + font-style: normal; + font-display: swap; } // pretendard @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Bold.woff2') format('woff2'), - url('/fonts/Pretendard-Bold.woff') format('woff'); - font-weight: bold; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Bold.woff2') format('woff2'), + url('/fonts/Pretendard-Bold.woff') format('woff'); + font-weight: bold; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-ExtraBold.woff2') format('woff2'), - url('/fonts/Pretendard-ExtraBold.woff') format('woff'); - font-weight: bold; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-ExtraBold.woff2') format('woff2'), + url('/fonts/Pretendard-ExtraBold.woff') format('woff'); + font-weight: bold; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-ExtraBold.woff2') format('woff2'), - url('/fonts/Pretendard-ExtraBold.woff') format('woff'); - font-weight: bold; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-ExtraBold.woff2') format('woff2'), + url('/fonts/Pretendard-ExtraBold.woff') format('woff'); + font-weight: bold; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-ExtraLight.woff2') format('woff2'), - url('/fonts/Pretendard-ExtraLight.woff') format('woff'); - font-weight: 200; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-ExtraLight.woff2') format('woff2'), + url('/fonts/Pretendard-ExtraLight.woff') format('woff'); + font-weight: 200; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-ExtraLight.woff2') format('woff2'), - url('/fonts/Pretendard-ExtraLight.woff') format('woff'); - font-weight: 200; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-ExtraLight.woff2') format('woff2'), + url('/fonts/Pretendard-ExtraLight.woff') format('woff'); + font-weight: 200; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Light.woff2') format('woff2'), - url('/fonts/Pretendard-Light.woff') format('woff'); - font-weight: 300; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Light.woff2') format('woff2'), + url('/fonts/Pretendard-Light.woff') format('woff'); + font-weight: 300; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Light.woff2') format('woff2'), - url('/fonts/Pretendard-Light.woff') format('woff'); - font-weight: 300; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Light.woff2') format('woff2'), + url('/fonts/Pretendard-Light.woff') format('woff'); + font-weight: 300; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Medium.woff2') format('woff2'), - url('/fonts/Pretendard-Medium.woff') format('woff'); - font-weight: 500; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Medium.woff2') format('woff2'), + url('/fonts/Pretendard-Medium.woff') format('woff'); + font-weight: 500; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Medium.woff2') format('woff2'), - url('/fonts/Pretendard-Medium.woff') format('woff'); - font-weight: 500; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Medium.woff2') format('woff2'), + url('/fonts/Pretendard-Medium.woff') format('woff'); + font-weight: 500; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Regular.woff2') format('woff2'), - url('/fonts/Pretendard-Regular.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Regular.woff2') format('woff2'), + url('/fonts/Pretendard-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Black.woff2') format('woff2'), - url('/fonts/Pretendard-Black.woff') format('woff'); - font-weight: 900; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Black.woff2') format('woff2'), + url('/fonts/Pretendard-Black.woff') format('woff'); + font-weight: 900; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Black.woff2') format('woff2'), - url('/fonts/Pretendard-Black.woff') format('woff'); - font-weight: 900; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Black.woff2') format('woff2'), + url('/fonts/Pretendard-Black.woff') format('woff'); + font-weight: 900; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Pretendard'; - src: url('/fonts/Pretendard-Bold.woff2') format('woff2'), - url('/fonts/Pretendard-Bold.woff') format('woff'); - font-weight: bold; - font-style: normal; - font-display: swap; + font-family: 'Pretendard'; + src: url('/fonts/Pretendard-Bold.woff2') format('woff2'), + url('/fonts/Pretendard-Bold.woff') format('woff'); + font-weight: bold; + font-style: normal; + font-display: swap; } diff --git a/src/styles/_layout.scss b/src/styles/_layout.scss index e33d75ea..919e80ff 100644 --- a/src/styles/_layout.scss +++ b/src/styles/_layout.scss @@ -1,216 +1,250 @@ -.wrap{ - display: flex; - flex-direction: column; - min-width: 1600px; - min-height: 100vh; - overflow-x: hidden; +.wrap { + display: flex; + flex-direction: column; + min-width: 1600px; + min-height: 100vh; + overflow-x: hidden; } -.content{ - flex: 1 1 auto; - padding-top: 46px; + +.content { + position: relative; + flex: 1 1 auto; + padding-top: 46px; + background-color: #F4F4F7; } // header // nav item 공통 -@mixin navitem(){ - position: relative; - display: flex; - align-items: center; - font-size: 14px; - color: #fff; - font-weight: 500; - height: 100%; - padding-right: 12px; - transition: color .17s ease-in-out; -} -header{ - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 1600px; - height: 46px; - background-color: #1C1C1C; - border-bottom: 1px solid #000; - z-index: 9999; - .header-inner{ - display: flex; - align-items: center; - height: 100%; - padding: 0 40px; - .header-right{ - display: flex; - height: 100%; - align-items: center; - .logo{ - a{ - display: block; - width: 232px; - height: 30px; - background: url(/static/images/common/Logo.svg)no-repeat center; - background-size: contain; - } - } - nav{ - margin-left: 50px; - height: 100%; - .nav-list{ - display: flex; - align-items: center; - height: 100%; - .nav-item{ - position: relative; - margin-right: 62px; - height: 100%; - a{ - @include navitem; - } - button{ - @include navitem; - &:after{ - content: ''; - position: absolute; - top: 50%; - right: 0; - transform: translateY(-50%); - width: 6px; - height: 10px; - background: url(/static/images/common/nav-arr.svg)no-repeat center; - transition: all .17s ease-in-out; - } - } - &:last-child{ - margin-right: 0; - } - .nav-depth2{ - position: absolute; - top: calc(100% - 2px); - left: 50%; - transform: translateX(-50%); - min-width: 100px; - background-color: #1C1C1C; - border: 1px solid #464646; - padding: 24px; - opacity: 0; - visibility: hidden; - transition: all .17s ease-in-out; - .nav-depth2-item{ - margin-bottom: 10px; - transition: all .17s ease-in-out; - a{ - font-size: 13px; - font-weight: normal; - white-space: nowrap; - } - &:last-child{ - margin-bottom: 0; - } - &.mouse{ - opacity: 0.55; - } - } - &::before{ - content: ''; - position: absolute; - top: -5px; - left: 50%; - transform: translateX(-50%) rotate(45deg); - width: 8px; - height: 8px; - background-color: #1c1c1c; - border-top: 1px solid #464646; - border-left: 1px solid #464646; - } - } - &.mouse{ - > a{ - color: rgba(255, 255, 255, 0.30); - } - > button{ - color: rgba(255, 255, 255, 0.30); - &:after{ - opacity: 0.3; - } - } - } - &:hover{ - .nav-depth2{ - opacity: 1; - visibility: visible; - } - > button{ - &:after{ - transform: translateY(-50%) rotate(90deg); - } - } - } - } - } - } - } - .header-left{ - margin-left: auto; - height: 100%; - display: flex; - align-items: center; - .profile-box{ - position: relative; - padding-left: 30px; - height: 100%; - display: flex; - align-items: center; - margin-right: 20px; - cursor: pointer; - .profile{ - font-size: 13px; - font-weight: normal; - color: #fff; - } - &::after{ - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%); - left: 0; - width: 24px; - height: 24px; - background: url(/static/images/common/profile_icon.svg)no-repeat center; - background-size: cover; - } - } - .sign-out-box{ - position: relative; - padding-left: 30px; - height: 100%; - display: flex; - align-items: center; - margin-right: 20px; - cursor: pointer; - .sign-out{ - font-size: 13px; - font-weight: normal; - color: #fff; - } - &::after{ - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%); - left: 0; - width: 24px; - height: 24px; - background: url(../../public/static/images/common/signout_icon.svg)no-repeat center; - background-size: cover; - } - } - .select-box{ - min-width: 165px; - margin-right: 8px; - >div{ - width: 100%; - } - } - } - } +@mixin navitem() { + position: relative; + display: flex; + align-items: center; + font-size: 14px; + color: #fff; + font-weight: 500; + height: 100%; + padding-right: 12px; + transition: color .17s ease-in-out; +} + +header { + position: fixed; + top: 0; + left: 0; + width: 100%; + min-width: 1600px; + height: 46px; + background-color: #1C1C1C; + border-bottom: 1px solid #000; + z-index: 9999; + + .header-inner { + display: flex; + align-items: center; + height: 100%; + padding: 0 40px; + + .header-right { + display: flex; + height: 100%; + align-items: center; + + .logo { + a { + display: block; + width: 232px; + height: 30px; + background: url(/static/images/common/Logo.svg) no-repeat center; + background-size: contain; + } + } + + nav { + margin-left: 50px; + height: 100%; + + .nav-list { + display: flex; + align-items: center; + height: 100%; + + .nav-item { + position: relative; + margin-right: 62px; + height: 100%; + + a { + @include navitem; + } + + button { + @include navitem; + + &:after { + content: ''; + position: absolute; + top: 50%; + right: 0; + transform: translateY(-50%); + width: 6px; + height: 10px; + background: url(/static/images/common/nav-arr.svg) no-repeat center; + transition: all .17s ease-in-out; + } + } + + &:last-child { + margin-right: 0; + } + + .nav-depth2 { + position: absolute; + top: calc(100% - 2px); + left: 50%; + transform: translateX(-50%); + min-width: 100px; + background-color: #1C1C1C; + border: 1px solid #464646; + padding: 24px; + opacity: 0; + visibility: hidden; + transition: all .17s ease-in-out; + + .nav-depth2-item { + margin-bottom: 10px; + transition: all .17s ease-in-out; + + a { + font-size: 13px; + font-weight: normal; + white-space: nowrap; + } + + &:last-child { + margin-bottom: 0; + } + + &.mouse { + opacity: 0.55; + } + } + + &::before { + content: ''; + position: absolute; + top: -5px; + left: 50%; + transform: translateX(-50%) rotate(45deg); + width: 8px; + height: 8px; + background-color: #1c1c1c; + border-top: 1px solid #464646; + border-left: 1px solid #464646; + } + } + + &.mouse { + > a { + color: rgba(255, 255, 255, 0.30); + } + + > button { + color: rgba(255, 255, 255, 0.30); + + &:after { + opacity: 0.3; + } + } + } + + &:hover { + .nav-depth2 { + opacity: 1; + visibility: visible; + } + + > button { + &:after { + transform: translateY(-50%) rotate(90deg); + } + } + } + } + } + } + } + + .header-left { + margin-left: auto; + height: 100%; + display: flex; + align-items: center; + + .profile-box { + position: relative; + padding-left: 30px; + height: 100%; + display: flex; + align-items: center; + margin-right: 20px; + cursor: pointer; + + .profile { + font-size: 13px; + font-weight: normal; + color: #fff; + } + + &::after { + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 0; + width: 24px; + height: 24px; + background: url(/static/images/common/profile_icon.svg) no-repeat center; + background-size: cover; + } + } + + .sign-out-box { + position: relative; + padding-left: 30px; + height: 100%; + display: flex; + align-items: center; + margin-right: 20px; + cursor: pointer; + + .sign-out { + font-size: 13px; + font-weight: normal; + color: #fff; + } + + &::after { + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 0; + width: 24px; + height: 24px; + background: url(../../public/static/images/common/signout_icon.svg) no-repeat center; + background-size: cover; + } + } + + .select-box { + min-width: 165px; + margin-right: 8px; + + > div { + width: 100%; + } + } + } + } } diff --git a/src/styles/_main.scss b/src/styles/_main.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index 05b0e4a9..c57e5968 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -1,91 +1,146 @@ -@keyframes mountpop{ - from{opacity: 0; scale: 0.95;} - to{opacity: 1; scale: 1;} -} -@keyframes unmountpop{ - from{opacity: 1; scale: 1;} - to{opacity: 0; scale: 0.95;} +@keyframes mountpop { + from { + opacity: 0; + scale: 0.95; + } + to { + opacity: 1; + scale: 1; + } } -.modal-pop-wrap{ - position: fixed; - top: 200px; - right: 100px; - width: 100%; - min-width: 380px; - max-width: fit-content; - height: -webkit-fit-content; - height: -moz-fit-content; - height: fit-content; - border: 1px solid #000; - border-radius: 4px; - background-color: #272727; - z-index: 9999999; - &.sm{ - max-width: 450px; - } - &.mount{ - animation: mountpop .17s ease-in-out forwards; - } - &.unmount{ - animation: unmountpop .17s ease-in-out forwards; - } +@keyframes unmountpop { + from { + opacity: 1; + scale: 1; + } + to { + opacity: 0; + scale: 0.95; + } } -.modal-head{ + +.modal-pop-wrap { + position: fixed; + top: 200px; + right: 100px; + width: 100%; + min-width: 380px; + max-width: fit-content; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + border: 1px solid #000; + border-radius: 4px; + background-color: #272727; + z-index: 9999999; + + &.sm { + max-width: 450px; + } + + &.ssm { + max-width: 380px; + } + + &.mount { + animation: mountpop .17s ease-in-out forwards; + } + + &.unmount { + animation: unmountpop .17s ease-in-out forwards; + } +} + +.modal-head { + display: flex; + align-items: center; + padding: 10px 24px; + background-color: #000; + cursor: pointer; + + h1.title { + font-size: 13px; + color: #fff; + font-weight: 700; + } + + .modal-close { + margin-left: auto; + color: #fff; + text-indent: -999999999px; + width: 10px; + height: 10px; + background: url(../../public/static/images/canvas/modal_close.svg) no-repeat center; + } +} + +.modal-body { + padding: 15px; + + .modal-btn-wrap { display: flex; align-items: center; - padding: 10px 24px; - background-color: #000; - cursor: pointer; - h1.title{ - font-size: 13px; - color: #fff; - font-weight: 700; + gap: 5px; + + button { + flex: 1; } - .modal-close{ - margin-left: auto; - color: #fff; - text-indent: -999999999px; - width: 10px; - height: 10px; - background: url(../../public/static/images/canvas/modal_close.svg)no-repeat center; + } + + .modal-check-btn-wrap { + margin-top: 15px; + + .check-wrap-title { + font-size: 12px; + color: #fff; + font-weight: 600; + + &.light { + font-weight: 400; + } } -} -.modal-body{ - padding: 15px; - .modal-btn-wrap{ - display: flex; - align-items: center; - gap: 5px; - button{ - flex: 1; + + .flex-check-box { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 15px; + + &.for2 { + button { + width: calc(50% - 5px); } - } - .modal-check-btn-wrap{ - margin-top: 15px; - .check-wrap-title{ - font-size: 12px; - color: #fff; - font-weight: 600; - &.light{ - font-weight: 400; - } + + &.btn { + gap: 5px; + + button { + width: calc(50% - 2.5px); + } } - .flex-check-box{ - display: flex; - flex-wrap: wrap; - gap: 10px; - margin-top: 15px; - &.for2{ - button{ - width: calc(50% - 5px); - } - } - &.for-line{ - button{ - flex: 1; - } - } + } + + &.for-line { + button { + flex: 1; } + } } + } + + .outer-line-wrap { + border-top: 1px solid #3C3C3C; + margin-top: 10px; + padding-top: 15px; + margin-bottom: 15px; + + > div { + margin-bottom: 15px; + + &:last-child { + margin-bottom: 0; + } + } + } } \ No newline at end of file diff --git a/src/styles/style.scss b/src/styles/style.scss index 67e19244..1841ebb9 100644 --- a/src/styles/style.scss +++ b/src/styles/style.scss @@ -1,3 +1 @@ -@import '_layout.scss'; -@import '_contents.scss'; -@import '_modal.scss'; \ No newline at end of file +@import '_main.scss'; \ No newline at end of file From c74dec07a1f6d996ad36c60b48f4edd2b7ecd944 Mon Sep 17 00:00:00 2001 From: minsik Date: Wed, 11 Sep 2024 18:06:00 +0900 Subject: [PATCH 02/23] =?UTF-8?q?-=20=EC=99=B8=EB=B2=BD=EC=84=A0=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=ED=99=94=EB=A9=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20-=20Canvas=20=EC=84=A4=EC=A0=95=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.js | 3 +- src/components/floor-plan/FloorPlan.jsx | 13 +-- .../modal/outerlinesetting/OuterLineWall.jsx | 80 +++++++++++++++++++ .../{settoing01 => setting01}/FirstOption.jsx | 0 .../SecondOption.jsx | 14 ++-- .../SettingModal01.jsx | 2 +- src/locales/ja.json | 35 +++++--- src/locales/ko.json | 19 ++++- src/store/modalAtom.js | 14 +--- src/store/settingAtom.js | 16 ++-- 10 files changed, 152 insertions(+), 44 deletions(-) create mode 100644 src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx rename src/components/floor-plan/modal/{settoing01 => setting01}/FirstOption.jsx (100%) rename src/components/floor-plan/modal/{settoing01 => setting01}/SecondOption.jsx (68%) rename src/components/floor-plan/modal/{settoing01 => setting01}/SettingModal01.jsx (95%) diff --git a/src/app/layout.js b/src/app/layout.js index 90a46e6e..4d4a4f21 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -4,7 +4,6 @@ import RecoilRootWrapper from './RecoilWrapper' import UIProvider from './UIProvider' import { ToastContainer } from 'react-toastify' -import QModal from '@/components/common/modal/QModal' import './globals.css' import '../styles/style.scss' @@ -30,7 +29,7 @@ export default function RootLayout({ children }) { - + {/**/} diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index e7fe4225..1577227d 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -1,20 +1,23 @@ 'use client' import CanvasMenu from '@/components/floor-plan/CanvasMenu' -import SettingModal01 from '@/components/floor-plan/modal/settoing01/SettingModal01' -import { useState } from 'react' +import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01' import CanvasLayout from '@/components/floor-plan/CanvasLayout' import '@/styles/contents.scss' +import { modalState } from '@/store/modalAtom' +import { useRecoilValue } from 'recoil' +import OuterLineWall from '@/components/floor-plan/modal/outerlinesetting/OuterLineWall' export default function FloorPlan() { - const [modalOpen, setModalOpen] = useState('option') + const modalOption = useRecoilValue(modalState) return ( <>
- +
- {modalOpen === 'option' && } + {modalOption.option && } + {modalOption.outerwall && }
diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx new file mode 100644 index 00000000..1ba1c597 --- /dev/null +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -0,0 +1,80 @@ +'use client' + +import { useState } from 'react' +import WithDraggable from '@/components/common/draggable/withDraggable' +import { modalState } from '@/store/modalAtom' +import { useRecoilState } from 'recoil' +import { useMessage } from '@/hooks/useMessage' + +export default function OuterLineWall() { + const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state + const [buttonAct, setButtonAct] = useState(1) + const [close, setClose] = useState(false) + const { getMessage } = useMessage() + const HandleClickClose = () => { + setClose(true) + setTimeout(() => { + setModalOption({ ...modalOption, outerwall: false }) + setClose(false) + }, 180) + } + return ( + +
+
+

{getMessage('modal.cover.outline.drawing')}

+ +
+
+
+ + + + + + +
+
+

{getMessage('modal.cover.outline.setting')}

+
+
+ + +
+
+ + +
+
+
+ + + + +
+
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/settoing01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx similarity index 100% rename from src/components/floor-plan/modal/settoing01/FirstOption.jsx rename to src/components/floor-plan/modal/setting01/FirstOption.jsx diff --git a/src/components/floor-plan/modal/settoing01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx similarity index 68% rename from src/components/floor-plan/modal/settoing01/SecondOption.jsx rename to src/components/floor-plan/modal/setting01/SecondOption.jsx index 5b417f2b..499b316c 100644 --- a/src/components/floor-plan/modal/settoing01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -1,9 +1,11 @@ import { useRecoilState } from 'recoil' import { settingModalSecondOptionsState } from '@/store/settingAtom' +import { useMessage } from '@/hooks/useMessage' export default function SecondOption() { const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalSecondOptionsState) const { option1, option2 } = settingsModalOptions + const { getMessage } = useMessage() const onClickOption = (option) => { option.selected = !option.selected @@ -12,31 +14,31 @@ export default function SecondOption() { return ( <>
-

フォントとサイズの変更

+

{getMessage('modal.canvas.setting.font.plan.edit')}

{settingsModalOptions.option1.map((item) => ( ))}
-

吸着範囲の設定

+

{getMessage('modal.canvas.setting.font.plan.absorption')}

{settingsModalOptions.option2.map((item) => ( ))}
diff --git a/src/components/floor-plan/modal/settoing01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx similarity index 95% rename from src/components/floor-plan/modal/settoing01/SettingModal01.jsx rename to src/components/floor-plan/modal/setting01/SettingModal01.jsx index 6c9969d2..6350438d 100644 --- a/src/components/floor-plan/modal/settoing01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -3,7 +3,7 @@ import { useState } from 'react' import FirstOption from './FirstOption' import WithDraggable from '@/components/common/draggable/withDraggable' -import SecondOption from '@/components/floor-plan/modal/settoing01/SecondOption' +import SecondOption from '@/components/floor-plan/modal/setting01/SecondOption' import { useMessage } from '@/hooks/useMessage' export default function SettingModal01({ modalOpen, setModalOpen }) { diff --git a/src/locales/ja.json b/src/locales/ja.json index 50172c83..f4132734 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -16,17 +16,20 @@ "plan.menu.plan.drawing": "도면작성", "plan.menu.placement.surface.initial.setting": "配置面 初期設定", "plan.menu.root.cover": "지붕덮개", - "plan.menu.root.cover.outline.drawing": "외벽선 그리기", - "modal.cover.outline.drawing": "외벽선 그리기", - "modal.cover.outline": "외벽선", - "modal.cover.outline.right.angle": "직각", - "modal.cover.outline2": "이구배", - "modal.cover.outline.angle": "각도", - "modal.cover.outline.diagonal": "대각선", + "plan.menu.root.cover.outline.drawing": "外壁線を描", + "modal.cover.outline.drawing": "外壁線を描", + "modal.cover.outline": "外壁線", + "modal.cover.outline.right.angle": "直角", + "modal.cover.outline2": "イ・グベ", + "modal.cover.outline.angle": "角度", + "modal.cover.outline.diagonal": "対角線", "modal.cover.outline.setting": "설정", - "modal.cover.outline.length": "길이", - "modal.cover.outline.arrow": "방향(화살표)", - "modal.cover.outline.fix": "외벽선 확정", + "modal.cover.outline.length": "長さ (mm)", + "modal.cover.outline.arrow": "方向 (矢印)", + "modal.cover.outline.fix": "外壁線確定", + "modal.cover.outline.rollback": "一変戦に戻る", + "modal.cover.outline.remove": "外壁の削除", + "modal.cover.outline.select.move": "外壁の選択、移動", "plan.menu.root.cover.roof.setting": "屋根形状設定", "plan.menu.root.cover.roof.edit": "지붕형상 편집", "plan.menu.root.cover.sub.line": "補助線を描", @@ -49,6 +52,18 @@ "modal.canvas.setting": "Canvas設定", "modal.canvas.setting.display": "ディスプレイ設定", "modal.canvas.setting.font.plan": " フォントと図面サイズの設定", + "modal.canvas.setting.font.plan.edit": "フォントとサイズの変更", + "modal.canvas.setting.font.plan.edit.word": "文字フォントの変更", + "modal.canvas.setting.font.plan.edit.flow": "フロー方向フォントの変更", + "modal.canvas.setting.font.plan.edit.dimension": "寸法フォントの変更", + "modal.canvas.setting.font.plan.edit.circuit.num": "回路番号フォントの変更", + "modal.canvas.setting.font.plan.absorption": "吸着範囲の設定", + "modal.canvas.setting.font.plan.absorption.small": "極小", + "modal.canvas.setting.font.plan.absorption.small.semi": "牛", + "modal.canvas.setting.font.plan.absorption.medium": "中", + "modal.canvas.setting.font.plan.absorption.large": "ティーン", + "modal.canvas.setting.font.plan.absorption.dimension.line": "寸法線の設定", + "modal.canvas.setting.font.plan.absorption.plan.size.setting": "図面サイズの設定", "modal.canvas.setting.first.option.info": "※図面に表示する項目をクリックすると適用されます。", "modal.canvas.setting.first.option.alloc": "할당표시", "modal.canvas.setting.first.option.outline": "외벽선표시", diff --git a/src/locales/ko.json b/src/locales/ko.json index f519d872..cf7d758f 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -17,16 +17,19 @@ "plan.menu.placement.surface.initial.setting": "배치면 초기 설정", "plan.menu.root.cover": "지붕덮개", "plan.menu.root.cover.outline.drawing": "외벽선 그리기", - "modal.cover.outline.drawing": "외벽선 그리기", + "modal.cover.outline.drawing": "외벽선 작성", "modal.cover.outline": "외벽선", "modal.cover.outline.right.angle": "직각", "modal.cover.outline2": "이구배", "modal.cover.outline.angle": "각도", "modal.cover.outline.diagonal": "대각선", "modal.cover.outline.setting": "설정", - "modal.cover.outline.length": "길이", + "modal.cover.outline.length": "길이 (mm)", "modal.cover.outline.arrow": "방향(화살표)", "modal.cover.outline.fix": "외벽선 확정", + "modal.cover.outline.rollback": "일변전으로 돌아가기", + "modal.cover.outline.remove": "외벽 제거", + "modal.cover.outline.select.move": "외벽 선택, 이동", "plan.menu.root.cover.roof.setting": "지붕형상 설정", "plan.menu.root.cover.roof.edit": "지붕형상 편집", "plan.menu.root.cover.sub.line": "보조선 그리기", @@ -49,6 +52,18 @@ "modal.canvas.setting": "Canvas 설정", "modal.canvas.setting.display": "디스플레이 설정", "modal.canvas.setting.font.plan": "글꼴 및 도면 크기 설정", + "modal.canvas.setting.font.plan.edit": "글꼴 및 크기 변경", + "modal.canvas.setting.font.plan.edit.word": "문자 글꼴 변경", + "modal.canvas.setting.font.plan.edit.flow": "흐름 방향 글꼴 변경", + "modal.canvas.setting.font.plan.edit.dimension": "치수 글꼴변경", + "modal.canvas.setting.font.plan.edit.circuit.num": "회로번호 글꼴변경", + "modal.canvas.setting.font.plan.absorption": "흡착범위 설정", + "modal.canvas.setting.font.plan.absorption.small": "극소", + "modal.canvas.setting.font.plan.absorption.small.semi": "소", + "modal.canvas.setting.font.plan.absorption.medium": "중", + "modal.canvas.setting.font.plan.absorption.large": "대", + "modal.canvas.setting.font.plan.absorption.dimension.line": "치수선 설정", + "modal.canvas.setting.font.plan.absorption.plan.size.setting": "도면크기 설정", "modal.canvas.setting.first.option.info": "※도면에 표시하는 항목을 클릭하면 적용됩니다.", "modal.canvas.setting.first.option.alloc": "할당표시", "modal.canvas.setting.first.option.outline": "외벽선표시", diff --git a/src/store/modalAtom.js b/src/store/modalAtom.js index a9a708ac..fe3b6716 100644 --- a/src/store/modalAtom.js +++ b/src/store/modalAtom.js @@ -2,14 +2,8 @@ import { atom } from 'recoil' export const modalState = atom({ key: 'modalState', - default: false, -}) - -export const modalContent = atom({ - key: 'modalContent', - default: ( - <> -
test
- - ), + default: { + option: true, + outerwall: true, + }, }) diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js index 3f91f509..2899dd4e 100644 --- a/src/store/settingAtom.js +++ b/src/store/settingAtom.js @@ -29,16 +29,16 @@ export const settingModalSecondOptionsState = atom({ key: 'settingModalSecondOptions', default: { option1: [ - { id: 1, name: '文字フォントの変更' }, - { id: 2, name: 'フロー方向フォントの変更' }, - { id: 3, name: '寸法フォントの変更' }, - { id: 4, name: '回路番号フォントの変更' }, + { id: 1, name: 'modal.canvas.setting.font.plan.edit.word' }, + { id: 2, name: 'modal.canvas.setting.font.plan.edit.flow' }, + { id: 3, name: 'modal.canvas.setting.font.plan.edit.dimension' }, + { id: 4, name: 'modal.canvas.setting.font.plan.edit.circuit.num' }, ], option2: [ - { id: 1, name: '極小', selected: false }, - { id: 2, name: '牛', selected: false }, - { id: 3, name: '中', selected: false }, - { id: 4, name: 'ティーン', selected: false }, + { id: 1, name: 'modal.canvas.setting.font.plan.absorption.small', selected: false }, + { id: 2, name: 'modal.canvas.setting.font.plan.absorption.small.semi', selected: false }, + { id: 3, name: 'modal.canvas.setting.font.plan.absorption.medium', selected: false }, + { id: 4, name: 'modal.canvas.setting.font.plan.absorption.large', selected: false }, ], }, dangerouslyAllowMutability: true, From 34d7372c35d08694090b56af3c667188a32c3815 Mon Sep 17 00:00:00 2001 From: minsik Date: Thu, 12 Sep 2024 10:14:23 +0900 Subject: [PATCH 03/23] =?UTF-8?q?-=20Canvas=20=EC=84=A4=EC=A0=95,=20?= =?UTF-8?q?=EC=99=B8=EB=B2=BD=EC=84=A0=20=EA=B7=B8=EB=A6=AC=EA=B8=B0=20Mod?= =?UTF-8?q?al=20=EC=88=98=EC=A0=95=20-=20=EC=99=B8=EB=B2=BD=EC=84=A0=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20Modal=20open=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 8 +++++++- .../floor-plan/modal/setting01/SettingModal01.jsx | 9 ++++++--- src/store/modalAtom.js | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index cf5ada46..45896d96 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -34,7 +34,13 @@ export default function CanvasMenu() { {getMessage('plan.menu.placement.surface.initial.setting')} -
  • onClickNav(2)}> +
  • { + setModalOption({ ...modalOption, outerwall: true }) + onClickNav(2) + }} + > + {!isFormValid ? ( + <> + + + + ) : ( + + )} )) ||
    상세:::::::::::
    } From 7fc84937cf59fc37be3a1de3fbb2d0c634531255 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 12 Sep 2024 12:03:13 +0900 Subject: [PATCH 06/23] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EB=AA=A9=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 91cf5131..611fd07c 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -464,14 +464,24 @@ export default function StuffDetail() { {!isFormValid ? ( <> - + {/* */} ) : ( )} + + + - )) ||
    상세:::::::::::
    } + )) || ( +
    + 상세::::::::::: + + + +
    + )} {/*
    From c024a893cdd8b5fb73a2d0a160b41e26c03a4904 Mon Sep 17 00:00:00 2001 From: minsik Date: Thu, 12 Sep 2024 14:06:36 +0900 Subject: [PATCH 07/23] =?UTF-8?q?-=20modal=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20CanvasMenu=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.js | 3 +- src/components/floor-plan/CanvasMenu.jsx | 19 ++++--- src/components/floor-plan/FloorPlan.jsx | 27 +++++++--- src/components/floor-plan/MenuDepth01.jsx | 53 +++++++++++-------- .../modal/outerlinesetting/OuterLineWall.jsx | 15 ++---- .../modal/setting01/SettingModal01.jsx | 18 ++----- src/store/modalAtom.js | 14 +++-- 7 files changed, 81 insertions(+), 68 deletions(-) diff --git a/src/app/layout.js b/src/app/layout.js index 4d4a4f21..fd3a242d 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -8,6 +8,7 @@ import { ToastContainer } from 'react-toastify' import './globals.css' import '../styles/style.scss' import Header from '@/components/header/Header' +import QModal from '@/components/common/modal/QModal' const inter = Inter({ subsets: ['latin'] }) @@ -29,7 +30,7 @@ export default function RootLayout({ children }) {
    - {/**/} + diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 45896d96..6c53e9ba 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -1,22 +1,20 @@ 'use client' import { useState } from 'react' import MenuDepth01 from './MenuDepth01' -import { useRecoilState } from 'recoil' -import { modalState } from '@/store/modalAtom' import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' -export default function CanvasMenu() { - const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state +export default function CanvasMenu(props) { + const { setShowCanvasSettingModal, showOutlineModal, setShowOutlineModal } = props const [menuNumber, setMenuNumber] = useState(null) const [vertical, setVertical] = useState(true) const { getMessage } = useMessage() const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] const onClickNav = (number) => { setMenuNumber(number) - if (menuNumber === number) { - setMenuNumber(null) - } + } + const menuProps = { + setShowOutlineModal, } return (
    @@ -37,7 +35,8 @@ export default function CanvasMenu() {
  • { - setModalOption({ ...modalOption, outerwall: true }) + if (!showOutlineModal) setShowOutlineModal(true) + // setModalOption({ ...modalOption, outerwall: true }) onClickNav(2) }} > @@ -87,7 +86,7 @@ export default function CanvasMenu() {
    - +
    @@ -143,7 +142,7 @@ export default function CanvasMenu() {
    - {menuNumber === 2 && } + {menuNumber === 2 && } {menuNumber === 3 && } {menuNumber === 4 && }
    diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 1577227d..fd8dfe93 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -4,20 +4,35 @@ import CanvasMenu from '@/components/floor-plan/CanvasMenu' import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01' import CanvasLayout from '@/components/floor-plan/CanvasLayout' import '@/styles/contents.scss' -import { modalState } from '@/store/modalAtom' -import { useRecoilValue } from 'recoil' import OuterLineWall from '@/components/floor-plan/modal/outerlinesetting/OuterLineWall' +import { useState } from 'react' export default function FloorPlan() { - const modalOption = useRecoilValue(modalState) + const [showCanvasSettingModal, setShowCanvasSettingModal] = useState(false) + const [showOutlineModal, setShowOutlineModal] = useState(false) + + const canvasSettingProps = { + setShowCanvasSettingModal, + } + + const outlineProps = { + setShowOutlineModal, + } + + const modalProps = { + setShowCanvasSettingModal, + showOutlineModal, + setShowOutlineModal, + } + return ( <>
    - +
    - {modalOption.option && } - {modalOption.outerwall && } + {showCanvasSettingModal && } + {showOutlineModal && }
    diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index ce4bd6a4..08eac1f4 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -2,33 +2,42 @@ import { ToggleonMouse } from '@/components/header/Header' import { useMessage } from '@/hooks/useMessage' +import { useEffect, useState } from 'react' -export default function MenuDepth01() { +export default function MenuDepth01(props) { + const { setShowOutlineModal } = props const { getMessage } = useMessage() + const [activeMenu, setActiveMenu] = useState(0) + const onClickMenu = (menuNum) => { + setActiveMenu(menuNum) + setShowOutlineModal(menuNum === 0) + } + + const menus = [ + { id: 0, name: '外壁線を描' }, + { id: 1, name: '補助線を描' }, + { id: 2, name: '屋根形状設定' }, + { id: 3, name: '軒下変更' }, + { id: 4, name: '外壁線の上げ下げ' }, + { id: 5, name: '銅線移動' }, + { id: 6, name: '特殊コーナー形状' }, + ] + + useEffect(() => { + menus.forEach((menu) => { + menu.isActive = menu.id === activeMenu + }) + }, [menus, activeMenu]) return (
      -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • + {menus.map((menu) => { + return ( +
    • + +
    • + ) + })}
    • ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}> diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index 1ba1c597..b57e2cb0 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -2,25 +2,18 @@ import { useState } from 'react' import WithDraggable from '@/components/common/draggable/withDraggable' -import { modalState } from '@/store/modalAtom' -import { useRecoilState } from 'recoil' import { useMessage } from '@/hooks/useMessage' -export default function OuterLineWall() { - const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state +export default function OuterLineWall(props) { + const { setShowOutlineModal } = props const [buttonAct, setButtonAct] = useState(1) - const [close, setClose] = useState(false) const { getMessage } = useMessage() const HandleClickClose = () => { - setClose(true) - setTimeout(() => { - setModalOption({ ...modalOption, outerwall: false }) - setClose(false) - }, 180) + setShowOutlineModal(false) } return ( -
      +

      {getMessage('modal.cover.outline.drawing')}

      diff --git a/src/store/modalAtom.js b/src/store/modalAtom.js index 819669a1..a9a708ac 100644 --- a/src/store/modalAtom.js +++ b/src/store/modalAtom.js @@ -2,8 +2,14 @@ import { atom } from 'recoil' export const modalState = atom({ key: 'modalState', - default: { - option: false, - outerwall: false, - }, + default: false, +}) + +export const modalContent = atom({ + key: 'modalContent', + default: ( + <> +
      test
      + + ), }) From c1fd6087cdf38dd0f16741657472b08da9a7e9a5 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 12 Sep 2024 15:13:33 +0900 Subject: [PATCH 08/23] =?UTF-8?q?-=20=EC=99=B8=EB=B2=BD=EC=84=A0=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 5 +- src/components/floor-plan/CanvasLayout.jsx | 76 +++--- src/components/floor-plan/CanvasMenu.jsx | 52 ++-- .../floor-plan/RoofCoveringMenu.jsx | 54 +++++ .../modal/outerlinesetting/OuterLineWall.jsx | 227 +++++++++++++++--- src/hooks/useEvent.js | 112 ++++++--- src/store/canvasAtom.js | 7 +- src/store/outerLineAtom.js | 65 +++++ src/util/qpolygon-utils.js | 4 +- 9 files changed, 469 insertions(+), 133 deletions(-) create mode 100644 src/components/floor-plan/RoofCoveringMenu.jsx create mode 100644 src/store/outerLineAtom.js diff --git a/src/common/common.js b/src/common/common.js index aaba3f45..c78673ee 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -1,19 +1,22 @@ -export const STEP = { +export const MENU = { INITIAL_CANVAS_SETTING: 'initialCanvasSetting', // 배치면 초기설정 ROOF_COVERING: { EXTERIOR_WALL_LINE: 'exteriorWallLine', // 외벽선 그리기 ROOF_SHAPE_SETTINGS: 'roofShapeSettings', // 지붕형상 설정 ROOF_SHAPE_EDITING: 'roofShapeEditing', // 지붕형상 편집 HELP_LINE_DRAWING: 'helpLineDrawing', // 보조선 그리기 + DEFAULT: 'roofCoveringDefault', // 아무것도 선택 안할 경우 }, // 지붕덮개 BATCH_CANVAS: { BATCH_DRAWING: 'batchDrawing', // 배치면 그리기 SURFACE_SHAPE_BATCH: 'surfaceShapeBatch', // 면형상 배치 OBJECT_BATCH: 'objectBatch', // 오브젝트 배치 + DEFAULT: 'batchCanvasDefault', // default }, // 배치면 MODULE_CIRCUIT_SETTING: { BASIC_SETTING: 'basicSetting', // 기본설정 CIRCUIT_TRESTLE_SETTING: 'circuitTrestleSetting', // 회로가대설정 + DEFAULT: 'moduleCircuitSettingDefault', }, // 모듈회로구성 ESTIMATE: 'estimate', // todo 견적서 POWER_GENERATION_SIMULATION: 'powerGenerationSimulation', // todo 발전 시뮬레이션 diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 5be6a114..71c48845 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -1,45 +1,47 @@ 'use client' -import { useState } from "react" -import CanvasFrame from "./CanvasFrame"; +import { useState } from 'react' +import CanvasFrame from './CanvasFrame' +import { useRecoilState, useRecoilValue } from 'recoil' +import { currentMenuState, stepState } from '@/store/canvasAtom' -export default function CanvasLayout () { - const [plans, setPlans] = useState([{ id: 0, name: 'Plan 1' }, { id: 1, name: 'Plan 2' }, { id: 2, name: 'Plan 3' }]); - const [idxNum, setIdxNum] = useState(null); +export default function CanvasLayout() { + const [plans, setPlans] = useState([ + { id: 0, name: 'Plan 1' }, + { id: 1, name: 'Plan 2' }, + { id: 2, name: 'Plan 3' }, + ]) + const [idxNum, setIdxNum] = useState(null) - const onClickPlane = (num) => { - setIdxNum(num); - } + const onClickPlane = (num) => { + setIdxNum(num) + } - const handleDeletePlan = (e, id) => { - e.stopPropagation(); // 이벤트 버블링 방지 - setPlans(plans.filter(plan => plan.id !== id)); // 삭제할 아이디와 다른 아이템만 남김 - } + const handleDeletePlan = (e, id) => { + e.stopPropagation() // 이벤트 버블링 방지 + setPlans(plans.filter((plan) => plan.id !== id)) // 삭제할 아이디와 다른 아이템만 남김 + } - const addNewPlan = () => { - setPlans([...plans, { id: plans.length, name: `Plan ${plans.length + 1}` }]); - } + const addNewPlan = () => { + setPlans([...plans, { id: plans.length, name: `Plan ${plans.length + 1}` }]) + } - return( -
      -
      -
      - {plans.map((plan, idx) => ( - - ))} -
      - -
      - + return ( +
      +
      +
      + {plans.map((plan, idx) => ( + + ))}
      - ) -} \ No newline at end of file + +
      + +
      + ) +} diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 45896d96..4cb14c5c 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -1,10 +1,12 @@ 'use client' import { useState } from 'react' -import MenuDepth01 from './MenuDepth01' import { useRecoilState } from 'recoil' import { modalState } from '@/store/modalAtom' import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' +import { currentMenuState } from '@/store/canvasAtom' +import { MENU } from '@/common/common' +import RoofCoveringMenu from '@/components/floor-plan/RoofCoveringMenu' export default function CanvasMenu() { const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state @@ -12,34 +14,37 @@ export default function CanvasMenu() { const [vertical, setVertical] = useState(true) const { getMessage } = useMessage() const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] - const onClickNav = (number) => { - setMenuNumber(number) - if (menuNumber === number) { - setMenuNumber(null) - } + const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState) + + const onClickNav = (menu) => { + setCurrentMenu(menu) } return ( -
      +
        -
      • onClickNav(0)}> +
      • onClickNav(1)}>
      • -
      • onClickNav(1)}> - -
      • + { +
      • onClickNav(MENU.INITIAL_CANVAS_SETTING)} + > + +
      • + }
      • { - setModalOption({ ...modalOption, outerwall: true }) - onClickNav(2) - }} + className={`canvas-menu-item ${Object.values(MENU.ROOF_COVERING).includes(currentMenu) ? 'active' : ''}`} + onClick={() => onClickNav(MENU.ROOF_COVERING.DEFAULT)} >
      -
      - {menuNumber === 2 && } +
      + {Object.values(MENU.ROOF_COVERING).includes(currentMenu) && } + {/*{menuNumber === 2 && } {menuNumber === 3 && } - {menuNumber === 4 && } + {menuNumber === 4 && }*/}
      ) diff --git a/src/components/floor-plan/RoofCoveringMenu.jsx b/src/components/floor-plan/RoofCoveringMenu.jsx new file mode 100644 index 00000000..26da4bda --- /dev/null +++ b/src/components/floor-plan/RoofCoveringMenu.jsx @@ -0,0 +1,54 @@ +'use client' + +import { useMessage } from '@/hooks/useMessage' +import { useRecoilState, useSetRecoilState } from 'recoil' +import { currentMenuState } from '@/store/canvasAtom' +import { MENU } from '@/common/common' +import { modalState } from '@/store/modalAtom' +import { ToggleonMouse } from '@/components/header/Header' + +export default function RoofCoveringMenu() { + const { getMessage } = useMessage() + const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState) + + const setModalState = useSetRecoilState(modalState) + + const onClickNav = (menu) => { + setCurrentMenu(menu) + if (menu === MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) { + setModalState((prev) => ({ ...prev, outerwall: true })) + } else { + setModalState((prev) => ({ ...prev, outerwall: false })) + } + } + + return ( +
      +
        +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      +
        +
      • 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/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index 1ba1c597..f3699a50 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -1,68 +1,239 @@ 'use client' -import { useState } from 'react' +import { useEffect, useRef } from 'react' import WithDraggable from '@/components/common/draggable/withDraggable' import { modalState } from '@/store/modalAtom' -import { useRecoilState } from 'recoil' +import { useRecoilState, useRecoilValue } from 'recoil' import { useMessage } from '@/hooks/useMessage' +import { useEvent } from '@/hooks/useEvent' +import { canvasState } from '@/store/canvasAtom' +import { + OUTER_LINE_TYPE, + outerLineArrow1State, + outerLineArrow2State, + outerLineLength1State, + outerLineLength2State, + outerLinePointsState, + outerLineTypeState, +} from '@/store/outerLineAtom' +import { QLine } from '@/components/fabric/QLine' export default function OuterLineWall() { const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state - const [buttonAct, setButtonAct] = useState(1) - const [close, setClose] = useState(false) const { getMessage } = useMessage() - const HandleClickClose = () => { - setClose(true) - setTimeout(() => { - setModalOption({ ...modalOption, outerwall: false }) - setClose(false) - }, 180) + const { addCanvasMouseEventListener, addDocumentEventListener } = useEvent() + const length1Ref = useRef(null) + const length2Ref = useRef(null) + const [length1, setLength1] = useRecoilState(outerLineLength1State) + const [length2, setLength2] = useRecoilState(outerLineLength2State) + const [arrow1, setArrow1] = useRecoilState(outerLineArrow1State) + const [arrow2, setArrow2] = useRecoilState(outerLineArrow2State) + const [points, setPoints] = useRecoilState(outerLinePointsState) + const [type, setType] = useRecoilState(outerLineTypeState) + + const canvas = useRecoilValue(canvasState) + + useEffect(() => { + addCanvasMouseEventListener('mouse:down', mouseDown) + addDocumentEventListener('keydown', document, keydown) + }, []) + + useEffect(() => { + clear() + }, [type]) + + const clear = () => { + setLength1(0) + setArrow1('') } + + const mouseDown = (e) => { + const pointer = canvas.getPointer(e.e) + + setPoints((prev) => [...prev, pointer]) + } + + useEffect(() => { + canvas + ?.getObjects() + .filter((obj) => obj.name === 'outerLine') + .forEach((obj) => { + canvas?.remove(obj) + }) + canvas?.remove(canvas?.getObjects().find((obj) => obj.name === 'startPoint')) + if (points.length === 0) { + return + } + + if (points.length === 1) { + const point = new fabric.Circle({ + radius: 5, + fill: 'transparent', + stroke: 'red', + left: points[0].x - 5, + top: points[0].y - 5, + selectable: false, + name: 'startPoint', + }) + + canvas?.add(point) + } else { + points.forEach((point, idx) => { + if (idx === 0) { + return + } + drawLine(points[idx - 1], point) + }) + } + }, [points]) + + const drawLine = (point1, point2) => { + const line = new QLine([point1.x, point1.y, point2.x, point2.y], { + stroke: 'black', + strokeWidth: 1, + selectable: false, + name: 'outerLine', + }) + + line.setViewLengthText(true) + + canvas?.add(line) + } + + const keydown = (e) => { + const key = e.key + + const lengthNum = Number(length1Ref.current.value) + if (lengthNum === 0) { + return + } + switch (key) { + case 'Down': // IE/Edge에서 사용되는 값 + case 'ArrowDown': + setArrow1('↓') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y + lengthNum }] + }) + break + case 'Up': // IE/Edge에서 사용되는 값 + case 'ArrowUp': + setArrow1('↑') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y - lengthNum }] + }) + break + case 'Left': // IE/Edge에서 사용되는 값 + case 'ArrowLeft': + setArrow1('←') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - lengthNum, y: prev[prev.length - 1].y }] + }) + break + case 'Right': // IE/Edge에서 사용되는 값 + case 'ArrowRight': + setArrow1('→') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + lengthNum, y: prev[prev.length - 1].y }] + }) + break + } + } + + /** + * 일변전으로 돌아가기 + */ + const handleRollback = () => { + //points의 마지막 요소를 제거 + setPoints((prev) => prev.slice(0, prev.length - 1)) + } + + const handleClickClose = () => { + setModalOption({ ...modalOption, outerwall: false }) + } + + const handleFix = () => {} return ( -
      +

      {getMessage('modal.cover.outline.drawing')}

      -
      - - - - -

      {getMessage('modal.cover.outline.setting')}

      -
      -
      - - + {type === OUTER_LINE_TYPE.OUTER_LINE ? ( +
      +
      + + { + setLength1(e.target.value.replace(/[^-0-9]/g, '')) + }} + placeholder="3000" + /> +
      +
      + + +
      -
      - - -
      -
      + ) : ( + <> + )}
      - - -
      - {isLoggedIn && ( -
      - -
      - )} - {!isLoggedIn && ( -
      - - - -
      - )} -
      font-test
      - {/*

      {t('locale', { locale: {currentLocale} })}

      */} - {/*
      {t('hello')}
      */} - {/*
      {t('welcome', { name: '효준' })}
      */} - {/*
      */} - {/* */} - {/*
      */} - {/*{isLoggedIn && (*/} - {/*
      */} - {/* */} - {/*
      */} - {/*)}*/} - {/*
      font-test
      */} +

      Main page

      ) } diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index f81a0ca7..5335eaab 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -1,8 +1,9 @@ 'use client' import Link from 'next/link' -import QSelectBox from '@/components/common/select/QSelectBox' import { usePathname } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' +import QSelectBox from '@/components/common/select/QSelectBox' +import { getSession } from '@/lib/authActions' export const ToggleonMouse = (e, act, target) => { const listWrap = e.target.closest(target) @@ -19,7 +20,9 @@ export const ToggleonMouse = (e, act, target) => { } } -export default function Header() { +export default function Header(props) { + const { loginedUserNm } = props + // console.log('loginedUserNm:', loginedUserNm) const { getMessage } = useMessage() const pathName = usePathname() if (pathName.includes('login') || pathName.includes('join')) { @@ -101,7 +104,7 @@ export default function Header() {
      - +
      diff --git a/src/lib/authActions.js b/src/lib/authActions.js index 06c02ef0..eafddadd 100644 --- a/src/lib/authActions.js +++ b/src/lib/authActions.js @@ -27,6 +27,14 @@ export async function getSession() { return session } +export async function checkSession() { + const session = await getSession() + + if (!session.isLoggedIn) { + redirect('/login') + } +} + export async function setSession(data) { const session = await getSession() From 493317b27112896c9c8a767de5edb7adc90934f6 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 12 Sep 2024 15:45:02 +0900 Subject: [PATCH 10/23] =?UTF-8?q?line,=20polygon=20=EA=B4=80=EB=A0=A8=20ho?= =?UTF-8?q?ok=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/outerlinesetting/OuterLineWall.jsx | 8 ++-- src/hooks/useLine.js | 43 +++++++++++++++++++ src/hooks/usePolygon.js | 8 ++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 src/hooks/useLine.js create mode 100644 src/hooks/usePolygon.js diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index f3699a50..a44abb81 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -17,11 +17,13 @@ import { outerLineTypeState, } from '@/store/outerLineAtom' import { QLine } from '@/components/fabric/QLine' +import { useLine } from '@/hooks/useLine' export default function OuterLineWall() { const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state const { getMessage } = useMessage() const { addCanvasMouseEventListener, addDocumentEventListener } = useEvent() + const { addLineText, removeLineText } = useLine() const length1Ref = useRef(null) const length2Ref = useRef(null) const [length1, setLength1] = useRecoilState(outerLineLength1State) @@ -59,6 +61,7 @@ export default function OuterLineWall() { .filter((obj) => obj.name === 'outerLine') .forEach((obj) => { canvas?.remove(obj) + removeLineText(obj) }) canvas?.remove(canvas?.getObjects().find((obj) => obj.name === 'startPoint')) if (points.length === 0) { @@ -95,15 +98,14 @@ export default function OuterLineWall() { name: 'outerLine', }) - line.setViewLengthText(true) - canvas?.add(line) + addLineText(line) } const keydown = (e) => { const key = e.key - const lengthNum = Number(length1Ref.current.value) + const lengthNum = Number(length1Ref.current.value) / 10 if (lengthNum === 0) { return } diff --git a/src/hooks/useLine.js b/src/hooks/useLine.js new file mode 100644 index 00000000..81ebd1db --- /dev/null +++ b/src/hooks/useLine.js @@ -0,0 +1,43 @@ +import { useRecoilValue } from 'recoil' +import { canvasState, fontSizeState } from '@/store/canvasAtom' + +export const useLine = () => { + const canvas = useRecoilValue(canvasState) + const fontSize = useRecoilValue(fontSizeState) + + const addLineText = (line) => { + removeLineText(line) + + const text = new fabric.Text(getLengthByLine(line).toFixed(0), { + left: (line.x2 + line.x1) / 2, + top: (line.y2 + line.y1) / 2, + parent: line, + name: 'lengthTxt', + fontSize: fontSize, + }) + + canvas?.add(text) + } + + const removeLineText = (line) => { + canvas?.remove(canvas?.getObjects().find((obj) => obj.parent === line)) + } + + const getLengthByLine = (line) => { + const scaleX = line.scaleX + const scaleY = line.scaleY + const x1 = line.left + const y1 = line.top + const x2 = line.left + line.width * scaleX + const y2 = line.top + line.height * scaleY + const dx = x2 - x1 + const dy = y2 - y1 + + return Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) * 10 + } + + return { + addLineText, + removeLineText, + } +} diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js new file mode 100644 index 00000000..72354443 --- /dev/null +++ b/src/hooks/usePolygon.js @@ -0,0 +1,8 @@ +import { canvasState } from '@/store/canvasAtom' +import { useRecoilValue } from 'recoil' + +export const usePolygon = () => { + const canvas = useRecoilValue(canvasState) + + return {} +} From 98680aecf9fe72b1249f38c8b7caa85313920016 Mon Sep 17 00:00:00 2001 From: minsik Date: Thu, 12 Sep 2024 16:21:03 +0900 Subject: [PATCH 11/23] =?UTF-8?q?-=20menu=20link=20=EC=B6=94=EA=B0=80=20-?= =?UTF-8?q?=20modal=20=EC=9C=84=EC=B9=98=EC=88=98=EC=A0=95=20-=20logout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/[locale]/page.js | 3 +-- .../common/draggable/withDraggable.jsx | 8 ++++++-- src/components/floor-plan/MenuDepth01.jsx | 2 +- .../modal/outerlinesetting/OuterLineWall.jsx | 2 +- .../modal/setting01/SettingModal01.jsx | 2 +- src/components/header/Header.jsx | 18 +++++++++++------- src/lib/authActions.js | 4 +--- src/locales/ko.json | 1 + src/styles/_modal.scss | 2 -- 9 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/app/[locale]/page.js b/src/app/[locale]/page.js index b45f2690..aa5d3f7e 100644 --- a/src/app/[locale]/page.js +++ b/src/app/[locale]/page.js @@ -1,9 +1,8 @@ -import { getSession } from '@/lib/authActions' // import { getCurrentLocale } from '@/locales/server' import MainPage from '@/components/Main' export default async function page() { - const session = await getSession() + // const session = await getSession() // const currentLocale = getCurrentLocale() diff --git a/src/components/common/draggable/withDraggable.jsx b/src/components/common/draggable/withDraggable.jsx index 9f322583..b6c2920b 100644 --- a/src/components/common/draggable/withDraggable.jsx +++ b/src/components/common/draggable/withDraggable.jsx @@ -1,15 +1,19 @@ 'use client' -import { useState } from 'react' +import { useEffect, useState } from 'react' import Draggable from 'react-draggable' -export default function WithDraggable({ isShow, children }) { +export default function WithDraggable({ isShow, children, pos }) { const [position, setPosition] = useState({ x: 0, y: 0 }) const handleOnDrag = (data) => { setPosition({ x: data.x, y: data.y }) } + useEffect(() => { + setPosition({ ...pos }) + }, []) + return ( <> {isShow && ( diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index 08eac1f4..170fd820 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -33,7 +33,7 @@ export default function MenuDepth01(props) {
        {menus.map((menu) => { return ( -
      • +
      • ) diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index b57e2cb0..cd1d2c19 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -12,7 +12,7 @@ export default function OuterLineWall(props) { setShowOutlineModal(false) } return ( - +

        {getMessage('modal.cover.outline.drawing')}

        diff --git a/src/components/floor-plan/modal/setting01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx index c1f2651d..6ce186b7 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -12,7 +12,7 @@ export default function SettingModal01(props) { const { getMessage } = useMessage() return ( - +

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

        diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 5335eaab..5f90a132 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -3,7 +3,6 @@ import Link from 'next/link' import { usePathname } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' import QSelectBox from '@/components/common/select/QSelectBox' -import { getSession } from '@/lib/authActions' export const ToggleonMouse = (e, act, target) => { const listWrap = e.target.closest(target) @@ -29,6 +28,9 @@ export default function Header(props) { return null } const SelectOption = [{ name: 'オンライン保証シ' }, { name: 'ステム' }] + const onLogout = () => { + // logout() + } return (
        @@ -44,7 +46,7 @@ export default function Header(props) { onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')} > - {getMessage('header.menus.home')} + {getMessage('header.menus.home')}
      • ToggleonMouse(e, 'add', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} > - {getMessage('header.menus.management.plan')} + {getMessage('header.menus.management.plan')}
    • @@ -81,21 +83,21 @@ export default function Header(props) { onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} > - {getMessage('header.menus.community.notice')} + {getMessage('header.menus.community.notice')}
    • ToggleonMouse(e, 'add', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} > - {getMessage('header.menus.community.faq')} + {getMessage('header.menus.community.faq')}
    • ToggleonMouse(e, 'add', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} > - {getMessage('header.menus.community.archive')} + {getMessage('header.menus.community.archive')}
  • @@ -107,7 +109,9 @@ export default function Header(props) {
    - +
    diff --git a/src/lib/authActions.js b/src/lib/authActions.js index eafddadd..c19ba0f0 100644 --- a/src/lib/authActions.js +++ b/src/lib/authActions.js @@ -4,9 +4,7 @@ import { cookies } from 'next/headers' import { redirect } from 'next/navigation' import { getIronSession } from 'iron-session' - -import { getUserByIdAndPassword } from './user' -import { defaultSession, sessionOptions } from './session' +import { sessionOptions } from './session' export async function logout() { const session = await getSession() diff --git a/src/locales/ko.json b/src/locales/ko.json index cf7d758f..bb7451d3 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -17,6 +17,7 @@ "plan.menu.placement.surface.initial.setting": "배치면 초기 설정", "plan.menu.root.cover": "지붕덮개", "plan.menu.root.cover.outline.drawing": "외벽선 그리기", + "plan.menu.root.cover.auxiliary.line.drawing": "보조선 그리기", "modal.cover.outline.drawing": "외벽선 작성", "modal.cover.outline": "외벽선", "modal.cover.outline.right.angle": "직각", diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index c57e5968..0dd9d68f 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -22,8 +22,6 @@ .modal-pop-wrap { position: fixed; - top: 200px; - right: 100px; width: 100%; min-width: 380px; max-width: fit-content; From d3958665f2d94421f19b29a105d58b88e9a37019 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 12 Sep 2024 17:27:42 +0900 Subject: [PATCH 12/23] =?UTF-8?q?=EC=99=B8=EB=B2=BD=EC=84=A0=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=3D>=20=EC=A7=81=EA=B0=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/outerlinesetting/OuterLineWall.jsx | 298 +++++++++++++++--- 1 file changed, 250 insertions(+), 48 deletions(-) diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index a44abb81..c5bd5686 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useRef } from 'react' +import { useCallback, useEffect, useRef } from 'react' import WithDraggable from '@/components/common/draggable/withDraggable' import { modalState } from '@/store/modalAtom' import { useRecoilState, useRecoilValue } from 'recoil' @@ -22,7 +22,7 @@ import { useLine } from '@/hooks/useLine' export default function OuterLineWall() { const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state const { getMessage } = useMessage() - const { addCanvasMouseEventListener, addDocumentEventListener } = useEvent() + const { addCanvasMouseEventListener, addDocumentEventListener, removeAllDocumentEventListeners } = useEvent() const { addLineText, removeLineText } = useLine() const length1Ref = useRef(null) const length2Ref = useRef(null) @@ -32,21 +32,35 @@ export default function OuterLineWall() { const [arrow2, setArrow2] = useRecoilState(outerLineArrow2State) const [points, setPoints] = useRecoilState(outerLinePointsState) const [type, setType] = useRecoilState(outerLineTypeState) + const arrow1Ref = useRef(arrow1) + const arrow2Ref = useRef(arrow2) const canvas = useRecoilValue(canvasState) useEffect(() => { addCanvasMouseEventListener('mouse:down', mouseDown) - addDocumentEventListener('keydown', document, keydown) }, []) useEffect(() => { + arrow1Ref.current = arrow1 + }, [arrow1]) + + useEffect(() => { + arrow2Ref.current = arrow2 + }, [arrow2]) + + useEffect(() => { + removeAllDocumentEventListeners() + addDocumentEventListener('keydown', document, keydown[type]) clear() }, [type]) const clear = () => { setLength1(0) + setLength2(0) + setArrow1('') + setArrow2('') } const mouseDown = (e) => { @@ -102,55 +116,206 @@ export default function OuterLineWall() { addLineText(line) } - const keydown = (e) => { - const key = e.key + // 직각 완료될 경우 확인 + const checkRightAngle = () => { + const length1Num = Number(length1Ref.current.value) / 10 + const length2Num = Number(length2Ref.current.value) / 10 + console.log(length1Num, length2Num, arrow1Ref.current, arrow2Ref.current) - const lengthNum = Number(length1Ref.current.value) / 10 - if (lengthNum === 0) { + if (points.length === 0) { return } - switch (key) { - case 'Down': // IE/Edge에서 사용되는 값 - case 'ArrowDown': - setArrow1('↓') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y + lengthNum }] - }) - break - case 'Up': // IE/Edge에서 사용되는 값 - case 'ArrowUp': - setArrow1('↑') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y - lengthNum }] - }) - break - case 'Left': // IE/Edge에서 사용되는 값 - case 'ArrowLeft': - setArrow1('←') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x - lengthNum, y: prev[prev.length - 1].y }] - }) - break - case 'Right': // IE/Edge에서 사용되는 값 - case 'ArrowRight': - setArrow1('→') - setPoints((prev) => { - if (prev.length === 0) { - return [] - } - return [...prev, { x: prev[prev.length - 1].x + lengthNum, y: prev[prev.length - 1].y }] - }) - break + + if (length1Num === 0 || length2Num === 0 || arrow1Ref.current === '' || arrow2Ref.current === '') { + return } + + if (arrow1Ref.current === '↓' && arrow2Ref.current === '→') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length2Num, y: prev[prev.length - 1].y + length1Num }] + }) + } else if (arrow1Ref.current === '↓' && arrow2Ref.current === '←') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length2Num, y: prev[prev.length - 1].y + length1Num }] + }) + } else if (arrow1Ref.current === '↑' && arrow2Ref.current === '→') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length2Num, y: prev[prev.length - 1].y - length1Num }] + }) + } else if (arrow1Ref.current === '↑' && arrow2Ref.current === '←') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length2Num, y: prev[prev.length - 1].y - length1Num }] + }) + } else if (arrow1Ref.current === '→' && arrow2Ref.current === '↓') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length1Num, y: prev[prev.length - 1].y + length2Num }] + }) + } else if (arrow1Ref.current === '→' && arrow2Ref.current === '↑') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + length1Num, y: prev[prev.length - 1].y - length2Num }] + }) + } else if (arrow1Ref.current === '←' && arrow2Ref.current === '↓') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length1Num, y: prev[prev.length - 1].y + length2Num }] + }) + } else if (arrow1Ref.current === '←' && arrow2Ref.current === '↑') { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - length1Num, y: prev[prev.length - 1].y - length2Num }] + }) + } + } + + const keydown = { + outerLine: (e) => { + const key = e.key + + if (!length1Ref.current) { + return + } + + const lengthNum = Number(length1Ref.current.value) / 10 + if (lengthNum === 0) { + return + } + switch (key) { + case 'Down': // IE/Edge에서 사용되는 값 + case 'ArrowDown': { + setArrow1('↓') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y + lengthNum }] + }) + break + } + case 'Up': // IE/Edge에서 사용되는 값 + case 'ArrowUp': + setArrow1('↑') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x, y: prev[prev.length - 1].y - lengthNum }] + }) + break + case 'Left': // IE/Edge에서 사용되는 값 + case 'ArrowLeft': + setArrow1('←') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x - lengthNum, y: prev[prev.length - 1].y }] + }) + break + case 'Right': // IE/Edge에서 사용되는 값 + case 'ArrowRight': + setArrow1('→') + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[prev.length - 1].x + lengthNum, y: prev[prev.length - 1].y }] + }) + break + } + }, + rightAngle: (e) => { + const key = e.key + + const activeElem = document.activeElement + const length1Num = Number(length1Ref.current.value) / 10 + const length2Num = Number(length2Ref.current.value) / 10 + + switch (key) { + case 'Down': // IE/Edge에서 사용되는 값 + case 'ArrowDown': { + if (activeElem === length1Ref.current) { + setArrow1('↓') + arrow1Ref.current = '↓' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') { + break + } + setArrow2('↓') + arrow2Ref.current = '↓' + checkRightAngle() + } + + break + } + case 'Up': // IE/Edge에서 사용되는 값 + case 'ArrowUp': + if (activeElem === length1Ref.current) { + setArrow1('↑') + arrow1Ref.current = '↑' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') { + break + } + setArrow2('↑') + arrow2Ref.current = '↑' + checkRightAngle() + } + + break + case 'Left': // IE/Edge에서 사용되는 값 + case 'ArrowLeft': + if (activeElem === length1Ref.current) { + setArrow1('←') + arrow1Ref.current = '←' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '←' || arrow1Ref.current === '→') { + break + } + setArrow2('←') + arrow2Ref.current = '←' + checkRightAngle() + } + + break + case 'Right': // IE/Edge에서 사용되는 값 + case 'ArrowRight': + if (activeElem === length1Ref.current) { + setArrow1('→') + arrow1Ref.current = '→' + } else if (activeElem === length2Ref.current) { + if (arrow1Ref.current === '←' || arrow1Ref.current === '→') { + break + } + setArrow2('→') + arrow2Ref.current = '→' + checkRightAngle() + } + + break + } + }, } /** @@ -228,6 +393,43 @@ export default function OuterLineWall() {
    + ) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? ( +
    +
    + + { + setLength1(e.target.value.replace(/[^-0-9]/g, '')) + }} + placeholder="3000" + /> +
    +
    + + +
    +
    + + { + setLength2(e.target.value.replace(/[^-0-9]/g, '')) + }} + placeholder="3000" + /> +
    +
    + + +
    +
    ) : ( <> )} From b59bdd0645af5dc358da958ef892f3e78790658d Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 12 Sep 2024 17:45:40 +0900 Subject: [PATCH 13/23] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=ED=98=84=ED=99=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[locale]/management/stuff/detail/page.jsx | 4 + .../management/stuff/tempdetail/page.jsx | 15 + src/components/management/Stuff.jsx | 150 ++++++---- src/components/management/StuffDetail.jsx | 272 +++++++++++------- .../management/StuffSearchCondition.jsx | 50 +++- src/locales/ko.json | 2 +- src/store/stuffAtom.js | 4 + 7 files changed, 340 insertions(+), 157 deletions(-) create mode 100644 src/app/[locale]/management/stuff/tempdetail/page.jsx diff --git a/src/app/[locale]/management/stuff/detail/page.jsx b/src/app/[locale]/management/stuff/detail/page.jsx index 8b84287a..6759b282 100644 --- a/src/app/[locale]/management/stuff/detail/page.jsx +++ b/src/app/[locale]/management/stuff/detail/page.jsx @@ -1,11 +1,15 @@ import React from 'react' import Hero from '@/components/Hero' import StuffDetail from '@/components/management/StuffDetail' +import Link from 'next/link' export default function ManagementStuffDetailPage() { return ( <>

    물건정보

    + +

    도면작성

    +
    diff --git a/src/app/[locale]/management/stuff/tempdetail/page.jsx b/src/app/[locale]/management/stuff/tempdetail/page.jsx new file mode 100644 index 00000000..8b84287a --- /dev/null +++ b/src/app/[locale]/management/stuff/tempdetail/page.jsx @@ -0,0 +1,15 @@ +import React from 'react' +import Hero from '@/components/Hero' +import StuffDetail from '@/components/management/StuffDetail' +export default function ManagementStuffDetailPage() { + return ( + <> +
    +

    물건정보

    +
    +
    + +
    + + ) +} diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index cf427814..e445fa1d 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -6,7 +6,7 @@ import { Button } from '@nextui-org/react' import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' import StuffQGrid from './StuffQGrid' -import { useRecoilValue } from 'recoil' +import { useRecoilValue, useRecoilState } from 'recoil' import { stuffSearchState } from '@/store/stuffAtom' import { queryStringFormatter, isEmptyArray } from '@/util/common-utils' import dayjs from 'dayjs' @@ -15,10 +15,12 @@ dayjs.extend(isLeapYear) export default function Stuff() { const stuffSearchParams = useRecoilValue(stuffSearchState) + const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) const { getMessage } = useMessage() const [curPage, setCurPage] = useState(1) //현재 페이지 번호 - const [size, setSize] = useState(100) //페이지 당 게시물 수 - const { get, del } = useAxios() + const [defaultSize, setDefaultSize] = useState(100) //페이지 당 게시물 수 + const [defaultSortType, setDefaultSortType] = useState('R') + const { get } = useAxios() const gridRef = useRef() const [gridCount, setGridCount] = useState(0) @@ -38,13 +40,26 @@ export default function Stuff() { } } + //물건번호 복사버튼 옆에 영역 + const onDoubleClick = (e) => { + let objectNo = e.target.innerText + console.log(objectNo) + if (objectNo.substring(0, 1) === 'R') { + console.log('진짜') + router.push(`${pathname}/detail?objectNo=${objectNo.toString()}`) + } else { + console.log('임시') + router.push(`${pathname}/tempdetail?objectNo=${objectNo.toString()}`) + } + } + const [gridProps, setGridProps] = useState({ gridData: [], isPageable: false, // sets 10 rows per page (default is 100) - paginationPageSize: 100, + // paginationPageSize: 100, // allows the user to select the page size from a predefined list of page sizes - paginationPageSizeSelector: [100, 200, 300, 400], + // paginationPageSizeSelector: [100, 200, 300, 400], gridColumns: [ { field: 'lastEditDatetime', @@ -82,7 +97,6 @@ export default function Stuff() {
    - {params.value} + {params.value}
    ) } @@ -148,8 +162,15 @@ export default function Stuff() { return } else { console.log(' 상세이동::::::::', event.data) + //T 면 임시 R은 진짜 if (event.data.objectNo) { - router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`) + if (event.data.objectNo.substring(0, 1) === 'R') { + console.log('진짜:::::::::') + router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`) + } else { + console.log('임시:::::::::::::::::') + router.push(`${pathname}/tempdetail?objectNo=${event.data.objectNo.toString()}`) + } } } } @@ -175,45 +196,6 @@ export default function Stuff() { errCount++ } }) - - async function fetchDelete(data) { - console.log('물건삭제API호출!!!!!!!!!', data) - //행추가말고 api데이터만 보냄 - // let newData = data.filter((item) => item.company != null) - // console.log('삭제에 전송되는 데이타::', newData) - // await del({ url: '', data:newData }) - await get({ url: 'https://www.ag-grid.com/example-assets/space-mission-data.json' }) - // try { - // const res = await del({url:'', data:newData}) - - // if(!res || res.length === 0) { - - // } else { - fetchData() - // } - // } catch (error) { - // console.error('Data Delete error:', error); - // } - } - - // 삭제API 완료 후 fetchData Api호출 - async function fetchData() { - console.log('물건삭제후 조회API호출!!!!!!!!!!!!!', stuffSearchParams) - const data = await get({ url: 'https://www.ag-grid.com/example-assets/space-mission-data.json' }) - setGridProps({ ...gridProps, gridData: data, count: data.length }) - setGridCount(data.length) - //data.length = 10 - //setGridProps({ ...gridProps, gridData: data, count: data.length-1}) - //setGridCount(data.length - 1 ) - } - - if (errCount === 0) { - // console.log('errCount::::::::', errCount) - fetchDelete(data) - // fetchData() - } else { - alert('물건정보가 있는 행만 선택해주세요') - } } //행추가 @@ -265,15 +247,14 @@ 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) * size + 1, - endRow: curPage * size, + startRow: (curPage - 1) * defaultSize + 1, + endRow: curPage * defaultSize, + schSelSaleStoreId: '', + schSortType: 'R', } async function fetchData() { console.log('화면진입:::::::::::::', params) - console.log('현재페이지::::::', curPage) - console.log('페이지당 게시물수::::::', size) - //api에 넘길값 startRow, endRow // let startRow // let endRow @@ -306,6 +287,9 @@ export default function Stuff() { useEffect(() => { if (stuffSearchParams?.code === 'E') { + stuffSearchParams.startRow = (curPage - 1) * defaultSize + 1 + stuffSearchParams.endRow = curPage * defaultSize + stuffSearchParams.schSortType = defaultSortType console.log('조회 눌럿을때 ::::::::::::::', stuffSearchParams) async function fetchData() { const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` @@ -314,6 +298,9 @@ export default function Stuff() { if (!isEmptyArray(res)) { setGridProps({ ...gridProps, gridData: res, count: res.length }) setGridCount(res.length) + } else { + setGridProps({ ...gridProps, gridData: [], count: 0 }) + setGridCount(0) } }) } @@ -321,6 +308,56 @@ export default function Stuff() { } }, [stuffSearchParams]) + //페이지 갯수 변경 이벤트 + const onChangePerPage = (e) => { + let startRow = (curPage - 1) * e.target.value + 1 + stuffSearchParams.startRow = startRow + stuffSearchParams.endRow = curPage * e.target.value + setDefaultSize(e.target.value) + setStuffSearch({ + ...stuffSearch, + code: 'S', + startRow: startRow, + endRow: curPage * e.target.value, + }) + console.log('셋팅된 검색조건:::', stuffSearchParams) + //조회API호출 + const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + get({ url: apiUrl }).then((res) => { + console.log('보여줄개수바꿨을때 조회 ::::::::::', res) + if (!isEmptyArray(res)) { + setGridProps({ ...gridProps, gridData: res, count: res.length }) + setGridCount(res.length) + } else { + setGridProps({ ...gridProps, gridData: [], count: 0 }) + setGridCount(0) + } + }) + } + + //최근 등록일 수정일 정렬 이벤트 + const onChangeSortType = (e) => { + stuffSearchParams.schSortType = e.target.value + console.log('셋팅된 검색조건:::', stuffSearchParams) + setDefaultSortType(e.target.value) + setStuffSearch({ + ...stuffSearch, + code: 'S', + schSortType: e.target.value, + }) + const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + // console.log('apiUrl::', apiUrl) + get({ url: apiUrl }).then((res) => { + console.log('정렬바꿨을때 조회 ::::::::::', res) + if (!isEmptyArray(res)) { + setGridProps({ ...gridProps, gridData: res, count: res.length }) + setGridCount(res.length) + } else { + setGridProps({ ...gridProps, gridData: [], count: 0 }) + setGridCount(0) + } + }) + } return ( <>
    @@ -328,6 +365,15 @@ export default function Stuff() { 전체 : {gridCount} // 선택 : {selectedRowDataCount} + +
    {/*
    {!isFormValid ? ( <> - {/* */} - + ) : ( - + )} - + )) || ( -
    - 상세::::::::::: - - - -
    + <> + {objectNo.substring(0, 1) === 'R' ? ( + <> + + + + + + + ) : ( + <> + + + + + + )} + + //
    + // EDIT모드 + + // {/* {objectNo.substring(0,1) ? 'R' ? <>RRRRRRR : <>TTTTTTTT} */} + // {/* + // + // + // + // */} + //
    )} {/*
    diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index f0d665d0..58aa4ce9 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -2,10 +2,12 @@ import React, { useEffect } from 'react' import { useState } from 'react' -import { Input, RadioGroup, Radio, Button } from '@nextui-org/react' +import { Input, RadioGroup, Radio, Button, Autocomplete, AutocompleteItem } from '@nextui-org/react' import RangeDatePicker from '@/components/common/datepicker/RangeDatePicker' import { useRecoilState, useResetRecoilState } from 'recoil' import { stuffSearchState } from '@/store/stuffAtom' +import { isEmptyArray } from '@/util/common-utils' +import { get } from '@/lib/Axios' import dayjs from 'dayjs' import isLeapYear from 'dayjs/plugin/isLeapYear' // 윤년 판단 플러그인 dayjs.extend(isLeapYear) @@ -33,13 +35,16 @@ export default function StuffSearchCondition() { const [receiveUser, setReceiveUser] = useState('') //담당자 const [dispCompanyName, setDispCompanyName] = useState('') //견적처 const [dateType, setDateType] = useState('U') //갱신일(U)/등록일(R) + const [schSelSaleStoreId, setSchSelSaleStoreId] = useState('') //판매대리점 선택 + const [schSelSaleStoreList, setSchSelSaleStoreList] = useState([]) //판매대리점 자동완성 SELECT // 조회 const onSubmit = () => { let diff = dayjs(endRangeDate).diff(startRangeDate, 'day') if (diff > 366) { return alert('최대1년 조회 가능합니다.') } + setStuffSearch({ schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo, schSaleStoreId: stuffSearch?.schSaleStoreId ? stuffSearch.schSaleStoreId : saleStoreId, @@ -53,6 +58,10 @@ export default function StuffSearchCondition() { schFromDt: dayjs(startRangeDate).format('YYYY-MM-DD'), schToDt: dayjs(endRangeDate).format('YYYY-MM-DD'), code: 'E', + schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : schSelSaleStoreId, + startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1, + endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100, + schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R', }) } @@ -68,9 +77,31 @@ export default function StuffSearchCondition() { setDispCompanyName('') setDateType('U') setDateRange([dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), dayjs(new Date()).format('YYYY-MM-DD')]) + setSchSelSaleStoreId('') resetStuffRecoil() } + useEffect(() => { + get({ url: `/api/object/saleStore/201TES01/list` }).then((res) => { + if (!isEmptyArray(res)) { + // console.log('판매점 결과:::::', res) + setSchSelSaleStoreList(res) + } + }) + }, []) + + //판매대리점 자동완성 변경 + const onSelectionChange = (key) => { + // console.log('자동완성값변경', key) + if (key == null) { + setSchSelSaleStoreId('') + setStuffSearch({ ...stuffSearch, schSelSaleStoreId: '' }) + } else { + setSchSelSaleStoreId(key) + setStuffSearch({ ...stuffSearch, schSelSaleStoreId: key }) + } + } + //x로 날짜 비웠을때 기본값으로 셋팅 useEffect(() => { if (!startRangeDate && !endRangeDate) { @@ -88,7 +119,7 @@ export default function StuffSearchCondition() { return ( <>
    - +
    @@ -220,6 +251,17 @@ export default function StuffSearchCondition() { setStuffSearch({ ...stuffSearch, code: 'S', schDispCompanyName: e.target.value }) }} /> + {schSelSaleStoreList?.length > 0 && ( + + {(option) => {option.saleStoreName}} + + )}
    ) } else { diff --git a/src/locales/ko.json b/src/locales/ko.json index cf7d758f..82b187bc 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -118,7 +118,7 @@ "common.message.multi.insert": "Total {0} cases ({1} successes, {2} failures {3})", "common.message.error": "Error occurred, please contact site administrator.", "common.message.data.save": "Do you want to save it?", - "common.message.data.delete": "Do you want to delete it?", + "common.message.data.delete": "정말로 삭제하시겠습니까?", "common.message.data.exists": "{0} is data that already exists.", "common.message.data.no.exists": "{0} is data that does not exist.", "common.message.all": "All", diff --git a/src/store/stuffAtom.js b/src/store/stuffAtom.js index a122543c..5de2c04e 100644 --- a/src/store/stuffAtom.js +++ b/src/store/stuffAtom.js @@ -17,6 +17,10 @@ export const stuffSearchState = atom({ schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), //시작일 schToDt: dayjs(new Date()).format('YYYY-MM-DD'), //종료일 code: 'S', + schSelSaleStoreId: '', //판매대리점 선택 + startRow: 1, + endRow: 100, + schSortType: 'R', //정렬조건 (R:최근등록일 U:최근수정일) }, dangerouslyAllowMutability: true, }) From 06a2e595f5df258b7884bb08c1ab13fac588e476 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Thu, 12 Sep 2024 17:56:33 +0900 Subject: [PATCH 14/23] =?UTF-8?q?=EB=94=94=EC=8A=A4=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=20=EC=84=A4=EC=A0=95=20=EC=A1=B0=ED=9A=8C/=EB=93=B1?= =?UTF-8?q?=EB=A1=9D/=EC=88=98=EC=A0=95=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 53 ++++++++++++++++++- .../modal/setting01/FirstOption.jsx | 51 ++++++++++++++++++ src/store/settingAtom.js | 28 +++++----- 3 files changed, 117 insertions(+), 15 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 45896d96..47b1ec88 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -3,10 +3,13 @@ import { useState } from 'react' import MenuDepth01 from './MenuDepth01' import { useRecoilState } from 'recoil' import { modalState } from '@/store/modalAtom' +import { settingModalFirstOptionsState } from '@/store/settingAtom' import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' +import { post } from '@/lib/Axios' export default function CanvasMenu() { + const [objectNo, setObjectNo] = useState('test123240912001') const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state const [menuNumber, setMenuNumber] = useState(null) const [vertical, setVertical] = useState(true) @@ -18,6 +21,54 @@ export default function CanvasMenu() { setMenuNumber(null) } } + + const settingsModalOptions = useRecoilState(settingModalFirstOptionsState) + + // 저장버튼(btn08) 클릭 시 호출되는 함수 + const handleSaveSettings = async () => { + try { + // 서버에 전송할 데이터 + const dataToSend = { + option1: settingsModalOptions[0].option1.map((item) => ({ + column: item.column, + selected: item.selected, + })), + option2: settingsModalOptions[0].option2.map((item) => ({ + column: item.column, + selected: item.selected, + })), + } + + const patternData = { + objectNo, + assignDisplay: dataToSend.option1[0].selected, + drawDisplay: dataToSend.option1[1].selected, + gridDisplay: dataToSend.option1[2].selected, + charDisplay: dataToSend.option1[3].selected, + flowDisplay: dataToSend.option1[4].selected, + hallwayDimenDisplay: dataToSend.option1[5].selected, + actualDimenDisplay: dataToSend.option1[6].selected, + noDimenDisplay: dataToSend.option1[7].selected, + trestleDisplay: dataToSend.option1[8].selected, + coordiDisplay: dataToSend.option1[9].selected, + drawConverDisplay: dataToSend.option1[10].selected, + onlyBorder: dataToSend.option2[0].selected, + lineHatch: dataToSend.option2[1].selected, + allPainted: dataToSend.option2[2].selected, + } + + // HTTP POST 요청 보내기 + const response = await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) + + // 응답 처리 + console.log('서버 응답:', response.data) + alert('설정이 저장되었습니다.') + } catch (error) { + console.error('설정을 저장하는 동안 오류가 발생했습니다:', error) + alert('설정을 저장하는 중 오류가 발생했습니다.') + } + } + return (
    @@ -98,7 +149,7 @@ export default function CanvasMenu() {
    - +
    diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index cddab6c0..8489d1a5 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -1,8 +1,11 @@ import { useRecoilState } from 'recoil' import { settingModalFirstOptionsState } from '@/store/settingAtom' import { useMessage } from '@/hooks/useMessage' +import React, { useEffect, useState } from 'react' +import { get } from '@/lib/Axios' export default function FirstOption() { + const [objectNo, setObjectNo] = useState('test123240912001') const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalFirstOptionsState) const { option1, option2 } = settingsModalOptions const { getMessage } = useMessage() @@ -12,6 +15,54 @@ export default function FirstOption() { setSettingModalOptions({ option1, option2 }) } + // 초기 조회 + useEffect(() => { + // Canvas Setting 조회 및 초기화 + const fetchSettings = async () => { + try { + const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` }) + + // console.log(res) + + const data = { + option1: [ + { id: 1, column: 'assignDisplay', name: 'modal.canvas.setting.first.option.alloc', selected: res.assignDisplay }, + { id: 2, column: 'drawDisplay', name: 'modal.canvas.setting.first.option.outline', selected: res.drawDisplay }, + { id: 3, column: 'gridDisplay', name: 'modal.canvas.setting.first.option.plan', selected: res.gridDisplay }, + { id: 4, column: 'charDisplay', name: 'modal.canvas.setting.first.option.roof.line', selected: res.charDisplay }, + { id: 5, column: 'flowDisplay', name: 'modal.canvas.setting.first.option.grid', selected: res.flowDisplay }, + { id: 6, column: 'hallwayDimenDisplay', name: 'modal.canvas.setting.first.option.circuit.num', selected: res.hallwayDimenDisplay }, + { id: 7, column: 'actualDimenDisplay', name: 'modal.canvas.setting.first.option.word', selected: res.actualDimenDisplay }, + { id: 8, column: 'noDimenDisplay', name: 'modal.canvas.setting.first.option.trestle', selected: res.noDimenDisplay }, + { id: 9, column: 'trestleDisplay', name: 'modal.canvas.setting.first.option.flow', selected: res.trestleDisplay }, + { id: 10, column: 'coordiDisplay', name: 'modal.canvas.setting.first.option.total', selected: res.coordiDisplay }, + { id: 11, column: 'drawConverDisplay', name: 'modal.canvas.setting.first.option.corridor.dimension', selected: res.drawConverDisplay }, + ], + option2: [ + { id: 1, column: 'onlyBorder', name: 'modal.canvas.setting.first.option.border', selected: res.onlyBorder }, + { id: 2, column: 'lineHatch', name: 'modal.canvas.setting.first.option.line', selected: res.lineHatch }, + { id: 3, column: 'allPainted', name: 'modal.canvas.setting.first.option.all', selected: res.allPainted }, + ], + + //rangeSetting: res.adsorpRangeSetting, + //gridSettings: [res.randomGrid, res.solidGrid, res.dotGrid, res.gridColorSet, res.adsorpPointAdd], + } + + // 데이터 설정 + setSettingModalOptions({ + option1: data.option1, + option2: data.option2, + // rangeSetting: data.rangeSetting, + // gridSettings: data.gridSettings, + }) + } catch (error) { + console.error('Data fetching error:', error) + } + } + + fetchSettings() + }, []) + return ( <>
    diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js index 2899dd4e..26afc275 100644 --- a/src/store/settingAtom.js +++ b/src/store/settingAtom.js @@ -4,22 +4,22 @@ export const settingModalFirstOptionsState = atom({ key: 'settingModalFirstOptions', default: { option1: [ - { id: 1, name: 'modal.canvas.setting.first.option.alloc', selected: false }, - { id: 2, name: 'modal.canvas.setting.first.option.outline', selected: false }, - { id: 3, name: 'modal.canvas.setting.first.option.plan', selected: false }, - { id: 4, name: 'modal.canvas.setting.first.option.roof.line', selected: false }, - { id: 5, name: 'modal.canvas.setting.first.option.grid', selected: false }, - { id: 6, name: 'modal.canvas.setting.first.option.circuit.num', selected: false }, - { id: 7, name: 'modal.canvas.setting.first.option.word', selected: false }, - { id: 8, name: 'modal.canvas.setting.first.option.trestle', selected: false }, - { id: 9, name: 'modal.canvas.setting.first.option.flow', selected: false }, - { id: 10, name: 'modal.canvas.setting.first.option.total', selected: false }, - { id: 11, name: 'modal.canvas.setting.first.option.corridor.dimension', selected: false }, + { id: 1, column: 'assignDisplay', name: 'modal.canvas.setting.first.option.alloc', selected: false }, + { id: 2, column: 'drawDisplay', name: 'modal.canvas.setting.first.option.outline', selected: false }, + { id: 3, column: 'gridDisplay', name: 'modal.canvas.setting.first.option.plan', selected: false }, + { id: 4, column: 'charDisplay', name: 'modal.canvas.setting.first.option.roof.line', selected: false }, + { id: 5, column: 'flowDisplay', name: 'modal.canvas.setting.first.option.grid', selected: false }, + { id: 6, column: 'hallwayDimenDisplay', name: 'modal.canvas.setting.first.option.circuit.num', selected: false }, + { id: 7, column: 'actualDimenDisplay', name: 'modal.canvas.setting.first.option.word', selected: false }, + { id: 8, column: 'noDimenDisplay', name: 'modal.canvas.setting.first.option.trestle', selected: false }, + { id: 9, column: 'trestleDisplay', name: 'modal.canvas.setting.first.option.flow', selected: false }, + { id: 10, column: 'coordiDisplay', name: 'modal.canvas.setting.first.option.total', selected: false }, + { id: 11, column: 'drawConverDisplay', name: 'modal.canvas.setting.first.option.corridor.dimension', selected: false }, ], option2: [ - { id: 1, name: 'modal.canvas.setting.first.option.border', selected: false }, - { id: 2, name: 'modal.canvas.setting.first.option.line', selected: false }, - { id: 3, name: 'modal.canvas.setting.first.option.all', selected: false }, + { id: 1, column: 'onlyBorder', name: 'modal.canvas.setting.first.option.border', selected: false }, + { id: 2, column: 'lineHatch', name: 'modal.canvas.setting.first.option.line', selected: false }, + { id: 3, column: 'allPainted', name: 'modal.canvas.setting.first.option.all', selected: false }, ], }, dangerouslyAllowMutability: true, From c06216bdb20807189e471916472e2e07305fa5f5 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 13 Sep 2024 09:53:57 +0900 Subject: [PATCH 15/23] =?UTF-8?q?=EC=99=B8=EB=B2=BD=EC=84=A0=20=ED=99=95?= =?UTF-8?q?=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/outerlinesetting/OuterLineWall.jsx | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index c5bd5686..b743b6fe 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -99,15 +99,16 @@ export default function OuterLineWall() { if (idx === 0) { return } - drawLine(points[idx - 1], point) + drawLine(points[idx - 1], point, idx) }) } }, [points]) - const drawLine = (point1, point2) => { + const drawLine = (point1, point2, idx) => { const line = new QLine([point1.x, point1.y, point2.x, point2.y], { stroke: 'black', strokeWidth: 1, + idx: idx, selectable: false, name: 'outerLine', }) @@ -120,7 +121,6 @@ export default function OuterLineWall() { const checkRightAngle = () => { const length1Num = Number(length1Ref.current.value) / 10 const length2Num = Number(length2Ref.current.value) / 10 - console.log(length1Num, length2Num, arrow1Ref.current, arrow2Ref.current) if (points.length === 0) { return @@ -258,6 +258,7 @@ export default function OuterLineWall() { if (activeElem === length1Ref.current) { setArrow1('↓') arrow1Ref.current = '↓' + length2Ref.current.focus() } else if (activeElem === length2Ref.current) { if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') { break @@ -274,6 +275,7 @@ export default function OuterLineWall() { if (activeElem === length1Ref.current) { setArrow1('↑') arrow1Ref.current = '↑' + length2Ref.current.focus() } else if (activeElem === length2Ref.current) { if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') { break @@ -289,6 +291,7 @@ export default function OuterLineWall() { if (activeElem === length1Ref.current) { setArrow1('←') arrow1Ref.current = '←' + length2Ref.current.focus() } else if (activeElem === length2Ref.current) { if (arrow1Ref.current === '←' || arrow1Ref.current === '→') { break @@ -304,6 +307,7 @@ export default function OuterLineWall() { if (activeElem === length1Ref.current) { setArrow1('→') arrow1Ref.current = '→' + length2Ref.current.focus() } else if (activeElem === length2Ref.current) { if (arrow1Ref.current === '←' || arrow1Ref.current === '→') { break @@ -316,6 +320,15 @@ export default function OuterLineWall() { break } }, + leeGubae: (e) => { + console.log('leegubae') + }, + angle: (e) => { + console.log('angle') + }, + diagonalLine: (e) => { + console.log('diagonalLine') + }, } /** @@ -330,7 +343,14 @@ export default function OuterLineWall() { setModalOption({ ...modalOption, outerwall: false }) } - const handleFix = () => {} + const handleFix = () => { + setPoints((prev) => { + if (prev.length === 0) { + return [] + } + return [...prev, { x: prev[0].x, y: prev[0].y }] + }) + } return (
    From ff564e73e51dbf3f68643c54fd67c6be6a0ec6e5 Mon Sep 17 00:00:00 2001 From: minsik Date: Fri, 13 Sep 2024 10:03:58 +0900 Subject: [PATCH 16/23] =?UTF-8?q?-=20Canvas=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 15 ++- src/components/floor-plan/MenuDepth01.jsx | 27 ++++- src/components/header/Header.jsx | 128 +++++++++++----------- src/locales/ja.json | 14 ++- src/locales/ko.json | 12 +- 5 files changed, 114 insertions(+), 82 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 6c53e9ba..2a8bde0d 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -1,5 +1,5 @@ 'use client' -import { useState } from 'react' +import { useEffect, useState } from 'react' import MenuDepth01 from './MenuDepth01' import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' @@ -8,14 +8,21 @@ export default function CanvasMenu(props) { const { setShowCanvasSettingModal, showOutlineModal, setShowOutlineModal } = props const [menuNumber, setMenuNumber] = useState(null) const [vertical, setVertical] = useState(true) + const [type, setType] = useState('') const { getMessage } = useMessage() const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] const onClickNav = (number) => { setMenuNumber(number) + if (number === 2) setType('outline') + if (number === 3) setType('surface') + if (number === 4) setType('module') } const menuProps = { setShowOutlineModal, + type, } + useEffect(() => {}, [menuNumber, type]) + return (
    @@ -42,7 +49,7 @@ export default function CanvasMenu(props) { >
  • onClickNav(3)}> @@ -143,8 +150,8 @@ export default function CanvasMenu(props) {
  • {menuNumber === 2 && } - {menuNumber === 3 && } - {menuNumber === 4 && } + {menuNumber === 3 && } + {menuNumber === 4 && }
    ) diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index 170fd820..1015abd1 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -5,7 +5,7 @@ import { useMessage } from '@/hooks/useMessage' import { useEffect, useState } from 'react' export default function MenuDepth01(props) { - const { setShowOutlineModal } = props + const { setShowOutlineModal, type } = props const { getMessage } = useMessage() const [activeMenu, setActiveMenu] = useState(0) const onClickMenu = (menuNum) => { @@ -23,6 +23,27 @@ export default function MenuDepth01(props) { { id: 6, name: '特殊コーナー形状' }, ] + const menuInfo = { + outline: [ + // 지붕덮개 + { id: 0, name: 'plan.menu.roof.cover.outline.drawing' }, + { id: 1, name: 'plan.menu.roof.cover.roof.shape.setting' }, + { id: 2, name: 'plan.menu.roof.cover.roof.shape.edit' }, + { id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing' }, + ], + surface: [ + // 배치면 + { id: 0, name: 'plan.menu.placement.surface.drawing' }, + { id: 1, name: 'plan.menu.placement.surface.surface' }, + { id: 2, name: 'plan.menu.placement.surface.object' }, + ], + module: [ + // 모듈, 회로 구성 + { id: 0, name: 'plan.menu.module.circuit.setting.default' }, + { id: 1, name: 'plan.menu.module.circuit.setting.circuit.trestle.setting' }, + ], + } + useEffect(() => { menus.forEach((menu) => { menu.isActive = menu.id === activeMenu @@ -31,10 +52,10 @@ export default function MenuDepth01(props) { return (
      - {menus.map((menu) => { + {menuInfo[type].map((menu) => { return (
    • - +
    • ) })} diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 5f90a132..ca5aa2da 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -3,6 +3,8 @@ import Link from 'next/link' import { usePathname } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' import QSelectBox from '@/components/common/select/QSelectBox' +import React from 'react' +import { logout } from '@/lib/authActions' export const ToggleonMouse = (e, act, target) => { const listWrap = e.target.closest(target) @@ -21,15 +23,74 @@ export const ToggleonMouse = (e, act, target) => { export default function Header(props) { const { loginedUserNm } = props - // console.log('loginedUserNm:', loginedUserNm) const { getMessage } = useMessage() const pathName = usePathname() + if (pathName.includes('login') || pathName.includes('join')) { return null } const SelectOption = [{ name: 'オンライン保証シ' }, { name: 'ステム' }] const onLogout = () => { - // logout() + logout() + } + const menus = [ + { name: 'header.menus.home', url: '/', children: [] }, + { + name: 'header.menus.management', + url: '', + children: [ + { name: 'header.menus.management.stuff', url: '/management/stuff', children: [] }, + { name: 'header.menus.management.plan', url: '/floor-plan', children: [] }, + ], + }, + { + name: 'header.menus.community', + url: '', + children: [ + { name: 'header.menus.community.notice', url: '/community/notice', children: [] }, + { name: 'header.menus.community.faq', url: '/community/faq', children: [] }, + { name: 'header.menus.community.archive', url: '/community/archive', children: [] }, + ], + }, + ] + + const getMenuTemplate = (menus) => { + return menus.map((menu) => { + return ( +
    • ToggleonMouse(e, 'add', 'nav > ul')} + onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')} + > + {menu.children.length === 0 ? ( + + {getMessage(menu.name)} + + ) : ( + + +
        + {menu.children.map((m) => { + return ( +
      • ToggleonMouse(e, 'add', 'li > ul')} + onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} + > + + {getMessage(m.name)} + +
      • + ) + })} +
      +
      + )} +
    • + ) + }) } return ( @@ -40,68 +101,7 @@ export default function Header(props) {
    diff --git a/src/locales/ja.json b/src/locales/ja.json index f4132734..12ef2163 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -15,8 +15,12 @@ "header.stem": "ステム", "plan.menu.plan.drawing": "도면작성", "plan.menu.placement.surface.initial.setting": "配置面 初期設定", - "plan.menu.root.cover": "지붕덮개", - "plan.menu.root.cover.outline.drawing": "外壁線を描", + "plan.menu.roof.cover": "지붕덮개", + "plan.menu.roof.cover.outline.drawing": "外壁線を描", + "plan.menu.roof.cover.roof.shape.setting": "屋根形状設定", + "plan.menu.roof.cover.roof.shape.edit": "지붕형상 편집", + "plan.menu.roof.cover.auxiliary.line.drawing": "補助線を描", + "plan.menu.roof.cover.roof.surface.alloc": "지붕면 할당", "modal.cover.outline.drawing": "外壁線を描", "modal.cover.outline": "外壁線", "modal.cover.outline.right.angle": "直角", @@ -30,9 +34,9 @@ "modal.cover.outline.rollback": "一変戦に戻る", "modal.cover.outline.remove": "外壁の削除", "modal.cover.outline.select.move": "外壁の選択、移動", - "plan.menu.root.cover.roof.setting": "屋根形状設定", - "plan.menu.root.cover.roof.edit": "지붕형상 편집", - "plan.menu.root.cover.sub.line": "補助線を描", + "plan.menu.roof.cover.roof.setting": "屋根形状設定", + "plan.menu.roof.cover.roof.edit": "지붕형상 편집", + "plan.menu.roof.cover.sub.line": "補助線を描", "plan.menu.placement.surface": "配置面", "plan.menu.placement.surface.drawing": "배치면 그리기", "plan.menu.placement.surface.surface": "면형상 배치", diff --git a/src/locales/ko.json b/src/locales/ko.json index bb7451d3..d65eea13 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -15,9 +15,12 @@ "header.stem": "Stem", "plan.menu.plan.drawing": "도면작성", "plan.menu.placement.surface.initial.setting": "배치면 초기 설정", - "plan.menu.root.cover": "지붕덮개", - "plan.menu.root.cover.outline.drawing": "외벽선 그리기", - "plan.menu.root.cover.auxiliary.line.drawing": "보조선 그리기", + "plan.menu.roof.cover": "지붕덮개", + "plan.menu.roof.cover.outline.drawing": "외벽선 그리기", + "plan.menu.roof.cover.roof.shape.setting": "지붕형상 설정", + "plan.menu.roof.cover.roof.shape.edit": "지붕형상 편집", + "plan.menu.roof.cover.auxiliary.line.drawing": "보조선 그리기", + "plan.menu.roof.cover.roof.surface.alloc": "지붕면 할당", "modal.cover.outline.drawing": "외벽선 작성", "modal.cover.outline": "외벽선", "modal.cover.outline.right.angle": "직각", @@ -31,9 +34,6 @@ "modal.cover.outline.rollback": "일변전으로 돌아가기", "modal.cover.outline.remove": "외벽 제거", "modal.cover.outline.select.move": "외벽 선택, 이동", - "plan.menu.root.cover.roof.setting": "지붕형상 설정", - "plan.menu.root.cover.roof.edit": "지붕형상 편집", - "plan.menu.root.cover.sub.line": "보조선 그리기", "plan.menu.placement.surface": "배치면", "plan.menu.placement.surface.drawing": "배치면 그리기", "plan.menu.placement.surface.surface": "면형상 배치", From fda37ff58a14b2304393c955c4b3e790e32fd98b Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 13 Sep 2024 13:00:51 +0900 Subject: [PATCH 17/23] refactor: Refactoring router structure --- src/app/QcastProvider.js | 35 +++++++ src/app/[locale]/page.js | 6 +- src/app/community/archive/page.jsx | 16 +++ src/app/community/faq/page.jsx | 16 +++ src/app/community/notice/page.jsx | 16 +++ src/app/floor-plan/page.jsx | 9 ++ src/app/initSettingsModal/page.jsx | 16 +++ src/app/intro/page.jsx | 14 +++ src/app/join/complete/page.jsx | 19 ++++ src/app/join/page.jsx | 5 + src/app/layout.js | 18 +++- src/app/login/page.jsx | 9 ++ src/app/management/plan/page.jsx | 16 +++ src/app/management/stuff/detail/page.jsx | 15 +++ src/app/management/stuff/page.jsx | 21 ++++ src/app/master/company/page.jsx | 16 +++ src/app/master/price/page.jsx | 16 +++ src/app/page.js | 17 ++- src/app/playground/page.jsx | 17 +++ src/app/roof/page.jsx | 16 +++ src/app/roof2/RoofSelect.jsx | 128 +++++++++++++++++++++++ src/app/roof2/page.jsx | 26 +++++ src/app/settings/page.jsx | 16 +++ src/components/auth/Login.jsx | 6 +- src/components/header/Header.jsx | 97 +++++++++-------- src/components/ui/Loading.jsx | 5 + src/components/ui/Loading.module.css | 35 +++++++ src/hooks/useAxios.js | 6 +- src/lib/authActions.js | 7 +- src/middleware.js | 36 +++---- 30 files changed, 592 insertions(+), 83 deletions(-) create mode 100644 src/app/QcastProvider.js create mode 100644 src/app/community/archive/page.jsx create mode 100644 src/app/community/faq/page.jsx create mode 100644 src/app/community/notice/page.jsx create mode 100644 src/app/floor-plan/page.jsx create mode 100644 src/app/initSettingsModal/page.jsx create mode 100644 src/app/intro/page.jsx create mode 100644 src/app/join/complete/page.jsx create mode 100644 src/app/join/page.jsx create mode 100644 src/app/login/page.jsx create mode 100644 src/app/management/plan/page.jsx create mode 100644 src/app/management/stuff/detail/page.jsx create mode 100644 src/app/management/stuff/page.jsx create mode 100644 src/app/master/company/page.jsx create mode 100644 src/app/master/price/page.jsx create mode 100644 src/app/playground/page.jsx create mode 100644 src/app/roof/page.jsx create mode 100644 src/app/roof2/RoofSelect.jsx create mode 100644 src/app/roof2/page.jsx create mode 100644 src/app/settings/page.jsx create mode 100644 src/components/ui/Loading.jsx create mode 100644 src/components/ui/Loading.module.css diff --git a/src/app/QcastProvider.js b/src/app/QcastProvider.js new file mode 100644 index 00000000..f9431eb6 --- /dev/null +++ b/src/app/QcastProvider.js @@ -0,0 +1,35 @@ +'use client' + +import { useEffect } from 'react' +import { useRecoilState, useRecoilValue } from 'recoil' +import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' +import { ErrorBoundary } from 'next/dist/client/components/error-boundary' +import ServerError from './error' + +import '@/styles/common.scss' + +import KO from '@/locales/ko.json' +import JA from '@/locales/ja.json' + +export const QcastProvider = ({ children }) => { + const globalLocale = useRecoilValue(globalLocaleStore) + const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore) + + useEffect(() => { + console.log(sessionStorage.getItem('hi')) + console.log(Object.keys(appMessageState).length) + // if (Object.keys(appMessageState).length === 0) { + if (globalLocale === 'ko') { + setAppMessageState(KO) + } else { + setAppMessageState(JA) + } + // } + }, [globalLocale]) + + return ( + <> + }>{children} + + ) +} diff --git a/src/app/[locale]/page.js b/src/app/[locale]/page.js index aa5d3f7e..1b8f2258 100644 --- a/src/app/[locale]/page.js +++ b/src/app/[locale]/page.js @@ -1,10 +1,8 @@ -// import { getCurrentLocale } from '@/locales/server' +import { getSession } from '@/lib/authActions' import MainPage from '@/components/Main' export default async function page() { - // const session = await getSession() - - // const currentLocale = getCurrentLocale() + const session = await getSession() const mainPageProps = { isLoggedIn: session?.isLoggedIn, diff --git a/src/app/community/archive/page.jsx b/src/app/community/archive/page.jsx new file mode 100644 index 00000000..6917f228 --- /dev/null +++ b/src/app/community/archive/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Archive from '@/components/community/Archive' +import { initCheck } from '@/util/session-util' + +export default async function CommunityArchivePage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/community/faq/page.jsx b/src/app/community/faq/page.jsx new file mode 100644 index 00000000..2b9d5452 --- /dev/null +++ b/src/app/community/faq/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Faq from '@/components/community/Faq' +import { initCheck } from '@/util/session-util' + +export default async function CommunityFaqPage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/community/notice/page.jsx b/src/app/community/notice/page.jsx new file mode 100644 index 00000000..d2157b20 --- /dev/null +++ b/src/app/community/notice/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Notice from '@/components/community/Notice' +import { initCheck } from '@/util/session-util' + +export default async function CommunityNoticePage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/floor-plan/page.jsx b/src/app/floor-plan/page.jsx new file mode 100644 index 00000000..f503099e --- /dev/null +++ b/src/app/floor-plan/page.jsx @@ -0,0 +1,9 @@ +import FloorPlan from '@/components/floor-plan/FloorPlan' + +export default function FloorPlanPage() { + return ( + <> + + + ) +} diff --git a/src/app/initSettingsModal/page.jsx b/src/app/initSettingsModal/page.jsx new file mode 100644 index 00000000..a081ef47 --- /dev/null +++ b/src/app/initSettingsModal/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import InitSettingsModal from '@/components/InitSettingsModal' +import { initCheck } from '@/util/session-util' + +export default async function InitSettingsModalPage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/intro/page.jsx b/src/app/intro/page.jsx new file mode 100644 index 00000000..8d560ce5 --- /dev/null +++ b/src/app/intro/page.jsx @@ -0,0 +1,14 @@ +import Intro from '@/components/Intro' +import { initCheck } from '@/util/session-util' + +export default async function IntroPage() { + await initCheck() + + return ( + <> +
    + +
    + + ) +} diff --git a/src/app/join/complete/page.jsx b/src/app/join/complete/page.jsx new file mode 100644 index 00000000..3f9fc462 --- /dev/null +++ b/src/app/join/complete/page.jsx @@ -0,0 +1,19 @@ +'use client' + +import { useMessage } from '@/hooks/useMessage' + +export default function CompletePage() { + const { getMessage } = useMessage() + + return ( + <> +
    +

    {getMessage('join.complete.title')}

    +
    {getMessage('join.complete.contents')}
    +
    + {getMessage('join.complete.email_comment')} : {getMessage('join.complete.email')} +
    +
    + + ) +} diff --git a/src/app/join/page.jsx b/src/app/join/page.jsx new file mode 100644 index 00000000..118a25b4 --- /dev/null +++ b/src/app/join/page.jsx @@ -0,0 +1,5 @@ +import Join from '@/components/auth/Join' + +export default function JoinPage() { + return <>{} +} diff --git a/src/app/layout.js b/src/app/layout.js index 640dbe11..c3ac72de 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -1,6 +1,8 @@ import { Inter } from 'next/font/google' -import { checkSession, getSession } from '@/lib/authActions' +import { headers } from 'next/headers' +import { redirect } from 'next/navigation' +import { getSession } from '@/lib/authActions' import RecoilRootWrapper from './RecoilWrapper' import UIProvider from './UIProvider' @@ -11,6 +13,7 @@ import QModal from '@/components/common/modal/QModal' import './globals.css' import '../styles/style.scss' +import { QcastProvider } from './QcastProvider' const inter = Inter({ subsets: ['latin'] }) @@ -20,9 +23,16 @@ export const metadata = { } export default async function RootLayout({ children }) { - await checkSession() + const headersList = headers() + const headerPathname = headersList.get('x-pathname') || '' + + // console.log('headerPathname:', headerPathname) + // const isLoggedIn = await checkSession() const session = await getSession() console.log('session[layout]:', session) + if (!headerPathname.includes('/login') && !session.isLoggedIn) { + redirect('/login') + } return ( @@ -32,7 +42,9 @@ export default async function RootLayout({ children }) {
    - {children} + + {children} +
    diff --git a/src/app/login/page.jsx b/src/app/login/page.jsx new file mode 100644 index 00000000..0686da2e --- /dev/null +++ b/src/app/login/page.jsx @@ -0,0 +1,9 @@ +import Login from '@/components/auth/Login' + +export default function LoginPage() { + return ( + <> + + + ) +} diff --git a/src/app/management/plan/page.jsx b/src/app/management/plan/page.jsx new file mode 100644 index 00000000..5fefa62a --- /dev/null +++ b/src/app/management/plan/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Plan from '@/components/management/Plan' +import { initCheck } from '@/util/session-util' + +export default async function ManagementPlanPage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/management/stuff/detail/page.jsx b/src/app/management/stuff/detail/page.jsx new file mode 100644 index 00000000..8b84287a --- /dev/null +++ b/src/app/management/stuff/detail/page.jsx @@ -0,0 +1,15 @@ +import React from 'react' +import Hero from '@/components/Hero' +import StuffDetail from '@/components/management/StuffDetail' +export default function ManagementStuffDetailPage() { + return ( + <> +
    +

    물건정보

    +
    +
    + +
    + + ) +} diff --git a/src/app/management/stuff/page.jsx b/src/app/management/stuff/page.jsx new file mode 100644 index 00000000..7590a7cf --- /dev/null +++ b/src/app/management/stuff/page.jsx @@ -0,0 +1,21 @@ +import StuffSearchCondition from '@/components/management/StuffSearchCondition' +import Stuff from '@/components/management/Stuff' +import { initCheck } from '@/util/session-util' +import Hero from '@/components/Hero' +export default async function ManagementStuffPage() { + await initCheck() + + return ( + <> + +
    +
    + +
    +
    +
    + +
    + + ) +} diff --git a/src/app/master/company/page.jsx b/src/app/master/company/page.jsx new file mode 100644 index 00000000..15eda41c --- /dev/null +++ b/src/app/master/company/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Company from '@/components/master/Company' +import { initCheck } from '@/util/session-util' + +export default async function MasterCompanyPage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/master/price/page.jsx b/src/app/master/price/page.jsx new file mode 100644 index 00000000..a641d6bb --- /dev/null +++ b/src/app/master/price/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Price from '@/components/master/Price' +import { initCheck } from '@/util/session-util' + +export default async function MasterPricePage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/page.js b/src/app/page.js index 9c905040..25cd8640 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -1,5 +1,16 @@ -import Main from '@/components/Main' +import MainPage from '@/components/Main' +import { getSession } from '@/lib/authActions' -export default function Home() { - return
    +export default async function Home() { + const session = await getSession() + + const mainPageProps = { + isLoggedIn: session?.isLoggedIn, + } + + return ( + <> + + + ) } diff --git a/src/app/playground/page.jsx b/src/app/playground/page.jsx new file mode 100644 index 00000000..66d83c34 --- /dev/null +++ b/src/app/playground/page.jsx @@ -0,0 +1,17 @@ +import Playground from '@/components/Playground' +import { initCheck } from '@/util/session-util' + +export default async function PlaygroundPage() { + // const { session } = await checkSession() + + // if (!session.isLoggedIn) { + // redirect('/login') + // } + await initCheck() + + return ( + <> + + + ) +} diff --git a/src/app/roof/page.jsx b/src/app/roof/page.jsx new file mode 100644 index 00000000..f5b8e611 --- /dev/null +++ b/src/app/roof/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Roof from '@/components/Roof' +import { initCheck } from '@/util/session-util' + +export default async function RoofPage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/app/roof2/RoofSelect.jsx b/src/app/roof2/RoofSelect.jsx new file mode 100644 index 00000000..d759398b --- /dev/null +++ b/src/app/roof2/RoofSelect.jsx @@ -0,0 +1,128 @@ +'use client' + +import { Select, SelectItem } from '@nextui-org/react' +import { useEffect, useState } from 'react' +import { useAxios } from '@/hooks/useAxios' + +export default function RoofSelect() { + const [roofMaterials, setRoofMaterials] = useState([]) + const [manufacturers, setManufacturers] = useState([]) + const [trestles, setTrestles] = useState([]) + const [modules, setModules] = useState([]) + const [originTrestles, setOriginTrestles] = useState([]) + + const [roofMaterialId, setRoofMaterialId] = useState(null) + const [manufacturerId, setManufacturerId] = useState(null) + const [trestleId, setTrestleId] = useState(null) + + const { get } = useAxios() + + useEffect(() => { + get({ url: '/api/roof-material/roof-material-infos' }).then((res) => { + //TODO: error handling + if (!res) return + + setRoofMaterials(res) + }) + }, []) + + useEffect(() => { + if (!roofMaterialId) { + return + } + + get({ url: `/api/roof-material/roof-material-infos/${roofMaterialId}/trestles` }).then((res) => { + if (res.length === 0) { + return + } + setOriginTrestles(res) + const manufactural = res.map((trestle) => { + return { id: trestle.manufacturerId, name: trestle.manufacturerName } + }) + // Remove duplicates + const uniqueManufactural = Array.from(new Set(manufactural.map((a) => a.id))).map((id) => { + return manufactural.find((a) => a.id === id) + }) + + setManufacturers(uniqueManufactural) + }) + }, [roofMaterialId]) + + useEffect(() => { + if (!manufacturerId) { + return + } + + const trestles = originTrestles.filter((trestle) => trestle.manufacturerId === manufacturerId) + setTrestles(trestles) + }, [manufacturerId]) + + useEffect(() => { + if (!trestleId) { + return + } + get({ url: `/api/module/module-infos?roofMaterialId=${roofMaterialId}&trestleId=${trestleId}` }).then((res) => { + if (res.length === 0) { + return + } + setModules(res) + }) + }, [trestleId]) + + const handleRoofMaterialOnChange = (e) => { + const roofMaterialId = e.target.value + setRoofMaterialId(roofMaterialId) + setManufacturers([]) + setManufacturerId(null) + setTrestleId(null) + setTrestles([]) + setModules([]) + } + + const handleManufacturersOnChange = (e) => { + const manufacturerId = Number(e.target.value) + setTrestles([]) + setManufacturerId(manufacturerId) + setTrestleId(null) + setModules([]) + } + + const handleTrestlesOnChange = (e) => { + const trestleId = Number(e.target.value) + setTrestleId(trestleId) + setModules([]) + } + + return ( +
    + {roofMaterials.length > 0 && ( + + )} + {manufacturers.length > 0 && ( + + )} + {trestles.length > 0 && ( + + )} + {modules.length > 0 && ( + + )} +
    + ) +} diff --git a/src/app/roof2/page.jsx b/src/app/roof2/page.jsx new file mode 100644 index 00000000..72881d11 --- /dev/null +++ b/src/app/roof2/page.jsx @@ -0,0 +1,26 @@ +import Roof2 from '@/components/Roof2' +import RoofSelect from '@/app/[locale]/roof2/RoofSelect' +import { initCheck } from '@/util/session-util' + +export default async function Roof2Page() { + const session = await initCheck() + const roof2Props = { + name: session.name || '', + userId: session.userId || '', + email: session.email || '', + isLoggedIn: session.isLoggedIn, + } + + return ( + <> +
    +
    + +
    +
    +
    + +
    + + ) +} diff --git a/src/app/settings/page.jsx b/src/app/settings/page.jsx new file mode 100644 index 00000000..797c024c --- /dev/null +++ b/src/app/settings/page.jsx @@ -0,0 +1,16 @@ +import Hero from '@/components/Hero' +import Settings from '@/components/Settings' +import { initCheck } from '@/util/session-util' + +export default async function SettingsPage() { + await initCheck() + + return ( + <> + +
    + +
    + + ) +} diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index 44d163a0..326f5720 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -1,6 +1,7 @@ 'use client' -import { post, patch } from '@/lib/Axios' +import { useState } from 'react' +import { useAxios } from '@/hooks/useAxios' import { setSession } from '@/lib/authActions' import { redirect } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' @@ -9,9 +10,10 @@ import { Button, Switch } from '@nextui-org/react' import { useRecoilState } from 'recoil' import { globalLocaleStore } from '@/store/localeAtom' import { modalContent, modalState } from '@/store/modalAtom' -import { useState } from 'react' export default function Login(props) { + const { patch } = useAxios() + const { currentLocale } = props const { getMessage } = useMessage() const [globalLocaleState, setGlbalLocaleState] = useRecoilState(globalLocaleStore) diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index ca5aa2da..b716cbdd 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -1,11 +1,12 @@ 'use client' +import { Fragment } from 'react' import Link from 'next/link' -import { usePathname } from 'next/navigation' +import { usePathname, useRouter } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' -import QSelectBox from '@/components/common/select/QSelectBox' -import React from 'react' import { logout } from '@/lib/authActions' +import QSelectBox from '@/components/common/select/QSelectBox' + export const ToggleonMouse = (e, act, target) => { const listWrap = e.target.closest(target) const ListItem = Array.from(listWrap.childNodes) @@ -25,31 +26,29 @@ export default function Header(props) { const { loginedUserNm } = props const { getMessage } = useMessage() const pathName = usePathname() - - if (pathName.includes('login') || pathName.includes('join')) { - return null - } + // if (pathName.includes('login') || pathName.includes('join')) { + // return null + // } const SelectOption = [{ name: 'オンライン保証シ' }, { name: 'ステム' }] - const onLogout = () => { - logout() - } const menus = [ - { name: 'header.menus.home', url: '/', children: [] }, + { id: 0, name: 'header.menus.home', url: '/', children: [] }, { + id: 1, name: 'header.menus.management', url: '', children: [ - { name: 'header.menus.management.stuff', url: '/management/stuff', children: [] }, - { name: 'header.menus.management.plan', url: '/floor-plan', children: [] }, + { id: 3, name: 'header.menus.management.stuff', url: '/management/stuff', children: [] }, + { id: 4, name: 'header.menus.management.plan', url: '/floor-plan', children: [] }, ], }, { + id: 2, name: 'header.menus.community', url: '', children: [ - { name: 'header.menus.community.notice', url: '/community/notice', children: [] }, - { name: 'header.menus.community.faq', url: '/community/faq', children: [] }, - { name: 'header.menus.community.archive', url: '/community/archive', children: [] }, + { id: 5, name: 'header.menus.community.notice', url: '/community/notice', children: [] }, + { id: 6, name: 'header.menus.community.faq', url: '/community/faq', children: [] }, + { id: 7, name: 'header.menus.community.archive', url: '/community/archive', children: [] }, ], }, ] @@ -58,35 +57,33 @@ export default function Header(props) { return menus.map((menu) => { return (
  • ToggleonMouse(e, 'add', 'nav > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')} > {menu.children.length === 0 ? ( - + {getMessage(menu.name)} ) : ( - +
      {menu.children.map((m) => { return (
    • ToggleonMouse(e, 'add', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} > - - {getMessage(m.name)} - + {getMessage(m.name)}
    • ) })}
    -
    + )}
  • ) @@ -94,33 +91,35 @@ export default function Header(props) { } return ( -
    -
    -
    -

    - -

    - -
    -
    -
    - + !(pathName.includes('login') || pathName.includes('join')) && ( +
    +
    +
    +

    + +

    +
    -
    - -
    -
    - -
    -
    - +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    -
    -
    +
    + ) ) } diff --git a/src/components/ui/Loading.jsx b/src/components/ui/Loading.jsx new file mode 100644 index 00000000..59d2170b --- /dev/null +++ b/src/components/ui/Loading.jsx @@ -0,0 +1,5 @@ +import style from '@/components/ui/Loading.module.css' + +export default function Loading() { + return +} diff --git a/src/components/ui/Loading.module.css b/src/components/ui/Loading.module.css new file mode 100644 index 00000000..7b3001f8 --- /dev/null +++ b/src/components/ui/Loading.module.css @@ -0,0 +1,35 @@ +.loader { + position: relative; + font-size: 48px; + letter-spacing: 6px; +} +.loader:before { + content: 'Loading'; + color: #fff; +} +.loader:after { + content: ''; + width: 20px; + height: 20px; + background-color: #ff3d00; + background-image: radial-gradient(circle 2px, #fff4 100%, transparent 0), radial-gradient(circle 1px, #fff3 100%, transparent 0); + background-position: + 14px -4px, + 12px -1px; + border-radius: 50%; + position: absolute; + margin: auto; + top: -5px; + right: 66px; + transform-origin: center bottom; + animation: fillBaloon 1s ease-in-out infinite alternate; +} + +@keyframes fillBaloon { + 0% { + transform: scale(1); + } + 100% { + transform: scale(3); + } +} diff --git a/src/hooks/useAxios.js b/src/hooks/useAxios.js index 4c7be165..d06d3a2e 100644 --- a/src/hooks/useAxios.js +++ b/src/hooks/useAxios.js @@ -38,6 +38,10 @@ export function useAxios() { .catch(console.error) } + const promiseGet = async ({ url }) => { + return await getInstances(url).get(url) + } + const post = async ({ url, data }) => { return await getInstances(url) .post(url, data) @@ -70,5 +74,5 @@ export function useAxios() { .catch(console.error) } - return { get, post, promisePost, put, patch, del } + return { get, promiseGet, post, promisePost, put, patch, del } } diff --git a/src/lib/authActions.js b/src/lib/authActions.js index c19ba0f0..d3f5aaf3 100644 --- a/src/lib/authActions.js +++ b/src/lib/authActions.js @@ -28,9 +28,10 @@ export async function getSession() { export async function checkSession() { const session = await getSession() - if (!session.isLoggedIn) { - redirect('/login') - } + // if (!session.isLoggedIn) { + // redirect('/login') + // } + return session.isLoggedIn } export async function setSession(data) { diff --git a/src/middleware.js b/src/middleware.js index f93c0506..c9e6811c 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -1,27 +1,27 @@ -import { createI18nMiddleware } from 'next-international/middleware' +// import { createI18nMiddleware } from 'next-international/middleware' -const I18nMiddleware = createI18nMiddleware({ - locales: ['ko', 'ja'], - defaultLocale: 'ko', -}) +// const I18nMiddleware = createI18nMiddleware({ +// locales: ['ko', 'ja'], +// defaultLocale: 'ko', +// }) -export function middleware(request) { - return I18nMiddleware(request) -} +// export function middleware(request) { +// return I18nMiddleware(request) +// } export const config = { matcher: ['/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)'], } -// import { NextRequest, NextResponse } from 'next/server' +import { NextRequest, NextResponse } from 'next/server' -// export function middleware(request) { -// const requestHeaders = new Headers(request.headers) -// requestHeaders.set('x-pathname', request.nextUrl.pathname) +export function middleware(request) { + const requestHeaders = new Headers(request.headers) + requestHeaders.set('x-pathname', request.nextUrl.pathname) -// return NextResponse.next({ -// request: { -// headers: requestHeaders, -// }, -// }) -// } + return NextResponse.next({ + request: { + headers: requestHeaders, + }, + }) +} From 34701e865f049f465a89c5712b50e0fb8f3a32a1 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 13 Sep 2024 13:16:17 +0900 Subject: [PATCH 18/23] fix: Resolve conflict --- src/components/floor-plan/CanvasMenu.jsx | 95 ++----------------- .../modal/outerlinesetting/OuterLineWall.jsx | 9 +- 2 files changed, 11 insertions(+), 93 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index db60bf75..2a8bde0d 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -1,20 +1,9 @@ 'use client' -import { useState } from 'react' -import { useRecoilState } from 'recoil' -import { modalState } from '@/store/modalAtom' -import { settingModalFirstOptionsState } from '@/store/settingAtom' import { useEffect, useState } from 'react' import MenuDepth01 from './MenuDepth01' import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' -import { post } from '@/lib/Axios' -import { currentMenuState } from '@/store/canvasAtom' -import { MENU } from '@/common/common' -import RoofCoveringMenu from '@/components/floor-plan/RoofCoveringMenu' -export default function CanvasMenu() { - const [objectNo, setObjectNo] = useState('test123240912001') - const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state export default function CanvasMenu(props) { const { setShowCanvasSettingModal, showOutlineModal, setShowOutlineModal } = props const [menuNumber, setMenuNumber] = useState(null) @@ -22,64 +11,12 @@ export default function CanvasMenu(props) { const [type, setType] = useState('') const { getMessage } = useMessage() const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] - const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState) - - const onClickNav = (menu) => { - setCurrentMenu(menu) - } - - const settingsModalOptions = useRecoilState(settingModalFirstOptionsState) - - // 저장버튼(btn08) 클릭 시 호출되는 함수 - const handleSaveSettings = async () => { - try { - // 서버에 전송할 데이터 - const dataToSend = { - option1: settingsModalOptions[0].option1.map((item) => ({ - column: item.column, - selected: item.selected, - })), - option2: settingsModalOptions[0].option2.map((item) => ({ - column: item.column, - selected: item.selected, - })), - } - - const patternData = { - objectNo, - assignDisplay: dataToSend.option1[0].selected, - drawDisplay: dataToSend.option1[1].selected, - gridDisplay: dataToSend.option1[2].selected, - charDisplay: dataToSend.option1[3].selected, - flowDisplay: dataToSend.option1[4].selected, - hallwayDimenDisplay: dataToSend.option1[5].selected, - actualDimenDisplay: dataToSend.option1[6].selected, - noDimenDisplay: dataToSend.option1[7].selected, - trestleDisplay: dataToSend.option1[8].selected, - coordiDisplay: dataToSend.option1[9].selected, - drawConverDisplay: dataToSend.option1[10].selected, - onlyBorder: dataToSend.option2[0].selected, - lineHatch: dataToSend.option2[1].selected, - allPainted: dataToSend.option2[2].selected, - } - - // HTTP POST 요청 보내기 - const response = await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) - - // 응답 처리 - console.log('서버 응답:', response.data) - alert('설정이 저장되었습니다.') - } catch (error) { - console.error('설정을 저장하는 동안 오류가 발생했습니다:', error) - alert('설정을 저장하는 중 오류가 발생했습니다.') - } const onClickNav = (number) => { setMenuNumber(number) if (number === 2) setType('outline') if (number === 3) setType('surface') if (number === 4) setType('module') } - const menuProps = { setShowOutlineModal, type, @@ -87,28 +24,21 @@ export default function CanvasMenu(props) { useEffect(() => {}, [menuNumber, type]) return ( -
    +
      -
    • onClickNav(1)}> +
    • onClickNav(0)}>
    • - { -
    • onClickNav(MENU.INITIAL_CANVAS_SETTING)} - > - -
    • - } +
    • onClickNav(1)}> + +
    • { @@ -174,7 +104,7 @@ export default function CanvasMenu(props) {
    - +
    @@ -218,13 +148,6 @@ export default function CanvasMenu(props) { )}
    -
    - {Object.values(MENU.ROOF_COVERING).includes(currentMenu) && } - {/*{menuNumber === 2 && } - {menuNumber === 3 && } - {menuNumber === 4 && }*/}
    {menuNumber === 2 && } {menuNumber === 3 && } diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index 5ad24284..b743b6fe 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -21,9 +21,6 @@ import { useLine } from '@/hooks/useLine' export default function OuterLineWall() { const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state -export default function OuterLineWall(props) { - const { setShowOutlineModal } = props - const [buttonAct, setButtonAct] = useState(1) const { getMessage } = useMessage() const { addCanvasMouseEventListener, addDocumentEventListener, removeAllDocumentEventListeners } = useEvent() const { addLineText, removeLineText } = useLine() @@ -64,8 +61,6 @@ export default function OuterLineWall(props) { setArrow1('') setArrow2('') - const HandleClickClose = () => { - setShowOutlineModal(false) } const mouseDown = (e) => { @@ -357,8 +352,8 @@ export default function OuterLineWall(props) { }) } return ( - -
    + +

    {getMessage('modal.cover.outline.drawing')}

    + {options?.map((option) => ( +
  • +
  • ))} diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index b716cbdd..e8a4e872 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -1,5 +1,5 @@ 'use client' -import { Fragment } from 'react' +import { Fragment, useState } from 'react' import Link from 'next/link' import { usePathname, useRouter } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' @@ -29,7 +29,14 @@ export default function Header(props) { // if (pathName.includes('login') || pathName.includes('join')) { // return null // } - const SelectOption = [{ name: 'オンライン保証シ' }, { name: 'ステム' }] + const [selected, setSelected] = useState('') + + const SelectOptions = [ + { id: 0, name: 'オンライン保証シ', link: '' }, + { id: 1, name: 'ステム', link: '' }, + { id: 2, name: 'TEST1', link: 'https://www.weather.go.kr/w/index.do' }, + { id: 3, name: 'TEST2', link: 'https://www.google.com' }, + ] const menus = [ { id: 0, name: 'header.menus.home', url: '/', children: [] }, { @@ -53,6 +60,15 @@ export default function Header(props) { }, ] + const onChangeSelect = (option) => { + setSelected(option) + } + const navPage = () => { + if (selected.link) { + location.href = selected.link + } + } + const getMenuTemplate = (menus) => { return menus.map((menu) => { return ( @@ -112,10 +128,12 @@ export default function Header(props) {
    - +
    - +
    From 8b4550d442b1acd956ca48df2aeb9d67bf9da6b6 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 13 Sep 2024 13:37:59 +0900 Subject: [PATCH 20/23] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=ED=98=84=ED=99=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/management/stuff/detail/page.jsx | 4 + src/app/management/stuff/tempdetail/page.jsx | 15 + src/components/management/Stuff.jsx | 12 +- src/components/management/StuffDetail.jsx | 353 ++++++------------- 4 files changed, 143 insertions(+), 241 deletions(-) create mode 100644 src/app/management/stuff/tempdetail/page.jsx diff --git a/src/app/management/stuff/detail/page.jsx b/src/app/management/stuff/detail/page.jsx index 8b84287a..6759b282 100644 --- a/src/app/management/stuff/detail/page.jsx +++ b/src/app/management/stuff/detail/page.jsx @@ -1,11 +1,15 @@ import React from 'react' import Hero from '@/components/Hero' import StuffDetail from '@/components/management/StuffDetail' +import Link from 'next/link' export default function ManagementStuffDetailPage() { return ( <>

    물건정보

    + +

    도면작성

    +
    diff --git a/src/app/management/stuff/tempdetail/page.jsx b/src/app/management/stuff/tempdetail/page.jsx new file mode 100644 index 00000000..8b84287a --- /dev/null +++ b/src/app/management/stuff/tempdetail/page.jsx @@ -0,0 +1,15 @@ +import React from 'react' +import Hero from '@/components/Hero' +import StuffDetail from '@/components/management/StuffDetail' +export default function ManagementStuffDetailPage() { + return ( + <> +
    +

    물건정보

    +
    +
    + +
    + + ) +} diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index e445fa1d..6f615c3c 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -269,7 +269,8 @@ export default function Stuff() { // let size // let pageCount - const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` + // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` + const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}` await get({ url: apiUrl, @@ -292,7 +293,8 @@ export default function Stuff() { stuffSearchParams.schSortType = defaultSortType console.log('조회 눌럿을때 ::::::::::::::', stuffSearchParams) async function fetchData() { - const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` await get({ url: apiUrl }).then((res) => { console.log('API결과:::::::', res) if (!isEmptyArray(res)) { @@ -322,7 +324,8 @@ export default function Stuff() { }) console.log('셋팅된 검색조건:::', stuffSearchParams) //조회API호출 - const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` get({ url: apiUrl }).then((res) => { console.log('보여줄개수바꿨을때 조회 ::::::::::', res) if (!isEmptyArray(res)) { @@ -345,7 +348,8 @@ export default function Stuff() { code: 'S', schSortType: e.target.value, }) - const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` // console.log('apiUrl::', apiUrl) get({ url: apiUrl }).then((res) => { console.log('정렬바꿨을때 조회 ::::::::::', res) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 6e455876..66baf8e3 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -4,7 +4,7 @@ import React, { useState, useEffect } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { Input, RadioGroup, Radio, Button, Autocomplete, AutocompleteItem, Select, SelectItem, Checkbox, Textarea, button } from '@nextui-org/react' import Link from 'next/link' -import { del, get } from '@/lib/Axios' +import { del, get, post } from '@/lib/Axios' import { queryStringFormatter, isEmptyArray } from '@/util/common-utils' import dayjs from 'dayjs' import { useMessage } from '@/hooks/useMessage' @@ -24,8 +24,11 @@ export default function StuffDetail() { objectNameKana: '', //물건명 후리가나 saleStoreId: '', //판매점ID saleStoreName: '', //판매점명 + otherSaleStoreId: '', + otherSaleStoreName: '', zipNo: '', //우편번호 prefId: '', //도도부현 + prefName: '', address: '', //주소 powerSimArea: '', //발전량시뮬레이션지역 windSpeed: '', //기준풍속 @@ -35,7 +38,7 @@ export default function StuffDetail() { saltAreaChk: false, //염해지역용아이템사용 installHeight: '', //설치높이 powerConTerms: '0', //계약조건(잉여 / 전량) - remark: '', //메모 + remarks: '', //메모 tempFlag: 'T', //임시저장(1) 저장(0) } const { register, setValue, getValues, handleSubmit, resetField, control, watch } = useForm({ @@ -47,6 +50,7 @@ export default function StuffDetail() { const [prefCodeList, setPrefCodeList] = useState([]) //도도부현 코트 리스트 const [prefValue, setPrefValue] = useState('') const [saleStoreList, setSaleStoreList] = useState([]) // 판매점 리스트 + const [otherSaleStoreList, setOtherSaleStoreList] = useState([]) const [powerSimAreaList, setPowerSimAreaList] = useState([]) //발전시뮬레이션 리스트 @@ -59,6 +63,7 @@ export default function StuffDetail() { useEffect(() => { if (objectNo) { + console.log('수정화면') setEditMode('EDIT') if (objectNo.substring(0, 1) === 'R') { @@ -66,9 +71,9 @@ export default function StuffDetail() { setIsFormValid(true) } get({ url: `/api/object/${objectNo}/detail` }).then((res) => { - console.log('물건번호로 상세 API 호출') + // console.log('물건번호로 상세 API 호출') if (res != null) { - console.log('상세res:::::::', res) + // console.log('상세res:::::::', res) setDetailData(res) // 신규 상세 공통APi @@ -83,7 +88,7 @@ export default function StuffDetail() { // 임시 1차점 판매점코드 saleStoreId=201TES01 // T01 //1차점 : X167 - get({ url: `/api/object/saleStore/201TES01/list` }).then((res) => { + get({ url: `/api/object/saleStore/X167/list` }).then((res) => { if (!isEmptyArray(res)) { console.log('판매점 결과:::::', res) setSaleStoreList(res) @@ -91,6 +96,7 @@ export default function StuffDetail() { form.setValue('saleStoreId', res[0].saleStoreId) //1차 판매점 번호 셋팅 form.setValue('saleStoreName', res[0].saleStoreId) + setOtherSaleStoreList([]) } }) } else { @@ -99,7 +105,7 @@ export default function StuffDetail() { } }) } else { - console.log('신규일떄 공통코드세팅') + console.log('신규화면') // 신규 상세 공통APi // 도도부현API get({ url: '/api/object/prefecture/list' }).then((res) => { @@ -112,14 +118,22 @@ export default function StuffDetail() { // 임시 1차점 판매점코드 saleStoreId=201TES01 // T01 //1차점 : X167 - get({ url: `/api/object/saleStore/201TES01/list` }).then((res) => { + get({ url: `/api/object/saleStore/X167/list` }).then((res) => { if (!isEmptyArray(res)) { console.log('판매점 결과:::::', res) - setSaleStoreList(res) + const firstList = res.filter((row) => row.saleStoreLevel === '1') + const otherList = res.filter((row) => row.saleStoreLevel !== '1') + console.log('first:::::', firstList) + console.log('otherList:::::', otherList) + //1차점 셀렉트박스 + setSaleStoreList(firstList) //1차 판매점 자동완성 값 셋팅 - form.setValue('saleStoreId', res[0].saleStoreId) + form.setValue('saleStoreId', firstList[0].saleStoreId) //1차 판매점 번호 셋팅 - form.setValue('saleStoreName', res[0].saleStoreId) + form.setValue('saleStoreName', firstList[0].saleStoreId) + + //1차점 아닌 판매점 셀렉트박스 + setOtherSaleStoreList(otherList) } }) } @@ -135,6 +149,11 @@ export default function StuffDetail() { form.setValue('saleStoreName', key) } } + + //2차점 변경 이벤트 + const onSelectionChange2 = (key) => { + console.log(key) + } // 우편번호 숫자만 체크 const _zipNo = watch('zipNo') useEffect(() => { @@ -161,7 +180,7 @@ export default function StuffDetail() { // saltAreaChk: false, //염해지역용아이템사용 // installHeight: '', //설치높이 // powerConTerms: '0', //계약조건(잉여 / 전량) - // remark: '', //메모 + // remarks: '', //메모 // tempFlag: 'T', //임시저장(1) 저장(0) const _dispCompanyName = watch('dispCompanyName') const _objectName = watch('objectName') @@ -174,10 +193,10 @@ export default function StuffDetail() { const _snowCover = watch('snowCover') const _installHeight = watch('installHeight') useEffect(() => { - console.log('mode:::::', editMode) + // console.log('mode:::::', editMode) if (editMode === 'NEW') { const formData = form.getValues() - console.log('폼::::::::::::', formData) + // console.log('폼::::::::::::', formData) let errors = {} if (!_dispCompanyName || _dispCompanyName.trim().length === 0) { errors.dispCompanyName = true @@ -220,10 +239,10 @@ export default function StuffDetail() { errors.installHeight = true } - console.log('errors::', errors) + // console.log('errors::', errors) setIsFormValid(Object.keys(errors).length === 0) } else { - console.log('상세일때 폼체크') + // console.log('상세일때 폼체크') } }, [_dispCompanyName, _objectName, _objectNameOmit, _saleStoreId, _zipNo, _prefId, _address, _powerSimArea, _windSpeed, _snowCover, _installHeight]) @@ -237,17 +256,17 @@ export default function StuffDetail() { //9302226 if (res.status === 200) { if (res.results != null) { - console.log('주소검색::', res.results) - // prefId: '', //도도부현 - // address: '', //주소 - console.log('prefcode::', res.results[0].prefcode) - console.log('address::', res.results[0].address2 + res.results[0].address3) + // console.log('주소검색::', res.results) + // console.log('prefcode::', res.results[0].prefcode) + // console.log('address::', res.results[0].address2 + res.results[0].address3) setPrefValue(res.results[0].prefcode) form.setValue('prefId', res.results[0].prefcode) + form.setValue('prefName', res.results[0].address1) form.setValue('address', res.results[0].address2 + res.results[0].address3) } else { alert('등록된 우편번호에서 주소를 찾을 수 없습니다. 다시 입력해주세요.') form.setValue('prefId', '') + form.setValue('prefName', '') form.setValue('address', '') form.setValue('zipNo', '') setPrefValue('') @@ -262,12 +281,12 @@ export default function StuffDetail() { useEffect(() => { if (prefValue !== '') { - console.log('우편번호 검색해서 도도부현골랐을때::::', prefValue) + // console.log('우편번호 검색해서 도도부현골랐을때::::', prefValue) // 발전량시뮬레이션 지역 목록 // /api/object/prefecture/도도부현코드/list get({ url: `/api/object/prefecture/${prefValue}/list` }).then((res) => { if (!isEmptyArray(res)) { - console.log('발전시뮬레이션::::::::', res) + // console.log('발전시뮬레이션::::::::', res) setPowerSimAreaList(res) } }) @@ -276,10 +295,11 @@ export default function StuffDetail() { //필수값 다 입력했을때 const onValid = (data) => { - console.log('필수값 다 있고 저장') - console.log('data::::::', data) + // 수정모드일때는 PUT + // console.log('필수값 다 있고 저장') + // console.log('data::::::', data) const formData = form.getValues() - console.log('formData::::', formData) + // console.log('formData::::', formData) // const _dispCompanyName = watch('dispCompanyName') // const _objectStatusId = watch('objectStatusId') // const _objectNameOmit = watch('objectNameOmit') @@ -297,15 +317,52 @@ export default function StuffDetail() { // console.log('_coldAreaChk::', _coldAreaChk) } - //필수값 안넣었을때 임시저장 - const onInvalid = (errors) => { + //필수값 안넣었을때 임시저장 form required사용시 + // const onInvalid = (errors) => { + // console.log('22222222222222222222222') + // const formData = form.getValues() + // console.log('임시저장formData::::', formData) + // } + + // 임시저장 + const onTempSave = async () => { const formData = form.getValues() - console.log('임시저장formData::::', formData) + //console.log('임시저장::::::::', formData) + + const params = { + saleStoreId: formData.saleStoreId, + saleStoreName: formData.saleStoreName, + objectStatusId: formData.objectStatusId, + objectName: formData.objectName, + objectNameOmit: formData.objectNameOmit, + objectNameKana: formData.objectNameKana, + zipNo: formData.zipNo, + prefId: formData.prefId, + prefName: formData.prefName, + address: formData.address, + powerSimArea: formData.powerSimArea, + receiveUser: formData.dispCompanyName, + installHeight: formData.installHeight, + windSpeed: formData.windSpeed, + snowCover: formData.snowCover, + surfaceType: formData.surfaceType, + powerConTerms: formData.powerConTerms, + saltAreaChk: formData.saltAreaChk, + coldAreaChk: formData.coldAreaChk, + tempFlg: '1', + workNo: null, + workName: null, + } + console.log('임시저장params::', params) + return + await post({ url: '/api/object/save-object', data: params }).then((res) => { + console.log('res::::::', res) + }) } // 발전량 시뮬레이션 변경 const handlePowerSimAreaOnChange = (e) => { - console.log('가지고있는 도도부현코드:::::::::', prefValue) + // console.log('가지고있는 도도부현코드:::::::::', prefValue) // console.log('발전량시뮬레이션변경:::::::::', e.target.value) //값 set해주고 그거 useEffect로 api호출 } @@ -313,13 +370,13 @@ export default function StuffDetail() { // 물건삭제 const onDelete = () => { //http://localhost:8080/api/object/R201TES01240910023 - console.log('물건번호::::::::', objectNo) + // console.log('물건번호::::::::', objectNo) alert('사양확정일이 있으면 삭제 불가') if (confirm(getMessage('common.message.data.delete'))) { let testobj = '10' del({ url: `/api/object/${testobj}` }).then((res) => { - console.log('삭제 결과:::', res) + // console.log('삭제 결과:::', res) router.push('/management/stuff') }) } @@ -328,12 +385,12 @@ export default function StuffDetail() { return ( <> {(editMode === 'NEW' && ( -
    +
    (*필수 입력항목)
    - +
    @@ -341,9 +398,9 @@ export default function StuffDetail() { - +
    - @@ -353,7 +410,7 @@ export default function StuffDetail() {
    - +
    @@ -363,9 +420,8 @@ export default function StuffDetail() { className="max-w-xs" defaultItems={saleStoreList} label="판매점ID자동완성" - // selectedKey={saleStoreValue} selectedKey={form.watch('saleStoreId')} - {...form.register('saleStoreId', { required: true })} + {...form.register('saleStoreId')} onSelectionChange={onSelectionChange} > {(option) => {option.saleStoreName}} @@ -376,6 +432,19 @@ export default function StuffDetail() {
    +
    + {otherSaleStoreList?.length > 0 && ( + + {(option) => {option.saleStoreName}} + + )} +
    @@ -384,7 +453,6 @@ export default function StuffDetail() { className="input-origin" maxLength={7} {...form.register('zipNo', { - required: true, minLength: { value: 7, message: '7자리만가능' }, pattern: { value: /^[0-9]*$/g, message: '숫자만 입력' }, })} @@ -398,7 +466,7 @@ export default function StuffDetail() {
    {prefCodeList?.length > 0 && ( - {prefCodeList.map((row) => { return {row.prefName} })} @@ -414,7 +482,7 @@ export default function StuffDetail() { + + setName2(e.target.value)} /> -
    -
    - -
    -
    - 물건명 후리가나 - setName3(e.target.value)} /> -
    -
    */} - {/*
    - 판매점명 /ID * -
    - - {(option) => {option.name}} - -
    -
    */} - {/*
    - 우편번호* - - - *우편번호 7자리를 입력한 후, 주소검색 버튼을 클릭해 주십시오 -
    */} - {/*
    - 도도부현 / 주소* - -
    */} - {/*
    - 발전량시뮬레이션지역* - -
    -
    - 기준풍속* - - m/s이하 -
    -
    - 수직적설량* - cm - - 한랭지대책시행 - -
    */} - {/*
    - 면조도구분* - { - setGubun2(e.target.value) - }} - /> - - { - setGubun2(e.target.value) - }} - /> - - - 염해지역용아이템사용 - -
    -
    - 설치높이* - - m -
    -
    - 계약조건 - { - setGubun3(e.target.value) - }} - /> - - { - setGubun3(e.target.value) - }} - /> - -
    -
    - 메모 -