diff --git a/.env.development b/.env.development index 468efc67..933db5d3 100644 --- a/.env.development +++ b/.env.development @@ -8,4 +8,7 @@ DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;passwor SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" -NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" \ No newline at end of file +NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" + +NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-local.q-cells.jp:8120/eos/login/autoLogin" +NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-local.q-cells.jp:8120/qm/login/autoLogin" \ No newline at end of file diff --git a/.env.production b/.env.production index 2c41bf76..9bad1719 100644 --- a/.env.production +++ b/.env.production @@ -6,4 +6,7 @@ DATABASE_URL="" SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" -NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" \ No newline at end of file +NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" + +NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-local.q-cells.jp:8120/eos/login/autoLogin" +NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-local.q-cells.jp:8120/qm/login/autoLogin" \ No newline at end of file diff --git a/package.json b/package.json index 5355cae6..d7214b51 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "framer-motion": "^11.2.13", "fs": "^0.0.1-security", "iron-session": "^8.0.2", + "js-cookie": "^3.0.5", "mathjs": "^13.0.2", "mssql": "^11.0.1", "next": "14.2.3", @@ -43,6 +44,8 @@ "prettier": "^3.3.3", "prisma": "^5.18.0", "react-color-palette": "^7.2.2", + "react-dropdown-select": "^4.11.3", + "react-select": "^5.8.1", "sass": "^1.77.8", "tailwindcss": "^3.4.1" } diff --git a/public/static/images/canvas/additional-edit01.svg b/public/static/images/canvas/additional-edit01.svg new file mode 100644 index 00000000..2e8ce52c --- /dev/null +++ b/public/static/images/canvas/additional-edit01.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional-edit02.svg b/public/static/images/canvas/additional-edit02.svg new file mode 100644 index 00000000..5d3a03cd --- /dev/null +++ b/public/static/images/canvas/additional-edit02.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_bundle-del01.svg b/public/static/images/canvas/additional_bundle-del01.svg new file mode 100644 index 00000000..29ad58c0 --- /dev/null +++ b/public/static/images/canvas/additional_bundle-del01.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_bundle-del02.svg b/public/static/images/canvas/additional_bundle-del02.svg new file mode 100644 index 00000000..797adf82 --- /dev/null +++ b/public/static/images/canvas/additional_bundle-del02.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_bundle-del03.svg b/public/static/images/canvas/additional_bundle-del03.svg new file mode 100644 index 00000000..082cae56 --- /dev/null +++ b/public/static/images/canvas/additional_bundle-del03.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_bundle-del04.svg b/public/static/images/canvas/additional_bundle-del04.svg new file mode 100644 index 00000000..4f28a719 --- /dev/null +++ b/public/static/images/canvas/additional_bundle-del04.svg @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_bundle-edit01.svg b/public/static/images/canvas/additional_bundle-edit01.svg new file mode 100644 index 00000000..38c3846c --- /dev/null +++ b/public/static/images/canvas/additional_bundle-edit01.svg @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_bundle-edit02.svg b/public/static/images/canvas/additional_bundle-edit02.svg new file mode 100644 index 00000000..8b2c9f7b --- /dev/null +++ b/public/static/images/canvas/additional_bundle-edit02.svg @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_del01.svg b/public/static/images/canvas/additional_del01.svg new file mode 100644 index 00000000..17e8cea0 --- /dev/null +++ b/public/static/images/canvas/additional_del01.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_del02.svg b/public/static/images/canvas/additional_del02.svg new file mode 100644 index 00000000..575dae2b --- /dev/null +++ b/public/static/images/canvas/additional_del02.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_del03.svg b/public/static/images/canvas/additional_del03.svg new file mode 100644 index 00000000..2d071afd --- /dev/null +++ b/public/static/images/canvas/additional_del03.svg @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/additional_del04.svg b/public/static/images/canvas/additional_del04.svg new file mode 100644 index 00000000..b5dc6431 --- /dev/null +++ b/public/static/images/canvas/additional_del04.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/allocation_delete.svg b/public/static/images/canvas/allocation_delete.svg new file mode 100644 index 00000000..711a241e --- /dev/null +++ b/public/static/images/canvas/allocation_delete.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/canvas/allocation_edit.svg b/public/static/images/canvas/allocation_edit.svg new file mode 100644 index 00000000..795d10f9 --- /dev/null +++ b/public/static/images/canvas/allocation_edit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/canvas/allocation_icon01_black.svg b/public/static/images/canvas/allocation_icon01_black.svg new file mode 100644 index 00000000..01829a32 --- /dev/null +++ b/public/static/images/canvas/allocation_icon01_black.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/canvas/allocation_icon01_white.svg b/public/static/images/canvas/allocation_icon01_white.svg new file mode 100644 index 00000000..5618848e --- /dev/null +++ b/public/static/images/canvas/allocation_icon01_white.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/canvas/allocation_icon02_black.svg b/public/static/images/canvas/allocation_icon02_black.svg new file mode 100644 index 00000000..57c6173b --- /dev/null +++ b/public/static/images/canvas/allocation_icon02_black.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/canvas/allocation_icon02_white.svg b/public/static/images/canvas/allocation_icon02_white.svg new file mode 100644 index 00000000..17211b04 --- /dev/null +++ b/public/static/images/canvas/allocation_icon02_white.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/canvas/circuit_del.svg b/public/static/images/canvas/circuit_del.svg new file mode 100644 index 00000000..48a3c49d --- /dev/null +++ b/public/static/images/canvas/circuit_del.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/canvas/compas.svg b/public/static/images/canvas/compas.svg new file mode 100644 index 00000000..fc9bccb1 --- /dev/null +++ b/public/static/images/canvas/compas.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/static/images/canvas/compas_num.svg b/public/static/images/canvas/compas_num.svg new file mode 100644 index 00000000..5deeea27 --- /dev/null +++ b/public/static/images/canvas/compas_num.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon01.svg b/public/static/images/canvas/eaves_icon01.svg new file mode 100644 index 00000000..da520069 --- /dev/null +++ b/public/static/images/canvas/eaves_icon01.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon02.svg b/public/static/images/canvas/eaves_icon02.svg new file mode 100644 index 00000000..0addbc04 --- /dev/null +++ b/public/static/images/canvas/eaves_icon02.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon03.svg b/public/static/images/canvas/eaves_icon03.svg new file mode 100644 index 00000000..b95b49fc --- /dev/null +++ b/public/static/images/canvas/eaves_icon03.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon04.svg b/public/static/images/canvas/eaves_icon04.svg new file mode 100644 index 00000000..ac08ce05 --- /dev/null +++ b/public/static/images/canvas/eaves_icon04.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon05.svg b/public/static/images/canvas/eaves_icon05.svg new file mode 100644 index 00000000..649a6058 --- /dev/null +++ b/public/static/images/canvas/eaves_icon05.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon06.svg b/public/static/images/canvas/eaves_icon06.svg new file mode 100644 index 00000000..a2f17801 --- /dev/null +++ b/public/static/images/canvas/eaves_icon06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon07.svg b/public/static/images/canvas/eaves_icon07.svg new file mode 100644 index 00000000..1f101d56 --- /dev/null +++ b/public/static/images/canvas/eaves_icon07.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon08.svg b/public/static/images/canvas/eaves_icon08.svg new file mode 100644 index 00000000..8a2529de --- /dev/null +++ b/public/static/images/canvas/eaves_icon08.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon09.svg b/public/static/images/canvas/eaves_icon09.svg new file mode 100644 index 00000000..fe4512b1 --- /dev/null +++ b/public/static/images/canvas/eaves_icon09.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/images/canvas/eaves_icon10.svg b/public/static/images/canvas/eaves_icon10.svg new file mode 100644 index 00000000..99147480 --- /dev/null +++ b/public/static/images/canvas/eaves_icon10.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/module_tab_arr.svg b/public/static/images/canvas/module_tab_arr.svg new file mode 100644 index 00000000..f1da9ab2 --- /dev/null +++ b/public/static/images/canvas/module_tab_arr.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/module_tab_arr_white.svg b/public/static/images/canvas/module_tab_arr_white.svg new file mode 100644 index 00000000..49ac4437 --- /dev/null +++ b/public/static/images/canvas/module_tab_arr_white.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/object_img01.svg b/public/static/images/canvas/object_img01.svg new file mode 100644 index 00000000..1d72f00b --- /dev/null +++ b/public/static/images/canvas/object_img01.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/object_img02.svg b/public/static/images/canvas/object_img02.svg new file mode 100644 index 00000000..ab1e8f43 --- /dev/null +++ b/public/static/images/canvas/object_img02.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/penal_arr.svg b/public/static/images/canvas/penal_arr.svg new file mode 100644 index 00000000..0bd7560c --- /dev/null +++ b/public/static/images/canvas/penal_arr.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/penal_arr_white.svg b/public/static/images/canvas/penal_arr_white.svg new file mode 100644 index 00000000..e267fb93 --- /dev/null +++ b/public/static/images/canvas/penal_arr_white.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_arr.svg b/public/static/images/canvas/plane_arr.svg new file mode 100644 index 00000000..c3131c01 --- /dev/null +++ b/public/static/images/canvas/plane_arr.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_arr_act.svg b/public/static/images/canvas/plane_arr_act.svg new file mode 100644 index 00000000..2c91a0bc --- /dev/null +++ b/public/static/images/canvas/plane_arr_act.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape01.svg b/public/static/images/canvas/plane_shape01.svg new file mode 100644 index 00000000..a32d0c39 --- /dev/null +++ b/public/static/images/canvas/plane_shape01.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape010.svg b/public/static/images/canvas/plane_shape010.svg new file mode 100644 index 00000000..a17616fb --- /dev/null +++ b/public/static/images/canvas/plane_shape010.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape011.svg b/public/static/images/canvas/plane_shape011.svg new file mode 100644 index 00000000..4068d35a --- /dev/null +++ b/public/static/images/canvas/plane_shape011.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape012.svg b/public/static/images/canvas/plane_shape012.svg new file mode 100644 index 00000000..b7136002 --- /dev/null +++ b/public/static/images/canvas/plane_shape012.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape013.svg b/public/static/images/canvas/plane_shape013.svg new file mode 100644 index 00000000..6ef6e1a4 --- /dev/null +++ b/public/static/images/canvas/plane_shape013.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape014.svg b/public/static/images/canvas/plane_shape014.svg new file mode 100644 index 00000000..68789f56 --- /dev/null +++ b/public/static/images/canvas/plane_shape014.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape015.svg b/public/static/images/canvas/plane_shape015.svg new file mode 100644 index 00000000..76e89b3d --- /dev/null +++ b/public/static/images/canvas/plane_shape015.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape016.svg b/public/static/images/canvas/plane_shape016.svg new file mode 100644 index 00000000..54b8259c --- /dev/null +++ b/public/static/images/canvas/plane_shape016.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/static/images/canvas/plane_shape017.svg b/public/static/images/canvas/plane_shape017.svg new file mode 100644 index 00000000..d0378c1f --- /dev/null +++ b/public/static/images/canvas/plane_shape017.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape018.svg b/public/static/images/canvas/plane_shape018.svg new file mode 100644 index 00000000..4e48f83d --- /dev/null +++ b/public/static/images/canvas/plane_shape018.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape02.svg b/public/static/images/canvas/plane_shape02.svg new file mode 100644 index 00000000..aa0a756f --- /dev/null +++ b/public/static/images/canvas/plane_shape02.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape03.svg b/public/static/images/canvas/plane_shape03.svg new file mode 100644 index 00000000..fb6c7d0a --- /dev/null +++ b/public/static/images/canvas/plane_shape03.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape04.svg b/public/static/images/canvas/plane_shape04.svg new file mode 100644 index 00000000..3cbf25c8 --- /dev/null +++ b/public/static/images/canvas/plane_shape04.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape05.svg b/public/static/images/canvas/plane_shape05.svg new file mode 100644 index 00000000..36f1448c --- /dev/null +++ b/public/static/images/canvas/plane_shape05.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape06.svg b/public/static/images/canvas/plane_shape06.svg new file mode 100644 index 00000000..a87e30b8 --- /dev/null +++ b/public/static/images/canvas/plane_shape06.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape07.svg b/public/static/images/canvas/plane_shape07.svg new file mode 100644 index 00000000..526c95bc --- /dev/null +++ b/public/static/images/canvas/plane_shape07.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape08.svg b/public/static/images/canvas/plane_shape08.svg new file mode 100644 index 00000000..8ad3bf5a --- /dev/null +++ b/public/static/images/canvas/plane_shape08.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_shape09.svg b/public/static/images/canvas/plane_shape09.svg new file mode 100644 index 00000000..519294ef --- /dev/null +++ b/public/static/images/canvas/plane_shape09.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/plane_tab01.svg b/public/static/images/canvas/plane_tab01.svg new file mode 100644 index 00000000..f768a207 --- /dev/null +++ b/public/static/images/canvas/plane_tab01.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab02.svg b/public/static/images/canvas/plane_tab02.svg new file mode 100644 index 00000000..61891248 --- /dev/null +++ b/public/static/images/canvas/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab03.svg b/public/static/images/canvas/plane_tab03.svg new file mode 100644 index 00000000..295e0d89 --- /dev/null +++ b/public/static/images/canvas/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab04.svg b/public/static/images/canvas/plane_tab04.svg new file mode 100644 index 00000000..894bb55c --- /dev/null +++ b/public/static/images/canvas/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab05.svg b/public/static/images/canvas/plane_tab05.svg new file mode 100644 index 00000000..63b3c201 --- /dev/null +++ b/public/static/images/canvas/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab06.svg b/public/static/images/canvas/plane_tab06.svg new file mode 100644 index 00000000..1bad98a0 --- /dev/null +++ b/public/static/images/canvas/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab07.svg b/public/static/images/canvas/plane_tab07.svg new file mode 100644 index 00000000..a358f766 --- /dev/null +++ b/public/static/images/canvas/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab08.svg b/public/static/images/canvas/plane_tab08.svg new file mode 100644 index 00000000..22a72ab6 --- /dev/null +++ b/public/static/images/canvas/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab09.svg b/public/static/images/canvas/plane_tab09.svg new file mode 100644 index 00000000..756c3bfa --- /dev/null +++ b/public/static/images/canvas/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab10.svg b/public/static/images/canvas/plane_tab10.svg new file mode 100644 index 00000000..fe4073ea --- /dev/null +++ b/public/static/images/canvas/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab11.svg b/public/static/images/canvas/plane_tab11.svg new file mode 100644 index 00000000..0ac2cf59 --- /dev/null +++ b/public/static/images/canvas/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab12.svg b/public/static/images/canvas/plane_tab12.svg new file mode 100644 index 00000000..a68e7a39 --- /dev/null +++ b/public/static/images/canvas/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab13.svg b/public/static/images/canvas/plane_tab13.svg new file mode 100644 index 00000000..027e91e8 --- /dev/null +++ b/public/static/images/canvas/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab14.svg b/public/static/images/canvas/plane_tab14.svg new file mode 100644 index 00000000..7a3cef86 --- /dev/null +++ b/public/static/images/canvas/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab15.svg b/public/static/images/canvas/plane_tab15.svg new file mode 100644 index 00000000..c0c1b0bb --- /dev/null +++ b/public/static/images/canvas/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab16.svg b/public/static/images/canvas/plane_tab16.svg new file mode 100644 index 00000000..c66484e3 --- /dev/null +++ b/public/static/images/canvas/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab17.svg b/public/static/images/canvas/plane_tab17.svg new file mode 100644 index 00000000..ae8ddd0f --- /dev/null +++ b/public/static/images/canvas/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/plane_tab18.svg b/public/static/images/canvas/plane_tab18.svg new file mode 100644 index 00000000..12bd0ad3 --- /dev/null +++ b/public/static/images/canvas/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab01.svg b/public/static/images/canvas/shape/180deg/plane_tab01.svg new file mode 100644 index 00000000..84c22986 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab01.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab02.svg b/public/static/images/canvas/shape/180deg/plane_tab02.svg new file mode 100644 index 00000000..21cf9082 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab03.svg b/public/static/images/canvas/shape/180deg/plane_tab03.svg new file mode 100644 index 00000000..46d3b5b2 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab04.svg b/public/static/images/canvas/shape/180deg/plane_tab04.svg new file mode 100644 index 00000000..4b4ceafa --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab05.svg b/public/static/images/canvas/shape/180deg/plane_tab05.svg new file mode 100644 index 00000000..40d9d32b --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab06.svg b/public/static/images/canvas/shape/180deg/plane_tab06.svg new file mode 100644 index 00000000..8c3e8f6e --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab07.svg b/public/static/images/canvas/shape/180deg/plane_tab07.svg new file mode 100644 index 00000000..aef6908b --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab08.svg b/public/static/images/canvas/shape/180deg/plane_tab08.svg new file mode 100644 index 00000000..6d4b6949 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab09.svg b/public/static/images/canvas/shape/180deg/plane_tab09.svg new file mode 100644 index 00000000..c135a87b --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab10.svg b/public/static/images/canvas/shape/180deg/plane_tab10.svg new file mode 100644 index 00000000..6a9ede6f --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab11.svg b/public/static/images/canvas/shape/180deg/plane_tab11.svg new file mode 100644 index 00000000..a84d6796 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab12.svg b/public/static/images/canvas/shape/180deg/plane_tab12.svg new file mode 100644 index 00000000..15e01d3a --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab13.svg b/public/static/images/canvas/shape/180deg/plane_tab13.svg new file mode 100644 index 00000000..48d8f87e --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab14.svg b/public/static/images/canvas/shape/180deg/plane_tab14.svg new file mode 100644 index 00000000..e94c8459 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab15.svg b/public/static/images/canvas/shape/180deg/plane_tab15.svg new file mode 100644 index 00000000..cc6f56f2 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab16.svg b/public/static/images/canvas/shape/180deg/plane_tab16.svg new file mode 100644 index 00000000..42d6ad2e --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab17.svg b/public/static/images/canvas/shape/180deg/plane_tab17.svg new file mode 100644 index 00000000..741f65d4 --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/180deg/plane_tab18.svg b/public/static/images/canvas/shape/180deg/plane_tab18.svg new file mode 100644 index 00000000..c59192ca --- /dev/null +++ b/public/static/images/canvas/shape/180deg/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab01.svg b/public/static/images/canvas/shape/270deg/plane_tab01.svg new file mode 100644 index 00000000..22b32884 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab01.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab02.svg b/public/static/images/canvas/shape/270deg/plane_tab02.svg new file mode 100644 index 00000000..105cf6f1 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab03.svg b/public/static/images/canvas/shape/270deg/plane_tab03.svg new file mode 100644 index 00000000..9f10a097 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab04.svg b/public/static/images/canvas/shape/270deg/plane_tab04.svg new file mode 100644 index 00000000..46d682bc --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab05.svg b/public/static/images/canvas/shape/270deg/plane_tab05.svg new file mode 100644 index 00000000..90be1d79 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab06.svg b/public/static/images/canvas/shape/270deg/plane_tab06.svg new file mode 100644 index 00000000..4ac8ec72 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab07.svg b/public/static/images/canvas/shape/270deg/plane_tab07.svg new file mode 100644 index 00000000..61ea3380 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab08.svg b/public/static/images/canvas/shape/270deg/plane_tab08.svg new file mode 100644 index 00000000..0d70143a --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab09.svg b/public/static/images/canvas/shape/270deg/plane_tab09.svg new file mode 100644 index 00000000..11af80b9 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab10.svg b/public/static/images/canvas/shape/270deg/plane_tab10.svg new file mode 100644 index 00000000..5b182179 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab11.svg b/public/static/images/canvas/shape/270deg/plane_tab11.svg new file mode 100644 index 00000000..b8f70b55 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab12.svg b/public/static/images/canvas/shape/270deg/plane_tab12.svg new file mode 100644 index 00000000..2a9d4ea6 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab13.svg b/public/static/images/canvas/shape/270deg/plane_tab13.svg new file mode 100644 index 00000000..3200c6cc --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab14.svg b/public/static/images/canvas/shape/270deg/plane_tab14.svg new file mode 100644 index 00000000..82fa8d99 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab15.svg b/public/static/images/canvas/shape/270deg/plane_tab15.svg new file mode 100644 index 00000000..eb47001c --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab16.svg b/public/static/images/canvas/shape/270deg/plane_tab16.svg new file mode 100644 index 00000000..ff7b570d --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab17.svg b/public/static/images/canvas/shape/270deg/plane_tab17.svg new file mode 100644 index 00000000..0ce3740a --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab18.svg b/public/static/images/canvas/shape/270deg/plane_tab18.svg new file mode 100644 index 00000000..b0cbc443 --- /dev/null +++ b/public/static/images/canvas/shape/270deg/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab01.svg b/public/static/images/canvas/shape/90deg/plane_tab01.svg new file mode 100644 index 00000000..46476194 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab01.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab02.svg b/public/static/images/canvas/shape/90deg/plane_tab02.svg new file mode 100644 index 00000000..74d5a79c --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab03.svg b/public/static/images/canvas/shape/90deg/plane_tab03.svg new file mode 100644 index 00000000..8a1cf359 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab04.svg b/public/static/images/canvas/shape/90deg/plane_tab04.svg new file mode 100644 index 00000000..b06f007f --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab05.svg b/public/static/images/canvas/shape/90deg/plane_tab05.svg new file mode 100644 index 00000000..8f5be183 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab06.svg b/public/static/images/canvas/shape/90deg/plane_tab06.svg new file mode 100644 index 00000000..d269faab --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab07.svg b/public/static/images/canvas/shape/90deg/plane_tab07.svg new file mode 100644 index 00000000..998629bd --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab08.svg b/public/static/images/canvas/shape/90deg/plane_tab08.svg new file mode 100644 index 00000000..390997c4 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab09.svg b/public/static/images/canvas/shape/90deg/plane_tab09.svg new file mode 100644 index 00000000..bd4c9e53 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab10.svg b/public/static/images/canvas/shape/90deg/plane_tab10.svg new file mode 100644 index 00000000..40417b53 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab11.svg b/public/static/images/canvas/shape/90deg/plane_tab11.svg new file mode 100644 index 00000000..8bb5290a --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab12.svg b/public/static/images/canvas/shape/90deg/plane_tab12.svg new file mode 100644 index 00000000..bece8e29 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab13.svg b/public/static/images/canvas/shape/90deg/plane_tab13.svg new file mode 100644 index 00000000..bcb4307e --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab14.svg b/public/static/images/canvas/shape/90deg/plane_tab14.svg new file mode 100644 index 00000000..8d79bf02 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab15.svg b/public/static/images/canvas/shape/90deg/plane_tab15.svg new file mode 100644 index 00000000..4beac542 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab16.svg b/public/static/images/canvas/shape/90deg/plane_tab16.svg new file mode 100644 index 00000000..ed0456df --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab17.svg b/public/static/images/canvas/shape/90deg/plane_tab17.svg new file mode 100644 index 00000000..3fdb6160 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab18.svg b/public/static/images/canvas/shape/90deg/plane_tab18.svg new file mode 100644 index 00000000..2072da99 --- /dev/null +++ b/public/static/images/canvas/shape/90deg/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab01.svg b/public/static/images/canvas/shape/normal/plane_tab01.svg new file mode 100644 index 00000000..121b7025 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab01.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab02.svg b/public/static/images/canvas/shape/normal/plane_tab02.svg new file mode 100644 index 00000000..61891248 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab03.svg b/public/static/images/canvas/shape/normal/plane_tab03.svg new file mode 100644 index 00000000..295e0d89 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab04.svg b/public/static/images/canvas/shape/normal/plane_tab04.svg new file mode 100644 index 00000000..894bb55c --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab05.svg b/public/static/images/canvas/shape/normal/plane_tab05.svg new file mode 100644 index 00000000..63b3c201 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab06.svg b/public/static/images/canvas/shape/normal/plane_tab06.svg new file mode 100644 index 00000000..1bad98a0 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab07.svg b/public/static/images/canvas/shape/normal/plane_tab07.svg new file mode 100644 index 00000000..a358f766 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab08.svg b/public/static/images/canvas/shape/normal/plane_tab08.svg new file mode 100644 index 00000000..22a72ab6 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab09.svg b/public/static/images/canvas/shape/normal/plane_tab09.svg new file mode 100644 index 00000000..756c3bfa --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab10.svg b/public/static/images/canvas/shape/normal/plane_tab10.svg new file mode 100644 index 00000000..fe4073ea --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab11.svg b/public/static/images/canvas/shape/normal/plane_tab11.svg new file mode 100644 index 00000000..0ac2cf59 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab12.svg b/public/static/images/canvas/shape/normal/plane_tab12.svg new file mode 100644 index 00000000..a68e7a39 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab13.svg b/public/static/images/canvas/shape/normal/plane_tab13.svg new file mode 100644 index 00000000..027e91e8 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab14.svg b/public/static/images/canvas/shape/normal/plane_tab14.svg new file mode 100644 index 00000000..7a3cef86 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab15.svg b/public/static/images/canvas/shape/normal/plane_tab15.svg new file mode 100644 index 00000000..c0c1b0bb --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab16.svg b/public/static/images/canvas/shape/normal/plane_tab16.svg new file mode 100644 index 00000000..c66484e3 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab17.svg b/public/static/images/canvas/shape/normal/plane_tab17.svg new file mode 100644 index 00000000..ae8ddd0f --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab18.svg b/public/static/images/canvas/shape/normal/plane_tab18.svg new file mode 100644 index 00000000..12bd0ad3 --- /dev/null +++ b/public/static/images/canvas/shape/normal/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab01.svg b/public/static/images/canvas/shape/re_180deg/plane_tab01.svg new file mode 100644 index 00000000..aab78f30 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab01.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab02.svg b/public/static/images/canvas/shape/re_180deg/plane_tab02.svg new file mode 100644 index 00000000..53390298 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab03.svg b/public/static/images/canvas/shape/re_180deg/plane_tab03.svg new file mode 100644 index 00000000..1e054827 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab04.svg b/public/static/images/canvas/shape/re_180deg/plane_tab04.svg new file mode 100644 index 00000000..1144da35 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab05.svg b/public/static/images/canvas/shape/re_180deg/plane_tab05.svg new file mode 100644 index 00000000..14546582 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab06.svg b/public/static/images/canvas/shape/re_180deg/plane_tab06.svg new file mode 100644 index 00000000..0eb57a1f --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab07.svg b/public/static/images/canvas/shape/re_180deg/plane_tab07.svg new file mode 100644 index 00000000..978ec35a --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab08.svg b/public/static/images/canvas/shape/re_180deg/plane_tab08.svg new file mode 100644 index 00000000..1de4559c --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab09.svg b/public/static/images/canvas/shape/re_180deg/plane_tab09.svg new file mode 100644 index 00000000..1f985b96 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab10.svg b/public/static/images/canvas/shape/re_180deg/plane_tab10.svg new file mode 100644 index 00000000..b8c9f9f4 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab11.svg b/public/static/images/canvas/shape/re_180deg/plane_tab11.svg new file mode 100644 index 00000000..353359a2 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab12.svg b/public/static/images/canvas/shape/re_180deg/plane_tab12.svg new file mode 100644 index 00000000..50e211f2 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab13.svg b/public/static/images/canvas/shape/re_180deg/plane_tab13.svg new file mode 100644 index 00000000..de614d35 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab14.svg b/public/static/images/canvas/shape/re_180deg/plane_tab14.svg new file mode 100644 index 00000000..902506e5 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab15.svg b/public/static/images/canvas/shape/re_180deg/plane_tab15.svg new file mode 100644 index 00000000..81839b00 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab16.svg b/public/static/images/canvas/shape/re_180deg/plane_tab16.svg new file mode 100644 index 00000000..df7fe001 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab17.svg b/public/static/images/canvas/shape/re_180deg/plane_tab17.svg new file mode 100644 index 00000000..a684fd04 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab18.svg b/public/static/images/canvas/shape/re_180deg/plane_tab18.svg new file mode 100644 index 00000000..a3259150 --- /dev/null +++ b/public/static/images/canvas/shape/re_180deg/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab01.svg b/public/static/images/canvas/shape/re_270deg/plane_tab01.svg new file mode 100644 index 00000000..c225ea23 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab01.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab02.svg b/public/static/images/canvas/shape/re_270deg/plane_tab02.svg new file mode 100644 index 00000000..01b79908 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab03.svg b/public/static/images/canvas/shape/re_270deg/plane_tab03.svg new file mode 100644 index 00000000..dc0c23e7 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab04.svg b/public/static/images/canvas/shape/re_270deg/plane_tab04.svg new file mode 100644 index 00000000..5f61b284 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab05.svg b/public/static/images/canvas/shape/re_270deg/plane_tab05.svg new file mode 100644 index 00000000..d02eb0fb --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab06.svg b/public/static/images/canvas/shape/re_270deg/plane_tab06.svg new file mode 100644 index 00000000..d1ddabf5 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab07.svg b/public/static/images/canvas/shape/re_270deg/plane_tab07.svg new file mode 100644 index 00000000..bf213a02 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab08.svg b/public/static/images/canvas/shape/re_270deg/plane_tab08.svg new file mode 100644 index 00000000..cd9858e8 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab09.svg b/public/static/images/canvas/shape/re_270deg/plane_tab09.svg new file mode 100644 index 00000000..f82ee8cc --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab10.svg b/public/static/images/canvas/shape/re_270deg/plane_tab10.svg new file mode 100644 index 00000000..64444c46 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab11.svg b/public/static/images/canvas/shape/re_270deg/plane_tab11.svg new file mode 100644 index 00000000..bbd8fb3a --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab12.svg b/public/static/images/canvas/shape/re_270deg/plane_tab12.svg new file mode 100644 index 00000000..77321b0c --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab13.svg b/public/static/images/canvas/shape/re_270deg/plane_tab13.svg new file mode 100644 index 00000000..9e0fd3bb --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab14.svg b/public/static/images/canvas/shape/re_270deg/plane_tab14.svg new file mode 100644 index 00000000..921db3d0 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab15.svg b/public/static/images/canvas/shape/re_270deg/plane_tab15.svg new file mode 100644 index 00000000..caaad067 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab16.svg b/public/static/images/canvas/shape/re_270deg/plane_tab16.svg new file mode 100644 index 00000000..4fb31cf5 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab17.svg b/public/static/images/canvas/shape/re_270deg/plane_tab17.svg new file mode 100644 index 00000000..56465c10 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab18.svg b/public/static/images/canvas/shape/re_270deg/plane_tab18.svg new file mode 100644 index 00000000..83868560 --- /dev/null +++ b/public/static/images/canvas/shape/re_270deg/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab01.svg b/public/static/images/canvas/shape/re_90deg/plane_tab01.svg new file mode 100644 index 00000000..36c1d46b --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab01.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab02.svg b/public/static/images/canvas/shape/re_90deg/plane_tab02.svg new file mode 100644 index 00000000..74d5a79c --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab03.svg b/public/static/images/canvas/shape/re_90deg/plane_tab03.svg new file mode 100644 index 00000000..7db0ea6e --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab04.svg b/public/static/images/canvas/shape/re_90deg/plane_tab04.svg new file mode 100644 index 00000000..19194f44 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab05.svg b/public/static/images/canvas/shape/re_90deg/plane_tab05.svg new file mode 100644 index 00000000..787b4dd2 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab06.svg b/public/static/images/canvas/shape/re_90deg/plane_tab06.svg new file mode 100644 index 00000000..311178db --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab07.svg b/public/static/images/canvas/shape/re_90deg/plane_tab07.svg new file mode 100644 index 00000000..91d6dc11 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab08.svg b/public/static/images/canvas/shape/re_90deg/plane_tab08.svg new file mode 100644 index 00000000..05cebb84 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab09.svg b/public/static/images/canvas/shape/re_90deg/plane_tab09.svg new file mode 100644 index 00000000..917eb40e --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab10.svg b/public/static/images/canvas/shape/re_90deg/plane_tab10.svg new file mode 100644 index 00000000..964f6b05 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab11.svg b/public/static/images/canvas/shape/re_90deg/plane_tab11.svg new file mode 100644 index 00000000..0e8112eb --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab12.svg b/public/static/images/canvas/shape/re_90deg/plane_tab12.svg new file mode 100644 index 00000000..6481f3fe --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab13.svg b/public/static/images/canvas/shape/re_90deg/plane_tab13.svg new file mode 100644 index 00000000..6c7a85fb --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab14.svg b/public/static/images/canvas/shape/re_90deg/plane_tab14.svg new file mode 100644 index 00000000..32f8d9a9 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab15.svg b/public/static/images/canvas/shape/re_90deg/plane_tab15.svg new file mode 100644 index 00000000..07217d6c --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab16.svg b/public/static/images/canvas/shape/re_90deg/plane_tab16.svg new file mode 100644 index 00000000..b9c7230b --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab17.svg b/public/static/images/canvas/shape/re_90deg/plane_tab17.svg new file mode 100644 index 00000000..f36070a0 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab18.svg b/public/static/images/canvas/shape/re_90deg/plane_tab18.svg new file mode 100644 index 00000000..33bc4549 --- /dev/null +++ b/public/static/images/canvas/shape/re_90deg/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab01.svg b/public/static/images/canvas/shape/re_normal/plane_tab01.svg new file mode 100644 index 00000000..8fc73ac0 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab01.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab02.svg b/public/static/images/canvas/shape/re_normal/plane_tab02.svg new file mode 100644 index 00000000..61891248 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab02.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab03.svg b/public/static/images/canvas/shape/re_normal/plane_tab03.svg new file mode 100644 index 00000000..c6a52c40 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab03.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab04.svg b/public/static/images/canvas/shape/re_normal/plane_tab04.svg new file mode 100644 index 00000000..71f194d0 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab04.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab05.svg b/public/static/images/canvas/shape/re_normal/plane_tab05.svg new file mode 100644 index 00000000..8abc166e --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab06.svg b/public/static/images/canvas/shape/re_normal/plane_tab06.svg new file mode 100644 index 00000000..6aca72a5 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab06.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab07.svg b/public/static/images/canvas/shape/re_normal/plane_tab07.svg new file mode 100644 index 00000000..577ae1b1 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab07.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab08.svg b/public/static/images/canvas/shape/re_normal/plane_tab08.svg new file mode 100644 index 00000000..d9f3f324 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab08.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab09.svg b/public/static/images/canvas/shape/re_normal/plane_tab09.svg new file mode 100644 index 00000000..94f2ea1c --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab09.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab10.svg b/public/static/images/canvas/shape/re_normal/plane_tab10.svg new file mode 100644 index 00000000..0b051e22 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab10.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab11.svg b/public/static/images/canvas/shape/re_normal/plane_tab11.svg new file mode 100644 index 00000000..64b6796d --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab11.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab12.svg b/public/static/images/canvas/shape/re_normal/plane_tab12.svg new file mode 100644 index 00000000..8885243b --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab12.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab13.svg b/public/static/images/canvas/shape/re_normal/plane_tab13.svg new file mode 100644 index 00000000..3537d722 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab13.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab14.svg b/public/static/images/canvas/shape/re_normal/plane_tab14.svg new file mode 100644 index 00000000..440f09d1 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab15.svg b/public/static/images/canvas/shape/re_normal/plane_tab15.svg new file mode 100644 index 00000000..ff005996 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab15.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab16.svg b/public/static/images/canvas/shape/re_normal/plane_tab16.svg new file mode 100644 index 00000000..4ac68a72 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab16.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab17.svg b/public/static/images/canvas/shape/re_normal/plane_tab17.svg new file mode 100644 index 00000000..81b89809 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab17.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab18.svg b/public/static/images/canvas/shape/re_normal/plane_tab18.svg new file mode 100644 index 00000000..34d44490 --- /dev/null +++ b/public/static/images/canvas/shape/re_normal/plane_tab18.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_labrary01.svg b/public/static/images/canvas/shape_labrary01.svg new file mode 100644 index 00000000..c55fecfc --- /dev/null +++ b/public/static/images/canvas/shape_labrary01.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/images/canvas/shape_labrary02.svg b/public/static/images/canvas/shape_labrary02.svg new file mode 100644 index 00000000..88e1eadc --- /dev/null +++ b/public/static/images/canvas/shape_labrary02.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/canvas/shape_labrary03.svg b/public/static/images/canvas/shape_labrary03.svg new file mode 100644 index 00000000..194fd06b --- /dev/null +++ b/public/static/images/canvas/shape_labrary03.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/canvas/shape_menu01.svg b/public/static/images/canvas/shape_menu01.svg new file mode 100644 index 00000000..6fbe44cc --- /dev/null +++ b/public/static/images/canvas/shape_menu01.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_menu02.svg b/public/static/images/canvas/shape_menu02.svg new file mode 100644 index 00000000..36a5eb41 --- /dev/null +++ b/public/static/images/canvas/shape_menu02.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_menu03.svg b/public/static/images/canvas/shape_menu03.svg new file mode 100644 index 00000000..ae7701c3 --- /dev/null +++ b/public/static/images/canvas/shape_menu03.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_menu04.svg b/public/static/images/canvas/shape_menu04.svg new file mode 100644 index 00000000..e23282c5 --- /dev/null +++ b/public/static/images/canvas/shape_menu04.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_menu05.svg b/public/static/images/canvas/shape_menu05.svg new file mode 100644 index 00000000..500d6bc6 --- /dev/null +++ b/public/static/images/canvas/shape_menu05.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_menu06.svg b/public/static/images/canvas/shape_menu06.svg new file mode 100644 index 00000000..a13e1b6c --- /dev/null +++ b/public/static/images/canvas/shape_menu06.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_menu07.svg b/public/static/images/canvas/shape_menu07.svg new file mode 100644 index 00000000..08119e5e --- /dev/null +++ b/public/static/images/canvas/shape_menu07.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape_menu08.svg b/public/static/images/canvas/shape_menu08.svg new file mode 100644 index 00000000..4588b3bb --- /dev/null +++ b/public/static/images/canvas/shape_menu08.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/main/login_email.svg b/public/static/images/main/login_email.svg new file mode 100644 index 00000000..1ea1a274 --- /dev/null +++ b/public/static/images/main/login_email.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/images/sub/address_search.svg b/public/static/images/sub/address_search.svg new file mode 100644 index 00000000..4c0e2d1e --- /dev/null +++ b/public/static/images/sub/address_search.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/static/images/sub/attachment_ico.svg b/public/static/images/sub/attachment_ico.svg new file mode 100644 index 00000000..7e622a4e --- /dev/null +++ b/public/static/images/sub/attachment_ico.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/static/images/sub/click_check_ico.svg b/public/static/images/sub/click_check_ico.svg new file mode 100644 index 00000000..4fc2dae1 --- /dev/null +++ b/public/static/images/sub/click_check_ico.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/sub/community_clip.svg b/public/static/images/sub/community_clip.svg new file mode 100644 index 00000000..50092a01 --- /dev/null +++ b/public/static/images/sub/community_clip.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/sub/community_pop_close.svg b/public/static/images/sub/community_pop_close.svg new file mode 100644 index 00000000..e04458f2 --- /dev/null +++ b/public/static/images/sub/community_pop_close.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/static/images/sub/community_search.svg b/public/static/images/sub/community_search.svg new file mode 100644 index 00000000..e83caf34 --- /dev/null +++ b/public/static/images/sub/community_search.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/static/images/sub/file_down_btn.svg b/public/static/images/sub/file_down_btn.svg new file mode 100644 index 00000000..3159305a --- /dev/null +++ b/public/static/images/sub/file_down_btn.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/sub/grid-btn-excel.svg b/public/static/images/sub/grid-btn-excel.svg new file mode 100644 index 00000000..11f5bebc --- /dev/null +++ b/public/static/images/sub/grid-btn-excel.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/sub/grid-btn-file.svg b/public/static/images/sub/grid-btn-file.svg new file mode 100644 index 00000000..bf4edf88 --- /dev/null +++ b/public/static/images/sub/grid-btn-file.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/static/images/sub/grid_tip.svg b/public/static/images/sub/grid_tip.svg new file mode 100644 index 00000000..d60455dd --- /dev/null +++ b/public/static/images/sub/grid_tip.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/sub/information_help.svg b/public/static/images/sub/information_help.svg new file mode 100644 index 00000000..9eb16941 --- /dev/null +++ b/public/static/images/sub/information_help.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/static/images/sub/minus_btn.svg b/public/static/images/sub/minus_btn.svg new file mode 100644 index 00000000..e31ddaf9 --- /dev/null +++ b/public/static/images/sub/minus_btn.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/static/images/sub/plus_btn.svg b/public/static/images/sub/plus_btn.svg new file mode 100644 index 00000000..7f17a1f1 --- /dev/null +++ b/public/static/images/sub/plus_btn.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/app/QcastProvider.js b/src/app/QcastProvider.js index f9431eb6..3ae0993d 100644 --- a/src/app/QcastProvider.js +++ b/src/app/QcastProvider.js @@ -16,15 +16,11 @@ export const QcastProvider = ({ children }) => { 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 ( diff --git a/src/app/community/archive/page.jsx b/src/app/community/archive/page.jsx index 6917f228..308e02f3 100644 --- a/src/app/community/archive/page.jsx +++ b/src/app/community/archive/page.jsx @@ -7,10 +7,7 @@ export default async function CommunityArchivePage() { return ( <> - -
- -
+ ) } diff --git a/src/app/community/faq/page.jsx b/src/app/community/faq/page.jsx index 2b9d5452..054f9007 100644 --- a/src/app/community/faq/page.jsx +++ b/src/app/community/faq/page.jsx @@ -1,4 +1,3 @@ -import Hero from '@/components/Hero' import Faq from '@/components/community/Faq' import { initCheck } from '@/util/session-util' @@ -7,10 +6,7 @@ export default async function CommunityFaqPage() { return ( <> - -
- -
+ ) } diff --git a/src/app/community/notice/page.jsx b/src/app/community/notice/page.jsx index d2157b20..a3453e64 100644 --- a/src/app/community/notice/page.jsx +++ b/src/app/community/notice/page.jsx @@ -1,4 +1,3 @@ -import Hero from '@/components/Hero' import Notice from '@/components/community/Notice' import { initCheck } from '@/util/session-util' @@ -7,10 +6,7 @@ export default async function CommunityNoticePage() { return ( <> - -
- -
+ ) } diff --git a/src/app/join/complete/page.jsx b/src/app/join/complete/page.jsx index 3f9fc462..3f134e58 100644 --- a/src/app/join/complete/page.jsx +++ b/src/app/join/complete/page.jsx @@ -1,19 +1,9 @@ -'use client' - -import { useMessage } from '@/hooks/useMessage' - -export default function CompletePage() { - const { getMessage } = useMessage() +import JoinComplete from '@/components/auth/JoinComplete' +export default function JoinCompletePage() { 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 index 118a25b4..c8d2424b 100644 --- a/src/app/join/page.jsx +++ b/src/app/join/page.jsx @@ -1,5 +1,9 @@ import Join from '@/components/auth/Join' export default function JoinPage() { - return <>{} + return ( + <> + + + ) } diff --git a/src/app/layout.js b/src/app/layout.js index b77e75d0..d27522fe 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -4,7 +4,6 @@ import { headers } from 'next/headers' import { redirect } from 'next/navigation' import { getSession } from '@/lib/authActions' import RecoilRootWrapper from './RecoilWrapper' -import UIProvider from './UIProvider' import { ToastContainer } from 'react-toastify' @@ -14,6 +13,7 @@ import QModal from '@/components/common/modal/QModal' import './globals.css' import '../styles/style.scss' +import '../styles/contents.scss' import Dimmed from '@/components/ui/Dimmed' // const inter = Inter({ subsets: ['latin'] }) @@ -48,6 +48,8 @@ export default async function RootLayout({ children }) { telNo: session.telNo, fax: session.fax, email: session.email, + storeLvl: session.storeLvl, + groupId: session.groupId, pwdInitYn: session.pwdInitYn, isLoggedIn: session.isLoggedIn, } @@ -61,16 +63,22 @@ export default async function RootLayout({ children }) { - {/*{headerPathname !== '/login' && }*/} -
-
- + {headerPathname === '/login' || headerPathname === '/join' ? ( + {children} + ) : ( +
+
{children}
- -
+
+
+ COPYRIGHT©2024 Hanwha Japan All Rights Reserved. +
+
+
+ )} diff --git a/src/app/page.js b/src/app/page.js index 25cd8640..767679b0 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -3,9 +3,9 @@ import { getSession } from '@/lib/authActions' export default async function Home() { const session = await getSession() - const mainPageProps = { isLoggedIn: session?.isLoggedIn, + pwdInitYn: session?.pwdInitYn, } return ( diff --git a/src/common/common.js b/src/common/common.js index 84cf60a3..ebb394d3 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -17,6 +17,7 @@ export const MENU = { SLOPE_SETTING: 'slopeSetting', // 경사 설정 BATCH_DRAWING: 'batchDrawing', // 배치면 그리기 SURFACE_SHAPE_BATCH: 'surfaceShapeBatch', // 면형상 배치 + SURFACE_SHAPE_BATCH_TEMP: 'surfaceShapeBatchTemp', // 면형상 배치 임시 OBJECT_BATCH: 'objectBatch', // 오브젝트 배치 ALL_REMOVE: 'allRemove', // 전체 삭제 DEFAULT: 'batchCanvasDefault', // default @@ -53,8 +54,9 @@ export const Mode = { export const LINE_TYPE = { WALLLINE: { /** - * 처마 / 캐라바 / 벽 / 팔작지붕 / 반절처 / 한쪽흐름 + * 없음 / 처마 / 캐라바 / 벽 / 팔작지붕 / 반절처 / 한쪽흐름 */ + DEFAULT: 'default', EAVES: 'eaves', GABLE: 'gable', WALL: 'wall', @@ -91,10 +93,21 @@ export const LineType = { // 오브젝트 배치 > 개구배치, 그림자배치 export const BATCH_TYPE = { OPENING: 'opening', + OPENING_TEMP: 'openingTemp', SHADOW: 'shadow', + SHADOW_TEMP: 'shadowTemp', + TRIANGLE_DORMER: 'triangleDormer', + TRIANGLE_DORMER_TEMP: 'triangleDormerTemp', + PENTAGON_DORMER: 'pentagonDormer', + PENTAGON_DORMER_TEMP: 'pentagonDormerTemp', } // 오브젝트 배치 > 프리입력, 치수입력 export const INPUT_TYPE = { FREE: 'free', DIMENSION: 'dimension', } + +export const POLYGON_TYPE = { + ROOF: 'roof', + TRESTLE: 'trestle', +} diff --git a/src/components/GridSettingsModal.jsx b/src/components/GridSettingsModal.jsx index 35bb1793..92b2e618 100644 --- a/src/components/GridSettingsModal.jsx +++ b/src/components/GridSettingsModal.jsx @@ -6,6 +6,7 @@ import { guideLineState, horiGuideLinesState, vertGuideLinesState } from '@/stor import { fabric } from 'fabric' import { ColorPicker, useColor } from 'react-color-palette' import 'react-color-palette/css' +import { gridColorState } from '@/store/gridAtom' export default function GridSettingsModal(props) { const { canvasProps } = props @@ -23,7 +24,7 @@ export default function GridSettingsModal(props) { const gridSettingArray = [] - const [guideColor, setGuideColor] = useColor('rgb(200, 15, 15)') + const gridColor = useRecoilValue(gridColorState) const [colorPickerShow, setColorPickerShow] = useState(false) const boxStyle = { @@ -67,7 +68,7 @@ export default function GridSettingsModal(props) { const horizontalLine = new fabric.Line( [0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2], { - stroke: guideColor.hex, + stroke: gridColor, strokeWidth: 1, selectable: true, lockMovementX: true, @@ -89,7 +90,7 @@ export default function GridSettingsModal(props) { const verticalLine = new fabric.Line( [i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height], { - stroke: guideColor.hex, + stroke: gridColor, strokeWidth: 1, selectable: true, lockMovementX: true, diff --git a/src/components/InitSettingsModal.jsx b/src/components/InitSettingsModal.jsx index 58f0163f..5f0837a8 100644 --- a/src/components/InitSettingsModal.jsx +++ b/src/components/InitSettingsModal.jsx @@ -6,7 +6,6 @@ import { useRecoilState, useRecoilValue } from 'recoil' import { modalContent, modalState } from '@/store/modalAtom' import { canvasSettingState } from '@/store/canvasAtom' import { useAxios } from '@/hooks/useAxios' -import { get, post } from '@/lib/Axios' export default function InitSettingsModal(props) { const [objectNo, setObjectNo] = useState('test123240909003') // 후에 삭제 필요 @@ -25,6 +24,8 @@ export default function InitSettingsModal(props) { setOpen, } + const { get, post } = useAxios() + //const { get, post } = useAxios() useEffect(() => { diff --git a/src/components/Main.jsx b/src/components/Main.jsx index 4546f32d..76676cd1 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -1,9 +1,161 @@ 'use client' +import React, { useEffect, useState } from 'react' + +import { useRouter } from 'next/navigation' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { modalContent, modalState, modalProps } from '@/store/modalAtom' +import { sessionStore } from '@/store/commonAtom' +import { useAxios } from '@/hooks/useAxios' +import { globalLocaleStore } from '@/store/localeAtom' +import MainContents from './main/MainContents' +import { useMessage } from '@/hooks/useMessage' +import { stuffSearchState } from '@/store/stuffAtom' +import { useForm } from 'react-hook-form' +import '@/styles/contents.scss' +import ChangePasswordPop from './main/ChangePasswordPop' +import { searchState } from '@/store/boardAtom' +export default function MainPage() { + const [sessionState, setSessionState] = useRecoilState(sessionStore) + + const globalLocaleState = useRecoilValue(globalLocaleStore) + + const { get } = useAxios(globalLocaleState) + const router = useRouter() + const { getMessage } = useMessage() + + const [searchTxt, setSearchTxt] = useState('') + + const [searchRadioType, setSearchRadioType] = useState('object') + //컨텐츠 관련 + const [saleStoreId, setSaleStoreId] = useState('') + const [saleStoreName, setSaleStoreName] = useState('') + + const [objectList, setObjectList] = useState([]) + const [businessCharger, setBusinessCharger] = useState('') + const [businessChargerMail, setBusinessChargerMail] = useState('') + const [businessChargerTel, setBusinessChargerTel] = useState('') + + const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) + + const [searchForm, setSearchForm] = useRecoilState(searchState) + + useEffect(() => { + if (sessionState.pwdInitYn === 'Y') { + fetchObjectList() + } + }, [sessionState]) + + const fetchObjectList = async () => { + try { + // const apiUrl = `/api/main-page/object/X167/list` + const apiUrl = `/api/main-page/object/${sessionState?.storeId}/list` + const res = await get({ url: apiUrl }) + if (res) { + setSaleStoreId(res.saleStoreId) + setSaleStoreName(res.saleStoreName) + setObjectList(res.objectList) + setBusinessCharger(res.businessCharger) + setBusinessChargerMail(res.businessChargerMail) + setBusinessChargerTel(res.businessChargerTel) + } + } catch (error) { + console.error('MAIN API fetching error:', error) + } + } + + // 엔터 이벤트 + const handleByOnKeyUp = (e) => { + if (e.key === 'Enter') { + //물건번호 일떄 + if (searchRadioType === 'object') { + setStuffSearch({ + ...stuffSearch, + schObjectNo: searchTxt, + code: 'M', + }) + router.push('/management/stuff') + } else { + setSearchForm({ ...searchForm, searchValue: searchTxt, mainFlag: 'Y' }) + router.push('/community/faq') + } + } + } + + // 라디오 변경 이벤트 + const handleOnChangeRadio = (e) => { + setSearchRadioType(e.target.value) + } + + // 돋보기 클릭 + const handleOnSubmit = () => { + if (searchRadioType === 'object') { + setStuffSearch({ + ...stuffSearch, + schObjectNo: searchTxt, + code: 'M', + }) + + router.push('/management/stuff') + } else { + setSearchForm({ ...searchForm, searchValue: searchTxt, mainFlag: 'Y' }) + router.push('/community/faq') + } + } -export default function MainPage(props) { return ( <> -

Main page

+ {(sessionState?.pwdInitYn !== 'N' && ( + <> +
+
+
+
+
+ {getMessage('main.storeId')}/ {getMessage('main.storeName')} +
+
+ +
+ {saleStoreId} / {saleStoreName} +
+
+
+
+
+ + +
+
+ + +
+
+
+ { + setSearchTxt(e.target.value) + }} + /> + +
+
+ +
+ + )) || ( + <> + + + )} ) } diff --git a/src/components/Playground.jsx b/src/components/Playground.jsx index 200a0337..6393158d 100644 --- a/src/components/Playground.jsx +++ b/src/components/Playground.jsx @@ -1,6 +1,6 @@ 'use client' -import { useRef, useState } from 'react' +import { useRef, useState, useEffect } from 'react' import { useRecoilState } from 'recoil' import { v4 as uuidv4 } from 'uuid' import { FaAnglesUp } from 'react-icons/fa6' @@ -11,7 +11,6 @@ import { useMessage } from '@/hooks/useMessage' import { convertDwgToPng } from '@/lib/cadAction' import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom' -import QSelect from '@/components/ui/QSelect' import { Button } from '@nextui-org/react' import ColorPicker from './common/color-picker/ColorPicker' import { useSwal } from '@/hooks/useSwal' @@ -19,6 +18,10 @@ import { useSwal } from '@/hooks/useSwal' import styles from './playground.module.css' import Image from 'next/image' +import QInput from './common/input/Qinput' +import QSelect from './common/select/QSelect' +import QPagination from './common/pagination/QPagination' + export default function Playground() { const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) @@ -35,6 +38,24 @@ export default function Playground() { const [color, setColor] = useState('#ff0000') + const [textInput, setTextInput] = useState('') + const [radioInput, setRadioInput] = useState('') + const [checkboxInput, setCheckboxInput] = useState([]) + const [selectedValue, setSelectedValue] = useState('') + + useEffect(() => { + console.log('textInput:', textInput) + }, [textInput]) + useEffect(() => { + console.log('radioInput:', radioInput) + }, [radioInput]) + useEffect(() => { + console.log('checkboxInput:', checkboxInput) + }, [checkboxInput]) + useEffect(() => { + console.log('selectedValue:', selectedValue) + }, [selectedValue]) + const handleUsers = async () => { // const users = await get('/api/user/find-all') const params = { @@ -111,12 +132,113 @@ export default function Playground() { }) } + const paginationProps = { + pageNo: 1, + pageSize: 10, + pagePerBlock: 10, + totalCount: 501, + handleChangePage: (page) => { + console.log('page', page) + }, + } + return ( <>
이 영역은 테스트입니다.
- + + + +
+ + +
+ + +
+
+
+ + + +
{testVar}
@@ -180,6 +302,9 @@ export default function Playground() { Sweetalert - confirm
+
+ +
) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index bf63b348..fbe61038 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -39,7 +39,7 @@ import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMen import InitSettingsModal from './InitSettingsModal' import GridSettingsModal from './GridSettingsModal' import { SurfaceShapeModal } from '@/components/ui/SurfaceShape' -import { changeAllGableRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils' +import { changeAllHipAndGableRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils' import ThumbnailList from '@/components/ui/ThumbnailLIst' import ObjectPlacement from '@/components/ui/ObjectPlacement' import { globalLocaleStore } from '@/store/localeAtom' @@ -144,10 +144,10 @@ export default function Roof2(props) { useEffect(() => { get({ url: `/api/canvas-management/canvas-statuses/by-object/test123240822001/${userId}` }).then((res) => { - console.log(res) + // console.log(res) const arrangeData = res.map((item) => { - console.log(item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '')) + // console.log(item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '')) const test = item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '') const test2 = test.substring(1, test.length - 1) return { diff --git a/src/components/auth/Join.jsx b/src/components/auth/Join.jsx index 03fc8ecb..3412efdb 100644 --- a/src/components/auth/Join.jsx +++ b/src/components/auth/Join.jsx @@ -1,29 +1,28 @@ 'use client' -import { post } from '@/lib/Axios' -import { redirect } from 'next/navigation' +import { useAxios } from '@/hooks/useAxios' +import { useRouter } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' +import Cookies from 'js-cookie' export default function Join() { const { getMessage } = useMessage() + const { promisePost } = useAxios() + const router = useRouter() + + // 가입 신청 + const joinProcess = async (e) => { + e.preventDefault() + const formData = new FormData(e.target) - const joinProcess = async (formData) => { const param = { - langCd: 'JA', - lastEditUser: formData.get('userId'), storeQcastNm: formData.get('storeQcastNm'), storeQcastNmKana: formData.get('storeQcastNmKana'), postCd: formData.get('postCd'), addr: formData.get('addr'), telNo: formData.get('telNo'), fax: formData.get('fax'), - payTermsCd: 'JB02', - kamId: 'E1101011', - qtCompNm: formData.get('qtCompNm'), - qtPostCd: formData.get('qtPostCd'), - qtAddr: formData.get('qtAddr'), - qtTelNo: formData.get('qtTelNo'), - qtFax: formData.get('qtFax'), + bizNo: formData.get('bizNo'), userInfo: { userId: formData.get('userId'), userNm: formData.get('userNm'), @@ -35,287 +34,268 @@ export default function Join() { }, } - await post({ url: '/api/login/v1.0/user/join', data: param }).then((res) => { - if (res) { - if (res.result.resultCode == 'S') { - redirect('/join/complete') - } else { - alert(res.result.resultMsg) + await promisePost({ url: '/api/login/v1.0/user/join', data: param }) + .then((res) => { + if (res) { + if (res.data.result.resultCode == 'S') { + Cookies.set('joinEmail', formData.get('email'), { expires: 1 }) + router.push('/join/complete') + } else { + alert(res.data.result.resultMsg) + } } - } - }) + }) + .catch((error) => { + alert(error.response.data.message) + }) } return ( -
-

{getMessage('join.title')}

-
-
-
- ● {getMessage('join.sub1.title')} (*{getMessage('common.require')}) {getMessage('join.sub1.comment')} +
+
+ +
{getMessage('join.title')}
+
+
+
+

+ {getMessage('join.sub1.title')} (*{getMessage('common.require')}) +

+ {getMessage('join.sub1.comment')} +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {getMessage('join.sub1.storeQcastNm')} * + +
+ +
+
+ {getMessage('join.sub1.storeQcastNmKana')} * + +
+ +
+
+ {getMessage('join.sub1.postCd')}/{getMessage('join.sub1.addr')} * + +
+
+ +
+
+ +
+
+
+ {getMessage('join.sub1.telNo')} * + +
+ +
+
+ {getMessage('join.sub1.fax')} * + +
+ +
+
{getMessage('join.sub1.bizNo')} +
+ +
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
{getMessage('join.sub1.storeQcastNm')} * - -
{getMessage('join.sub1.storeQcastNmKana')} * - -
- {getMessage('join.sub1.postCd')}/{getMessage('join.sub1.addr')} * - - - -
{getMessage('join.sub1.telNo')} * - -
{getMessage('join.sub1.fax')} * - -
- -
- ● {getMessage('join.sub2.title')} (*{getMessage('common.require')}) +
+
+
+

+ {getMessage('join.sub2.title')} (*{getMessage('common.require')}) +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {getMessage('join.sub2.userNm')} * + +
+ +
+
{getMessage('join.sub2.userNmKana')} +
+ +
+
+ {getMessage('join.sub2.userId')} * + +
+ +
+
+ {getMessage('join.sub2.email')} * + +
+ +
+
+ {getMessage('join.sub2.telNo')} * + +
+ +
+
+ {getMessage('join.sub2.fax')} * + +
+ +
+
{getMessage('join.sub2.category')} +
+ +
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{getMessage('join.sub2.userNm')} * - -
{getMessage('join.sub2.userNmKana')} * - -
{getMessage('join.sub2.userId')} * - -
{getMessage('join.sub2.email')} * - -
{getMessage('join.sub2.telNo')} * - -
{getMessage('join.sub2.fax')} * - -
{getMessage('join.sub2.category')} - -
- -
- ● {getMessage('join.sub3.title')} (*{getMessage('common.require')}) +
+ +
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
{getMessage('join.sub3.qtCompNm')} - -
- {getMessage('join.sub3.qtPostCd')}/{getMessage('join.sub3.qtAddr')} - - - -
{getMessage('join.sub3.qtEmail')} - -
{getMessage('join.sub3.qtTelNo')} - -
{getMessage('join.sub3.qtFax')} - -
-
-
- -
- + +
) } diff --git a/src/components/auth/JoinComplete.jsx b/src/components/auth/JoinComplete.jsx new file mode 100644 index 00000000..c876f20a --- /dev/null +++ b/src/components/auth/JoinComplete.jsx @@ -0,0 +1,44 @@ +'use client' + +import { useMessage } from '@/hooks/useMessage' +import { useRouter } from 'next/navigation' +import { useState } from 'react' +import Cookies from 'js-cookie' + +export default function JoinComplete() { + const router = useRouter() + + const { getMessage } = useMessage() + const [emailText, setEmailText] = useState(Cookies.get('joinEmail')) + + return ( + <> +
+
+
+
+
{getMessage('join.complete.title')}
+
{getMessage('join.complete.contents')}
+
+
+ {getMessage('join.complete.email_comment')}: {emailText} +
+
+
+ +
+
+
+
+
+ + ) +} diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index ef9919c7..28416284 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -1,62 +1,80 @@ 'use client' -import { useState } from 'react' +import { useState, useEffect } from 'react' +import Image from 'next/image' +import Link from 'next/link' +import { useRecoilState } from 'recoil' import { useAxios } from '@/hooks/useAxios' import { setSession } from '@/lib/authActions' -import { redirect } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' - -import { Button, Switch } from '@nextui-org/react' -import { useRecoilState } from 'recoil' import { globalLocaleStore } from '@/store/localeAtom' -import { modalContent, modalState } from '@/store/modalAtom' import { sessionStore } from '@/store/commonAtom' +import { useRouter } from 'next/navigation' + +import Cookies from 'js-cookie' + +import { useSearchParams } from 'next/navigation' export default function Login() { - const { patch } = useAxios() + // 자동 로그인 + const initParams = useSearchParams() + const autoLoginParam = initParams.get('autoLoginParam1') + useEffect(() => { + if (autoLoginParam) { + autoLoginProcess(autoLoginParam) + } + }, []) + const autoLoginProcess = async (autoLoginParam) => { + await promisePost({ url: '/api/login/v1.0/user/login/autoLoginDecryptData', data: { loginId: autoLoginParam } }) + .then((res) => { + if (res) { + if (res.data) { + post({ url: '/api/login/v1.0/user', data: { loginId: res.data } }).then((response) => { + if (response) { + const result = { ...response, storeLvl: response.groupId === '60000' ? '1' : '2', pwdInitYn: 'Y' } + setSession(result) + setSessionState(result) + router.push('/') + } else { + router.push('/login') + } + }) + } + } + }) + .catch((error) => { + router.push('/login') + }) + } + + const [userId, setUserId] = useState('') + const [checkId, setCheckId] = useState('') + const [checkEmail, setCheckEmail] = useState('') + + useEffect(() => { + if (Cookies.get('chkLoginId')) { + setUserId(Cookies.get('chkLoginId')) + } + }, []) + + const [chkLoginId, setChkLoginId] = useState(Cookies.get('chkLoginId') ? true : false) + const [passwordVisible, setPasswordVisible] = useState(false) + const router = useRouter() const { getMessage } = useMessage() const [globalLocaleState, setGlbalLocaleState] = useRecoilState(globalLocaleStore) const [sessionState, setSessionState] = useRecoilState(sessionStore) - const [isSelected, setIsSelected] = useState(globalLocaleState === 'ko' ? true : false) - const handleSelected = () => { - if (isSelected) { - setGlbalLocaleState('ja') - } else { - setGlbalLocaleState('ko') - } + const [passwordReset, setPasswordReset] = useState(1) - setIsSelected(!isSelected) - } + const { promisePost, promisePatch, post } = useAxios(globalLocaleState) // login process - const loginProcess = async (formData) => { - const param = { - // langCd: currentLocale - langCd: globalLocaleState, - lastEditUser: formData.get('id'), - loginId: formData.get('id'), - pwd: formData.get('password'), - } - - // await post({ url: '/api/login/v1.0/login', data: param }).then((res) => { - // if (res) { - // if (res.result.resultCode == 'S') { - // // console.log('res.data', res.data) - // // 비밀번호 초기화가 필요한 경우 - // // if (res.data.pwdInitYn != 'Y') { - // // alert('비밀번호 초기화가 필요한 경우') - // // } else { - // setSession(res.data) - // redirect('/') - // // } - // } else { - // alert(res.result.resultMsg) - // } - // } - // }) + const loginProcess = async (e) => { + e.preventDefault() + const formData = new FormData(e.target) + /////////////////////////////////////////////////////////// // 임시 로그인 처리 setSession({ userId: 'NEW016610', @@ -71,9 +89,10 @@ export default function Login() { telNo: '336610', fax: null, email: 't10t@naver.com', - pwdInitYn: 'N', + pwdInitYn: 'Y', + storeLvl: '1', + groupId: '60000', }) - setSessionState({ userId: 'NEW016610', saleStoreId: null, @@ -87,155 +106,230 @@ export default function Login() { telNo: '336610', fax: null, email: 't10t@naver.com', - pwdInitYn: 'N', + pwdInitYn: 'Y', + storeLvl: '1', + groupId: '60000', }) - - redirect('/') + if (chkLoginId) { + Cookies.set('chkLoginId', formData.get('id'), { expires: 7 }) + } else { + Cookies.remove('chkLoginId') + } + router.push('/') // 임시 로그인 처리 끝 + /////////////////////////////////////////////////////////// + + // 로그인 처리 시작 - ** 상단 임시 로그인 추후 삭제 필요 ** + // const param = { + // loginId: formData.get('id'), + // pwd: formData.get('password'), + // } + // await promisePost({ url: '/api/login/v1.0/login', data: param }) + // .then((res) => { + // if (res) { + // if (res.data.result.resultCode === 'S') { + // setSession(res.data.data) + // setSessionState(res.data.data) + // // ID SAVE 체크되어 있는 경우, 쿠키 저장 + // if (chkLoginId) { + // Cookies.set('chkLoginId', formData.get('id'), { expires: 7 }) + // } else { + // Cookies.remove('chkLoginId') + // } + // router.push('/') + // } else { + // alert(res.data.result.resultMsg) + // } + // } + // }) + // .catch((error) => { + // alert(error.response.data.message) + // }) } // 비밀번호 초기화 관련 - const [open, setOpen] = useRecoilState(modalState) - const [contents, setContent] = useRecoilState(modalContent) - - const initPasswordProcess = async (formData) => { + const initPasswordProcess = async () => { const param = { - langCd: currentLocale, - lastEditUser: formData.get('checkId'), - loginId: formData.get('checkId'), - email: formData.get('checkEmail'), + loginId: checkId, + email: checkEmail, } - - await patch({ url: '/api/login/v1.0/user/init-password', data: param }).then((res) => { - if (res) { - if (res.result.resultCode == 'S') { - alert(getMessage('login.init_password.complete_message')) - redirect('/login') - } else { - alert(res.result.resultMsg) - } - } + await promisePatch({ + url: '/api/login/v1.0/user/init-password', + data: param, }) + .then((res) => { + if (res) { + if (res.data.result.resultCode == 'S') { + alert(getMessage('login.init_password.complete_message')) + setCheckId('') + setCheckEmail('') + setPasswordReset(1) + } else { + alert(res.data.result.resultMsg) + } + } + }) + .catch((error) => { + alert(error.response.data.message) + }) } - const initPasswordContent = ( -
-
-

{getMessage('login.init_password.title')}

-

{getMessage('login.init_password.sub_title')}

-
- -
- -
-
- -
-
- -
-
- -
-
-

- -

-
-
- ) - return ( -
-
-
-

{getMessage('site.name')}

-

{getMessage('site.sub_name')}

-
+
+
+ + react + -
-
-
- -
- + {passwordReset === 1 && ( + <> +
+ +
+ {getMessage('site.name')} + {getMessage('site.sub_name')} +
+
+
+ { + setUserId(e.target.value) + }} + /> + +
+
+ { + setPasswordVisible(passwordVisible) + }} + /> + +
+
+ { + setChkLoginId(e.target.checked) + }} + /> + +
+
+ +
+
+ +
+
+ +
+
+ + {getMessage('login.guide.text')} +
+ {getMessage('login.guide.sub1')} {getMessage('login.guide.join.btn')} + {getMessage('login.guide.sub2')} +
+ + )} + {passwordReset === 2 && ( + <> +
+
+ {getMessage('login.init_password.title')} + {getMessage('login.init_password.sub_title')} +
+
+
+ { + setCheckId(e.target.value) + }} + /> + +
+
+ { + setCheckEmail(e.target.value) + }} + placeholder={getMessage('login.init_password.email.placeholder')} + /> + +
+
+ + +
- -
-
- -
-
- -
-
- -
- -
- - -

- -

- -
- - {isSelected ? 'Current Locale: KO' : 'Current Locale: JA'} - -
-
+ + )}
+
COPYRIGHT©2024 Hanwha Japan All Rights Reserved.
) } diff --git a/src/components/common/context-menu/QContextMenu.jsx b/src/components/common/context-menu/QContextMenu.jsx index 9654c514..a86e40af 100644 --- a/src/components/common/context-menu/QContextMenu.jsx +++ b/src/components/common/context-menu/QContextMenu.jsx @@ -1,5 +1,6 @@ 'use client' -import { Children, useEffect, useState } from 'react' +import { useEffect, useState } from 'react' +import '@/styles/contents.scss' export default function QContextMenu(props) { const { contextRef, canvasProps } = props @@ -7,7 +8,7 @@ export default function QContextMenu(props) { // const children = useRecoilValue(modalContent) const [contextMenu, setContextMenu] = useState({ visible: false, x: 0, y: 0 }) - const activeObject = canvasProps.getActiveObject() //액티브된 객체를 가져옴 + const activeObject = canvasProps?.getActiveObject() //액티브된 객체를 가져옴 let contextType = '' @@ -24,24 +25,25 @@ export default function QContextMenu(props) { if (!contextRef.current) return const handleContextMenu = (e) => { - e.preventDefault() //기존 contextmenu 막고 + // e.preventDefault() //기존 contextmenu 막고 setContextMenu({ visible: true, x: e.pageX, y: e.pageY }) - canvasProps.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제 + console.log(111, canvasProps) + canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제 } const handleClick = (e) => { - e.preventDefault() + // e.preventDefault() setContextMenu({ ...contextMenu, visible: false }) } const handleOutsideClick = (e) => { - e.preventDefault() + // e.preventDefault() if (contextMenu.visible && !ref.current.contains(e.target)) { setContextMenu({ ...contextMenu, visible: false }) } } - canvasProps.upperCanvasEl.addEventListener('contextmenu', handleContextMenu) + canvasProps?.upperCanvasEl.addEventListener('contextmenu', handleContextMenu) document.addEventListener('click', handleClick) document.addEventListener('click', handleOutsideClick) @@ -57,7 +59,7 @@ export default function QContextMenu(props) { lockMovementY: false, // Y 축 이동 잠금 }) - canvasProps.on('object:modified', function (e) { + canvasProps?.on('object:modified', function (e) { activeObject.set({ lockMovementX: true, // X 축 이동 잠금 lockMovementY: true, // Y 축 이동 잠금 @@ -89,19 +91,19 @@ export default function QContextMenu(props) { return ( <> {contextMenu.visible && ( -
-
    -
  • handleObjectMove()}> - 이동 -
  • -
  • handleObjectDelete()}> - 삭제 -
  • -
  • handleObjectCopy()}> - 복사 -
  • - {props.children} -
+
+ {/*
    */} + {/*
  • handleObjectMove()}>*/} + {/* 이동*/} + {/*
  • */} + {/*
  • handleObjectDelete()}>*/} + {/* 삭제*/} + {/*
  • */} + {/*
  • handleObjectCopy()}>*/} + {/* 복사*/} + {/*
  • */} + {/*
*/} + {props.children}
)} diff --git a/src/components/common/draggable/withDraggable.jsx b/src/components/common/draggable/withDraggable.jsx index 23195fbe..29952981 100644 --- a/src/components/common/draggable/withDraggable.jsx +++ b/src/components/common/draggable/withDraggable.jsx @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react' import Draggable from 'react-draggable' -export default function WithDraggable({ isShow, children, pos }) { +export default function WithDraggable({ isShow, children, pos, handle = '' }) { const [position, setPosition] = useState({ x: 0, y: 0 }) const handleOnDrag = (e, data) => { @@ -17,7 +17,11 @@ export default function WithDraggable({ isShow, children, pos }) { return ( <> {isShow && ( - handleOnDrag(e, data)}> + handleOnDrag(e, data)} + handle={handle === '' ? '.modal-head' : handle} + > {children} )} diff --git a/src/components/common/input/QInput.jsx b/src/components/common/input/QInput.jsx new file mode 100644 index 00000000..39b8be08 --- /dev/null +++ b/src/components/common/input/QInput.jsx @@ -0,0 +1,68 @@ +'use client' + +import { useCallback } from 'react' + +export default function QInput({ type, readOnly = false, options = [], value, onChange }) { + // options = options || [ + // { + // id: 'one', + // name: 'Option 1', + // value: '111', + // }, + // { + // id: 'two', + // name: 'Option 2', + // value: '222', + // }, + // { + // id: 'three', + // name: 'Option 3', + // value: '333', + // }, + // ] + + const handleChange = useCallback( + (e, optionValue) => { + if (type === 'radio') { + onChange(e.target.value) + } else { + const newValue = value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue] + onChange(newValue) + } + }, + [type, value, onChange], + ) + + const handleTextChange = useCallback( + (e) => { + onChange(e.target.value) + }, + [onChange], + ) + + return ( + <> + {type === 'text' ? ( +
+ +
+ ) : type === 'radio' || type === 'checkbox' ? ( +
+ {options?.map((option) => ( +
+ handleChange(e, option.value)} + /> + +
+ ))} +
+ ) : null} + + ) +} diff --git a/src/components/common/modal/QModal.jsx b/src/components/common/modal/QModal.jsx index 1cf01915..cf98698b 100644 --- a/src/components/common/modal/QModal.jsx +++ b/src/components/common/modal/QModal.jsx @@ -4,16 +4,25 @@ import { useRecoilState, useRecoilValue } from 'recoil' import { Modal } from 'react-responsive-modal' -import { modalContent, modalState } from '@/store/modalAtom' +import { modalContent, modalState, modalProps } from '@/store/modalAtom' import 'react-responsive-modal/styles.css' export default function QModal() { const [open, setOpen] = useRecoilState(modalState) const children = useRecoilValue(modalContent) + const props = useRecoilValue(modalProps) + const { closeOnOverlayClick = true, closeOnEsc = true, showCloseIcon = true } = props return ( - setOpen(false)} center> + setOpen(false)} + center + closeOnOverlayClick={closeOnOverlayClick} + closeOnEsc={closeOnEsc} + showCloseIcon={showCloseIcon} + > {children} ) diff --git a/src/components/common/pagination/QPagination.jsx b/src/components/common/pagination/QPagination.jsx new file mode 100644 index 00000000..7eb6638a --- /dev/null +++ b/src/components/common/pagination/QPagination.jsx @@ -0,0 +1,43 @@ +import usePagination from '@/hooks/usePagination' + +export default function QPagination(props) { + const { handleChangePage = () => {}, pagePerBlock = 10 } = props + const { currentPage, changePage, pageGroup, totalPages, pages, startPage, endPage, pageRange } = usePagination(props) + + const handlePage = (page) => { + handleChangePage(page) + changePage(page) + } + + return ( +
    +
  1. + +
  2. +
  3. + +
  4. + {pageRange.map((page) => ( +
  5. + +
  6. + ))} +
  7. + +
  8. +
  9. + +
  10. +
+ ) +} diff --git a/src/components/common/select/QSelect.jsx b/src/components/common/select/QSelect.jsx new file mode 100644 index 00000000..acf0ac6b --- /dev/null +++ b/src/components/common/select/QSelect.jsx @@ -0,0 +1,34 @@ +'use client' + +import { useCallback } from 'react' + +export default function QSelect({ placeholder, options, disabled = false, dark = false, value, onChange }) { + // const options = [ + // { id: 's01', value: 'cat', name: '고양이' }, + // { id: 's02', value: 'dog', name: '개' }, + // { id: 's03', value: 'lion', name: '사자' }, + // { id: 's04', value: 'tiger', name: '호랑이' }, + // ] + + const handleChange = useCallback( + (e) => { + onChange(e.target.value) + }, + [onChange], + ) + + return ( + + ) +} diff --git a/src/components/community/Archive.jsx b/src/components/community/Archive.jsx index dcfc737f..768bc500 100644 --- a/src/components/community/Archive.jsx +++ b/src/components/community/Archive.jsx @@ -1,7 +1,71 @@ +'use client' + +import Link from 'next/link' +import Image from 'next/image' + +import Search from '@/components/community/Search' +import ArchiveTable from '@/components/community/ArchiveTable' + +import { useEffect, useState } from 'react' +import { useResetRecoilState } from 'recoil' +import { useMessage } from '@/hooks/useMessage' + +import { searchState } from '@/store/boardAtom' + export default function Archive() { + const { getMessage } = useMessage() + const resetSearch = useResetRecoilState(searchState) + const [isInitialized, setIsInitialized] = useState(false) + + useEffect(() => { + resetSearch() + setIsInitialized(true) + }, []) + + if (!isInitialized) { + return null + } + + const boardType = { + boardTitle: getMessage('board.archive.title'), + subTitle: getMessage('board.archive.sub.title'), + clsCode: 'DOWN', + } + return ( <> -

Community Archive

+
+
+
    +
  • + + {getMessage('board.archive.title')} + +
  • +
+
    +
  • + + react + +
  • +
  • + {getMessage('header.menus.community')} +
  • +
  • + {getMessage('board.archive.title')} +
  • +
+
+
+
+
+
+ + +
+
+
) } diff --git a/src/components/community/ArchiveTable.jsx b/src/components/community/ArchiveTable.jsx new file mode 100644 index 00000000..ef6b303b --- /dev/null +++ b/src/components/community/ArchiveTable.jsx @@ -0,0 +1,103 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useRecoilState } from 'recoil' +import { useAxios } from '@/hooks/useAxios' + +import { searchState } from '@/store/boardAtom' +import { useMessage } from '@/hooks/useMessage' + +import { handleFileDown } from '@/util/board-utils' + +export default function ArchiveTable({ clsCode }) { + const { getMessage } = useMessage() + + // api 조회 관련 + const { get } = useAxios() + const [search, setSearch] = useRecoilState(searchState) + const [boardList, setBoardList] = useState([]) + + // 목록 조회 + useEffect(() => { + async function fetchData() { + const url = `/api/board/list` + const params = new URLSearchParams({ + schNoticeTpCd: 'QC', + schNoticeClsCd: clsCode, + schTitle: search.searchValue ? search.searchValue : '', + }) + const apiUrl = `${url}?${params.toString()}` + + const resultData = await get({ url: apiUrl }) + + if (resultData) { + if (resultData.result.code === 200) { + setBoardList(resultData.data) + if (resultData.data.length > 0) { + setSearch({ ...search, totalCount: resultData.data[0].totCnt }) + } else { + setSearch({ ...search, totalCount: 0 }) + } + } else { + alert(resultData.result.message) + } + } + } + + fetchData() + }, [search.searchValue]) + + // 상세 파일 목록 조회 + const handleDetailFileListDown = async (noticeNo) => { + const url = `/api/board/detail` + const params = new URLSearchParams({ + noticeNo: noticeNo, + }) + const apiUrl = `${url}?${params.toString()}` + + const resultData = await get({ url: apiUrl }) + + if (resultData) { + if (resultData.result.code === 200) { + const boardDetailFileList = resultData.data.listFile + + if (boardDetailFileList && Array.isArray(boardDetailFileList)) { + boardDetailFileList.forEach((boardFile) => { + handleFileDown(boardFile) + }) + } + } else { + alert(resultData.result.message) + } + } + } + + return ( + <> +
+ {boardList?.map((board) => ( +
+
+
+ {/* 번호 */} + {board.rowNumber} +
+
+ {/* 제목 */} + {board.title} +
+
+ {/* 등록일 */} + {getMessage('board.sub.updDt')} : {board.uptDt ? board.uptDt : board.regDt} +
+
+
+ {/* 첨부파일 */} + +
+
+ ))} +
+ + ) +} diff --git a/src/components/community/Faq.jsx b/src/components/community/Faq.jsx index 722741b3..17254f5c 100644 --- a/src/components/community/Faq.jsx +++ b/src/components/community/Faq.jsx @@ -1,7 +1,80 @@ +'use client' + +import Link from 'next/link' +import Image from 'next/image' + +import Search from '@/components/community/Search' +import Pagination from '@/components/community/Pagination' +import Table from '@/components/community/Table' + +import { useEffect, useState } from 'react' +import { useResetRecoilState, useRecoilValue, useRecoilState } from 'recoil' +import { useMessage } from '@/hooks/useMessage' + +import { searchState } from '@/store/boardAtom' + export default function Faq() { + const { getMessage } = useMessage() + const resetSearch = useResetRecoilState(searchState) + const [isInitialized, setIsInitialized] = useState(false) + + const search = useRecoilValue(searchState) + const [searchForm, setSearchForm] = useRecoilState(searchState) + + useEffect(() => { + if (search.mainFlag === 'N') { + resetSearch() + } else { + setSearchForm({ ...searchForm, mainFlag: 'N' }) + } + setIsInitialized(true) + }, []) + + if (!isInitialized) { + return null + } + + const boardType = { + boardTitle: getMessage('board.faq.title'), + subTitle: getMessage('board.faq.sub.title'), + clsCode: 'FAQ', + } + return ( <> -

Community FAQ

+
+
+
    +
  • + + {getMessage('board.faq.title')} + +
  • +
+
    +
  • + + react + +
  • +
  • + {getMessage('header.menus.community')} +
  • +
  • + {getMessage('board.faq.title')} +
  • +
+
+
+
+
+
+ + + + + + ) } diff --git a/src/components/community/Notice.jsx b/src/components/community/Notice.jsx index 2ab67c8e..55dfbad1 100644 --- a/src/components/community/Notice.jsx +++ b/src/components/community/Notice.jsx @@ -1,7 +1,72 @@ +'use client' + +import Link from 'next/link' +import Image from 'next/image' + +import Search from '@/components/community/Search' +import Pagination from '@/components/community/Pagination' +import Table from '@/components/community/Table' + +import { useEffect, useState } from 'react' +import { useResetRecoilState } from 'recoil' +import { useMessage } from '@/hooks/useMessage' + +import { searchState } from '@/store/boardAtom' + export default function Notice() { + const { getMessage } = useMessage() + const resetSearch = useResetRecoilState(searchState) + const [isInitialized, setIsInitialized] = useState(false) + + useEffect(() => { + resetSearch() + setIsInitialized(true) + }, []) + + if (!isInitialized) { + return null + } + + const boardType = { + boardTitle: getMessage('board.notice.title'), + subTitle: getMessage('board.notice.sub.title'), + clsCode: 'NOTICE', + } return ( <> -

Community Notice

+
+
+
    +
  • + + {getMessage('board.notice.title')} + +
  • +
+
    +
  • + + + +
  • +
  • + {getMessage('header.menus.community')} +
  • +
  • + {getMessage('board.notice.title')} +
  • +
+
+
+
+
+
+ +
+ + + + ) } diff --git a/src/components/community/Pagination.jsx b/src/components/community/Pagination.jsx new file mode 100644 index 00000000..938f5b0d --- /dev/null +++ b/src/components/community/Pagination.jsx @@ -0,0 +1,78 @@ +'use client' + +import { searchState } from '@/store/boardAtom' +import { useRecoilState, useRecoilValue } from 'recoil' +import { generateBlockPagination } from '@/util/board-utils' + +export default function Pagination() { + const search = useRecoilValue(searchState) + + const [searchForm, setSearchForm] = useRecoilState(searchState) + + const handlePagination = (pageNum) => { + setSearchForm({ ...searchForm, currentPage: pageNum }) + } + + const totalPages = Math.ceil(search.totalCount / search.pageBlock) > 0 ? Math.ceil(search.totalCount / search.pageBlock) : 1 + const allPages = generateBlockPagination(search.currentPage, totalPages, 10) + + return ( + <> +
    +
  1. + +
  2. +
  3. + +
  4. + + {/* 페이지목록 */} + {allPages.map((page, index) => { + return ( +
  5. + +
  6. + ) + })} + +
  7. + +
  8. +
  9. + +
  10. +
+ + ) +} diff --git a/src/components/community/Search.jsx b/src/components/community/Search.jsx new file mode 100644 index 00000000..26ca1883 --- /dev/null +++ b/src/components/community/Search.jsx @@ -0,0 +1,117 @@ +'use client' + +import { searchState } from '@/store/boardAtom' +import { useRecoilState, useRecoilValue } from 'recoil' +import { useState } from 'react' +import { useMessage } from '@/hooks/useMessage' + +export default function Search({ title = '', subTitle = '', isSelectUse = false }) { + const { getMessage } = useMessage() + + const search = useRecoilValue(searchState) + const [searchForm, setSearchForm] = useRecoilState(searchState) + + const [selectPageBlock, setSelectPageBlock] = useState(search.pageBlock) + const [searchValue, setSearchValue] = useState(search.searchValue) + const [searchView, setSearchView] = useState(search.searchValue ? true : false) + const [searchViewText, setSearchViewText] = useState(search.searchValue ? search.searchValue : '') + + // Enter 키 처리 + const handleKeyDown = (e) => { + if (e.key === 'Enter') { + handleSubmit(e) + } + } + + // 조회 값 처리 + const handleSearch = (text, block) => { + if (text !== '') { + setSearchView(true) + setSearchViewText(text) + setSearchForm({ ...searchForm, currentPage: 1, searchValue: text, pageBlock: block, searchFlag: true }) + } else { + setSearchView(false) + setSearchViewText('') + setSearchForm({ ...searchForm, currentPage: 1, searchValue: '', pageBlock: block, searchFlag: !searchForm.searchFlag }) + } + // 조회 후 값 비워주기 + setSearchValue('') + } + + const handleSubmit = (e) => { + e.preventDefault() + handleSearch(searchValue, selectPageBlock) + } + + return ( + <> +
+
+ { + setSearchValue(e.target.value) + }} + onKeyDown={handleKeyDown} + value={searchValue} + /> + +
+ {searchView && ( +
+ {isSelectUse ? ( + <> +
${searchViewText}`, `${search.totalCount}`]), + }} + >
+ + ) : ( + <> +
${searchViewText}`, `${search.totalCount}`]), + }} + >
+ + )} +
+ )} +
+
+
+

{subTitle}

+
    +
  • + {getMessage('board.sub.total')} {search.totalCount} +
  • +
+
+ {isSelectUse && ( +
+
+ +
+
+ )} +
+ + ) +} diff --git a/src/components/community/Table.jsx b/src/components/community/Table.jsx new file mode 100644 index 00000000..f943bc86 --- /dev/null +++ b/src/components/community/Table.jsx @@ -0,0 +1,110 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useRecoilState } from 'recoil' + +import { searchState } from '@/store/boardAtom' + +import { useAxios } from '@/hooks/useAxios' +import { useMessage } from '@/hooks/useMessage' + +import BoardDetailModal from '../community/modal/BoardDetailModal' + +export default function Table({ clsCode }) { + const { getMessage } = useMessage() + + // api 조회 관련 + const { get } = useAxios() + const [search, setSearch] = useRecoilState(searchState) + const [boardList, setBoardList] = useState([]) + + // 팝업 관련 + const [open, setOpen] = useState(false) + const [modalNoticeNo, setModalNoticeNo] = useState('') + + // 목록 조회 + useEffect(() => { + async function fetchData() { + const startRow = (search.currentPage - 1) * search.pageBlock > 0 ? (search.currentPage - 1) * search.pageBlock + 1 : 1 + const endRow = search.currentPage * search.pageBlock + + const url = `/api/board/list` + const params = new URLSearchParams({ + schNoticeTpCd: 'QC', + schNoticeClsCd: clsCode, + schTitle: search.searchValue ? search.searchValue : '', + startRow: startRow, + endRow: endRow, + }) + const apiUrl = `${url}?${params.toString()}` + + const resultData = await get({ url: apiUrl }) + + if (resultData) { + if (resultData.result.code === 200) { + if (resultData.data.length > 0) { + setBoardList(resultData.data) + setSearch({ ...search, totalCount: resultData.data[0].totCnt }) + } else { + setBoardList([]) + setSearch({ ...search, totalCount: 0 }) + } + } else { + alert(resultData.result.message) + } + } + } + + fetchData() + }, [search.currentPage, search.searchValue, search.pageBlock, search.searchFlag]) + + return ( + <> +
+
+ + + + + + + {boardList.length > 0 ? ( + boardList?.map((board) => ( + { + setOpen(true) + setModalNoticeNo(board.noticeNo) + }} + > + + + + + )) + ) : ( + + + + )} + +
+ {/* 번호 */} + {board.rowNumber} + + {/* 제목 */} +
+
{board.title}
+ {board.attachYn && } +
+
+ {/* 등록일 */} + {board.regDt.split(' ')[0]} +
+ {getMessage('common.message.no.data')} +
+
+ {open && } + + ) +} diff --git a/src/components/community/modal/BoardDetailModal.jsx b/src/components/community/modal/BoardDetailModal.jsx new file mode 100644 index 00000000..ec324966 --- /dev/null +++ b/src/components/community/modal/BoardDetailModal.jsx @@ -0,0 +1,77 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useAxios } from '@/hooks/useAxios' +import { handleFileDown } from '@/util/board-utils' + +export default function BoardDetailModal({ noticeNo, setOpen }) { + // api 조회 관련 + const { get } = useAxios() + const [boardDetail, setBoardDetail] = useState({}) + + useEffect(() => { + // 상세 조회 + const fetchDetail = async (noticeNo) => { + const url = `/api/board/detail` + const params = new URLSearchParams({ + noticeNo: noticeNo, + }) + const apiUrl = `${url}?${params.toString()}` + + const resultData = await get({ url: apiUrl }) + + if (resultData) { + if (resultData.result.code === 200) { + const boardDetail = resultData.data + setBoardDetail(boardDetail) + } else { + alert(resultData.result.message) + } + } + } + + fetchDetail(noticeNo) + }, []) + + return ( + <> +
+
+
+
+ +
+
+
+
{boardDetail.title}
+ + {boardDetail.listFile && ( +
+
첨부파일 목록
+ {boardDetail.listFile.map((boardFile) => ( +
+ +
+ ))} +
+ )} + +
{boardDetail.contents}
+
+
+
+
+
+ + ) +} diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index da141287..ae3c6c62 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -13,7 +13,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { area: 0, children: [], initialize: function (points, options, canvas) { - this.callSuper('initialize', points, { ...options, selectable: options.selectable ?? false }) + this.callSuper('initialize', points, { ...options, selectable: options.selectable ?? true }) if (options.id) { this.id = options.id } else { @@ -90,7 +90,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { const y2 = this.top + this.height * scaleY if (thisText) { - thisText.set({ text: this.length.toFixed(0).toString(), left: (x1 + x2) / 2, top: (y1 + y2) / 2 }) + thisText.set({ text: this.getLength().toString(), left: (x1 + x2) / 2, top: (y1 + y2) / 2 }) this.text = thisText return } @@ -109,7 +109,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { const maxY = this.top + this.length const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI - const text = new fabric.Textbox(this.length.toFixed(0).toString(), { + const text = new fabric.Textbox(this.getLength().toString(), { left: left, top: top, fontSize: this.fontSize, @@ -148,6 +148,11 @@ export const QLine = fabric.util.createClass(fabric.Line, { this.canvas = canvas }, + getLength() { + //10배 곱해진 값 return + return Number(this.length.toFixed(1) * 10) + }, + setViewLengthText(bool) { const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) if (thisText) { diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 84e57974..0ac7a519 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -27,6 +27,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { point.x = Math.round(point.x) point.y = Math.round(point.y) }) + options.selectable = options.selectable ?? true options.sort = options.sort ?? true options.parentId = options.parentId ?? null @@ -51,6 +52,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { } this.callSuper('initialize', points, options) + if (options.id) { this.id = options.id } else { @@ -119,13 +121,13 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { this.on('modified', (e) => { this.addLengthText() - if (this.arrow) { - drawDirectionArrow(this) - } + // if (this.arrow) { + // drawDirectionArrow(this) + // } }) this.on('selected', () => { - drawDirectionArrow(this) + // drawDirectionArrow(this) Object.keys(this.controls).forEach((controlKey) => { if (controlKey !== 'ml' && controlKey !== 'mr') { this.setControlVisible(controlKey, false) @@ -164,8 +166,12 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { stroke: this.stroke, strokeWidth: this.strokeWidth, fontSize: this.fontSize, + attributes: { + offset: 0, + }, + parent: this, direction: getDirectionByPoint(point, nextPoint), - idx: i, + idx: i + 1, }) line.startPoint = point line.endPoint = nextPoint @@ -193,14 +199,32 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { const end = points[(i + 1) % points.length] const dx = end.x - start.x const dy = end.y - start.y - const length = Math.sqrt(dx * dx + dy * dy) + const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10 - const midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2) + let midPoint + + switch (this.direction) { + case 'north': + midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2 - 30) + break + case 'west': + midPoint = new fabric.Point((start.x + end.x) / 2 - 30, (start.y + end.y) / 2) + break + case 'south': + midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2 + 30) + break + case 'east': + midPoint = new fabric.Point((start.x + end.x) / 2 + 30, (start.y + end.y) / 2) + break + default: + midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2) + break + } const degree = (Math.atan2(dy, dx) * 180) / Math.PI // Create new text object if it doesn't exist - const text = new fabric.IText(length.toFixed(0), { + const text = new fabric.Text(length.toFixed(0), { left: midPoint.x, top: midPoint.y, fontSize: this.fontSize, diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 9c8c9d38..f34d1cb6 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -4,10 +4,20 @@ import { useEffect, useRef } from 'react' import { useCanvas } from '@/hooks/useCanvas' import { useEvent } from '@/hooks/useEvent' +import QContextMenu from '@/components/common/context-menu/QContextMenu' +import { useContextMenu } from '@/hooks/useContextMenu' +import { useRecoilValue } from 'recoil' +import { currentObjectState } from '@/store/canvasAtom' export default function CanvasFrame({ plan }) { const canvasRef = useRef(null) const { canvas } = useCanvas('canvas') + const { contextMenu, currentContextMenu, setCurrentContextMenu } = useContextMenu() + const currentObject = useRecoilValue(currentObjectState) + + useEffect(() => { + console.log(currentObject) + }, [currentObject]) useEvent() const loadCanvas = () => { @@ -23,11 +33,23 @@ export default function CanvasFrame({ plan }) { useEffect(() => { loadCanvas() - }, [plan]) + }, [plan, canvas]) + + const onClickContextMenu = (index) => {} return (
+ + {contextMenu.map((menus, index) => ( +
    + {menus.map((menu) => ( +
  • setCurrentContextMenu(menu)}>{menu.name}
  • + ))} +
+ ))} +
+ {currentContextMenu?.component}
) } diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 5d3817a2..7138907c 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -3,94 +3,171 @@ import { useEffect, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import CanvasFrame from './CanvasFrame' +import { useMessage } from '@/hooks/useMessage' +import { useSwal } from '@/hooks/useSwal' import { usePlan } from '@/hooks/usePlan' import { globalLocaleStore } from '@/store/localeAtom' -import { currentCanvasPlanState, initCanvasPlansState } from '@/store/canvasAtom' +import { currentCanvasPlanState, initCanvasPlansState, plansState } from '@/store/canvasAtom' +import { sessionStore } from '@/store/commonAtom' export default function CanvasLayout() { const [objectNo, setObjectNo] = useState('test123240822001') // 이후 삭제 필요 - const [addCanvasPlans, setAddCanvasPlans] = useState([]) const [planNum, setPlanNum] = useState(0) const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const [initCanvasPlans, setInitCanvasPlans] = useRecoilState(initCanvasPlansState) + const [plans, setPlans] = useRecoilState(plansState) const globalLocaleState = useRecoilValue(globalLocaleStore) + const sessionState = useRecoilValue(sessionStore) - const { getCanvasByObjectNo } = usePlan() + const { getMessage } = useMessage() + const { swalFire } = useSwal() + const { getCanvasByObjectNo, delCanvasById, checkModifiedCanvasPlan, saveCanvas, currentCanvasData } = usePlan() const handleCurrentPlan = (newCurrentId) => { - if (!currentCanvasPlan?.id || currentCanvasPlan.id !== newCurrentId) { - setInitCanvasPlans((plans) => - plans.map((plan) => { - return { ...plan, isCurrent: plan.id === newCurrentId } - }), - ) - setAddCanvasPlans((plans) => - plans.map((plan) => { - return { ...plan, isCurrent: plan.id === newCurrentId } - }), - ) + // console.log('currentPlan newCurrentId: ', newCurrentId) + if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) { + if (currentCanvasPlan?.id && checkModifiedCanvasPlan()) { + swalFire({ + html: getMessage('common.message.confirm.save') + `
${currentCanvasPlan.name}`, + type: 'confirm', + confirmFn: async () => { + await saveCanvas(sessionState.userId) + updateCurrentPlan(newCurrentId) + }, + denyFn: () => { + updateCurrentPlan(newCurrentId) + }, + }) + } else { + updateCurrentPlan(newCurrentId) + } } } + const updateCurrentPlan = (newCurrentId) => { + setPlans((plans) => + plans.map((plan) => { + return { ...plan, isCurrent: plan.id === newCurrentId } + }), + ) + } useEffect(() => { - setCurrentCanvasPlan([...initCanvasPlans, ...addCanvasPlans].find((plan) => plan.isCurrent) || null) - }, [initCanvasPlans, addCanvasPlans]) + setCurrentCanvasPlan(plans.find((plan) => plan.isCurrent) || null) + }, [plans]) const handleDeletePlan = (e, id) => { e.stopPropagation() // 이벤트 버블링 방지 - // 삭제할 아이디와 다른 아이템만 남김 - const filterInitPlans = initCanvasPlans.filter((plan) => plan.id !== id) - setInitCanvasPlans(filterInitPlans) - const filterAddPlans = addCanvasPlans.filter((plan) => plan.id !== id) - setAddCanvasPlans(filterAddPlans) - - const combinedPlans = [...filterInitPlans, ...filterAddPlans] - if (combinedPlans.length === 0) { - // 모든 데이터가 삭제된 경우 - setPlanNum(0) + if (initCanvasPlans.some((plan) => plan.id === id)) { + delCanvasById(id) + .then((res) => { + swalFire({ text: getMessage('common.message.delete') }) + // console.log('[DELETE] canvas-statuses res :::::::: %o', res) + setInitCanvasPlans((initCanvasPlans) => initCanvasPlans.filter((plan) => plan.id !== id)) + setPlans((plans) => plans.filter((plan) => plan.id !== id)) + }) + .catch((error) => { + swalFire({ text: error.message, icon: 'error' }) + // console.error('[DELETE] canvas-statuses res error :::::::: %o', error) + }) } else { - const lastPlanId = combinedPlans.at(-1).id - if (id !== lastPlanId) { - handleCurrentPlan(lastPlanId) - } + setPlans((plans) => plans.filter((plan) => plan.id !== id)) + swalFire({ text: getMessage('common.message.delete') }) + } + + // 삭제 후 last 데이터에 포커싱 + const lastPlan = plans.filter((plan) => plan.id !== id).at(-1) + if (!lastPlan) { + setPlanNum(0) + setCurrentCanvasPlan(null) + } else if (id !== lastPlan.id) { + handleCurrentPlan(lastPlan.id) } } - const addNewPlan = () => { - setAddCanvasPlans([...addCanvasPlans, { id: planNum, name: `Plan ${planNum + 1}`, objectNo: `${objectNo}` }]) + const addEmptyPlan = () => { + setPlans([...plans, { id: planNum, name: `Plan ${planNum + 1}`, objectNo: `${objectNo}` }]) + handleCurrentPlan(planNum) + setPlanNum(planNum + 1) + } + + const addCopyPlan = () => { + const copyPlan = { + id: planNum, + name: `Plan ${planNum + 1}`, + objectNo: `${objectNo}`, + userId: sessionState.userId, + canvasStatus: currentCanvasData(), + } + setPlans((plans) => [...plans, copyPlan]) handleCurrentPlan(planNum) setPlanNum(planNum + 1) } useEffect(() => { - getCanvasByObjectNo(objectNo).then((res) => { - console.log('canvas 목록 ', res) - if (res.length > 0) { - setInitCanvasPlans(res) - handleCurrentPlan(res.at(-1).id) // last 데이터에 포커싱 - setPlanNum(res.length) - } else { - addNewPlan() - } - }) + if (!currentCanvasPlan) { + getCanvasByObjectNo(sessionState.userId, objectNo).then((res) => { + // console.log('canvas 목록 ', res) + if (res.length > 0) { + setInitCanvasPlans(res) + setPlans(res) + handleCurrentPlan(res.at(-1).id) // last 데이터에 포커싱 + setPlanNum(res.length) + } else { + addEmptyPlan() + } + }) + } }, []) return (
- {[...initCanvasPlans, ...addCanvasPlans].map((plan) => ( - ))}
- + {plans.length < 10 && ( + + )}
- plan.isCurrent === true)} /> + plan.isCurrent === true)} />
) } diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 99b3e048..ae8cc79d 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -9,7 +9,8 @@ import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' import { usePlan } from '@/hooks/usePlan' -import { canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom' +import { useSwal } from '@/hooks/useSwal' +import { canvasState, canvasZoomState, currentCanvasPlanState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom' import { sessionStore } from '@/store/commonAtom' import { outerLinePointsState } from '@/store/outerLineAtom' import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' @@ -30,7 +31,26 @@ const canvasMenus = [ ] export default function CanvasMenu(props) { - const { setShowCanvasSettingModal, showOutlineModal, setShowOutlineModal } = props + const { + setShowCanvasSettingModal, + showOutlineModal, + setShowOutlineModal, + setShowPlaceShapeModal, + setShowSlopeSettingModal, + setShowPlacementSurfaceSettingModal, + setShowPlaceShapeDrawingModal, + setShowRoofShapeSettingModal, + setShowObjectSettingModal, + setShowRoofShapePassivitySettingModal, + setShowAuxiliaryModal, + setShowEavesGableEditModal, + setShowMovementModal, + setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, + setShowBasicSettingModal, + setShowCircuitTrestleSettingModal, + setShowPropertiesSettingModal, + } = props const [menuNumber, setMenuNumber] = useState(null) const [type, setType] = useState('') @@ -40,6 +60,7 @@ export default function CanvasMenu(props) { const setCurrentMenu = useSetRecoilState(currentMenuState) const setPoints = useSetRecoilState(outerLinePointsState) const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) + const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const globalLocale = useRecoilValue(globalLocaleStore) const canvas = useRecoilValue(canvasState) @@ -47,6 +68,7 @@ export default function CanvasMenu(props) { const { getMessage } = useMessage() const { saveCanvas } = usePlan() + const { swalFire } = useSwal() const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] const onClickNav = (menu) => { @@ -54,6 +76,10 @@ export default function CanvasMenu(props) { setCurrentMenu(menu.title) switch (menu.index) { + case 1: + setType('placementShape') + onClickPlacementInitialMenu() + break case 2: setType('outline') break @@ -67,18 +93,50 @@ export default function CanvasMenu(props) { } const menuProps = { setShowOutlineModal, + setShowPlaceShapeModal, + setShowRoofShapeSettingModal, + setShowRoofShapePassivitySettingModal, + setShowAuxiliaryModal, + setShowEavesGableEditModal, + setShowMovementModal, + setShowSlopeSettingModal, + setShowPlacementSurfaceSettingModal, + setShowPlaceShapeDrawingModal, + setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, + setShowObjectSettingModal, + setShowBasicSettingModal, + setShowCircuitTrestleSettingModal, + setShowPropertiesSettingModal, type, } const settingsModalOptions = useRecoilState(settingModalFirstOptionsState) useEffect(() => { + if (menuNumber === 1) { + onClickPlacementInitialMenu() + } if (menuNumber !== 2 && showOutlineModal) setShowOutlineModal(false) }, [menuNumber, type]) // 저장버튼(btn08) 클릭 시 호출되는 함수 const handleSaveCanvas = () => { - saveCanvas(sessionState.userId) + swalFire({ + html: getMessage('common.message.confirm.save') + `
${currentCanvasPlan.name}`, + type: 'confirm', + confirmFn: () => { + saveCanvas(sessionState.userId) + }, + }) + } + + const onClickPlacementInitialMenu = () => { + setShowOutlineModal(false) + setShowCanvasSettingModal(false) + setShowEavesGableEditModal(false) + setShowMovementModal(false) + setShowPlaceShapeModal(true) } const handleClear = () => { @@ -107,7 +165,11 @@ export default function CanvasMenu(props) {
    {canvasMenus.map((menu) => { return ( -
  • onClickNav(menu)}> +
  • onClickNav(menu)} + >
}
- +
@@ -139,7 +201,12 @@ export default function CanvasMenu(props) {
- + {canvasZoom}%
diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 699c96c5..b8ea7784 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -11,10 +11,42 @@ import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal import CanvasLayout from '@/components/floor-plan/CanvasLayout' import DotLineGrid from '@/components/floor-plan/modal/grid/DotLineGrid' import WallLineSetting from '@/components/floor-plan/modal/outerlinesetting/WallLineSetting' +import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting' +import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting' +import GridColorSetting from './modal/grid/GridColorSetting' +import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting' +import PlacementShapeDrawing from '@/components/floor-plan/modal/placementShape/PlacementShapeDrawing' +import Slope from '@/components/floor-plan/modal/Slope' + +import AuxiliaryDrawing from '@/components/floor-plan/modal/auxiliary/AuxiliaryDrawing' +import EavesGableEdit from '@/components/floor-plan/modal/eavesGable/EavesGableEdit' +import WallLineOffsetSetting from '@/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting' +import ObjectSetting from '@/components/floor-plan/modal/object/ObjectSetting' +import PlacementSurfaceSetting from '@/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting' +import RoofShapePassivitySetting from '@/components/floor-plan/modal/roofShape/RoofShapePassivitySetting' +import MovementSetting from '@/components/floor-plan/modal/movement/MovementSetting' +import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting' +import BasicSetting from '@/components/floor-plan/modal/basic/BasicSetting' +import CircuitTrestleSetting from '@/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting' export default function FloorPlan() { const [showCanvasSettingModal, setShowCanvasSettingModal] = useState(false) const [showOutlineModal, setShowOutlineModal] = useState(false) + const [showPlaceShapeModal, setShowPlaceShapeModal] = useState(false) + const [showPropertiesSettingModal, setShowPropertiesSettingModal] = useState(false) + const [showRoofShapeSettingModal, setShowRoofShapeSettingModal] = useState(false) + const [showRoofShapePassivitySettingModal, setShowRoofShapePassivitySettingModal] = useState(false) + const [showAuxiliaryModal, setShowAuxiliaryModal] = useState(false) + const [showSlopeSettingModal, setShowSlopeSettingModal] = useState(false) + const [showPlacementSurfaceSettingModal, setShowPlacementSurfaceSettingModal] = useState(false) + const [showPlaceShapeDrawingModal, setShowPlaceShapeDrawingModal] = useState(false) + const [showObjectSettingModal, setShowObjectSettingModal] = useState(false) + const [showEavesGableEditModal, setShowEavesGableEditModal] = useState(false) + const [showMovementModal, setShowMovementModal] = useState(false) + const [showWallLineOffsetSettingModal, setShowWallLineOffsetSettingModal] = useState(false) + const [showRoofAllocationSettingModal, setShowRoofAllocationSettingModal] = useState(false) + const [showBasicSettingModal, setShowBasicSettingModal] = useState(false) + const [showCircuitTrestleSettingModal, setShowCircuitTrestleSettingModal] = useState(false) const globalLocaleState = useRecoilValue(globalLocaleStore) const { get } = useAxios(globalLocaleState) @@ -25,19 +57,37 @@ export default function FloorPlan() { const [showDotLineGridModal, setShowDotLineGridModal] = useState(false) const [showGridCopyModal, setShowGridCopyModal] = useState(false) const [showGridMoveModal, setShowGridMoveModal] = useState(false) + const [showColorPickerModal, setShowColorPickerModal] = useState(false) const canvasSettingProps = { setShowCanvasSettingModal, setShowDotLineGridModal, + setShowColorPickerModal, } const outlineProps = { setShowOutlineModal, + setShowPropertiesSettingModal, } const modalProps = { setShowCanvasSettingModal, showOutlineModal, setShowOutlineModal, + setShowPlaceShapeModal, + setShowSlopeSettingModal, + setShowPlacementSurfaceSettingModal, + setShowPlaceShapeDrawingModal, + setShowRoofShapeSettingModal, + setShowObjectSettingModal, + setShowRoofShapePassivitySettingModal, + setShowAuxiliaryModal, + setShowEavesGableEditModal, + setShowMovementModal, + setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, + setShowBasicSettingModal, + setShowCircuitTrestleSettingModal, + setShowPropertiesSettingModal, } useEffect(() => { @@ -75,6 +125,14 @@ export default function FloorPlan() { setShowDotLineGridModal, } + const gridColorProps = { + setShowColorPickerModal, + } + + const propertiesSettingProps = { + setShowPropertiesSettingModal, + } + useEffect(() => {}, [showOutlineModal]) return ( @@ -84,9 +142,27 @@ export default function FloorPlan() {
{showCanvasSettingModal && } - {/*{showOutlineModal && }*/} {showOutlineModal && } {showDotLineGridModal && } + {showColorPickerModal && } + {showPropertiesSettingModal && } + + {showPlaceShapeModal && } + {showRoofShapeSettingModal && } + {showRoofShapePassivitySettingModal && ( + + )} + {showAuxiliaryModal && } + {showSlopeSettingModal && } + {showPlaceShapeDrawingModal && } + {showEavesGableEditModal && } + {showMovementModal && } + {showRoofAllocationSettingModal && } + {showWallLineOffsetSettingModal && } + {showObjectSettingModal && } + {showPlacementSurfaceSettingModal && } + {showBasicSettingModal && } + {showCircuitTrestleSettingModal && }
diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index a6b12877..763dc92b 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -5,18 +5,86 @@ import { useEffect, useState } from 'react' import { MENU } from '@/common/common' import { currentMenuState } from '@/store/canvasAtom' import { useSetRecoilState } from 'recoil' - +import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' export default function MenuDepth01(props) { - const { setShowOutlineModal, type } = props + const { + setShowOutlineModal, + type, + setShowPlaceShapeModal, + setShowRoofShapeSettingModal, + setShowRoofShapePassivitySettingModal, + setShowAuxiliaryModal, + setShowEavesGableEditModal, + setShowMovementModal, + setShowSlopeSettingModal, + setShowPlacementSurfaceSettingModal, + setShowPlaceShapeDrawingModal, + setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, + setShowObjectSettingModal, + setShowBasicSettingModal, + setShowCircuitTrestleSettingModal, + setShowPropertiesSettingModal, + } = props const { getMessage } = useMessage() const [activeMenu, setActiveMenu] = useState() const setCurrentMenu = useSetRecoilState(currentMenuState) + + const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch() + const onClickMenu = ({ id, menu, name }) => { setActiveMenu(menu) setShowOutlineModal(menu === MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) setCurrentMenu(menu) + setShowPlaceShapeModal(false) if (type === 'outline') { setShowOutlineModal(id === 0) + setShowRoofShapeSettingModal(id === 1) + setShowRoofShapePassivitySettingModal(id === 2) + setShowAuxiliaryModal(id === 3) + setShowEavesGableEditModal(id === 4) + setShowMovementModal(id === 5) + setShowWallLineOffsetSettingModal(id === 6) + setShowRoofAllocationSettingModal(id === 7) + setShowPlaceShapeDrawingModal(false) + setShowPropertiesSettingModal(false) + setShowCircuitTrestleSettingModal(false) + } + + if (type === 'surface') { + setShowOutlineModal(false) + setShowRoofShapeSettingModal(false) + setShowRoofShapePassivitySettingModal(false) + setShowAuxiliaryModal(false) + setShowEavesGableEditModal(false) + setShowMovementModal(false) + setShowWallLineOffsetSettingModal(false) + setShowRoofAllocationSettingModal(false) + setShowPropertiesSettingModal(false) + setShowCircuitTrestleSettingModal(false) + setShowSlopeSettingModal(id === 0) + setShowPlaceShapeDrawingModal(id === 1) + setShowPlacementSurfaceSettingModal(id === 2) + setShowObjectSettingModal(id === 3) + + //배치면 전체 삭제 + if (id === 4) { + deleteAllSurfacesAndObjects() + } + } + + if (type === 'module') { + setShowOutlineModal(false) + setShowRoofShapeSettingModal(false) + setShowRoofShapePassivitySettingModal(false) + setShowAuxiliaryModal(false) + setShowEavesGableEditModal(false) + setShowMovementModal(false) + setShowWallLineOffsetSettingModal(false) + setShowRoofAllocationSettingModal(false) + setShowPropertiesSettingModal(false) + setShowBasicSettingModal(id === 0) + setShowCircuitTrestleSettingModal(id === 1) } } diff --git a/src/components/floor-plan/modal/Slope.jsx b/src/components/floor-plan/modal/Slope.jsx new file mode 100644 index 00000000..0ae32ab6 --- /dev/null +++ b/src/components/floor-plan/modal/Slope.jsx @@ -0,0 +1,34 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' + +export default function Slope({ setShowSlopeSettingModal }) { + const { getMessage } = useMessage() + return ( + +
+
+

{getMessage('plan.menu.placement.surface.slope.setting')}

+ +
+
+
+
+ + {getMessage('slope')} + +
+ +
+ {getMessage('size.angle')} +
+
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx new file mode 100644 index 00000000..d0f87114 --- /dev/null +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx @@ -0,0 +1,162 @@ +import { useState } from 'react' +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle' +import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch' +import Angle from '@/components/floor-plan/modal/lineTypes/Angle' +import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal' +import { OUTER_LINE_TYPE } from '@/store/outerLineAtom' +import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall' +import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall' +import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing' + +export default function AuxiliaryDrawing({ setShowAuxiliaryModal }) { + const { getMessage } = useMessage() + + const types = [ + { id: 1, name: getMessage('straight.line'), type: OUTER_LINE_TYPE.OUTER_LINE }, + { id: 2, name: getMessage('right.angle'), type: OUTER_LINE_TYPE.RIGHT_ANGLE }, + { id: 3, name: getMessage('double.pitch'), type: OUTER_LINE_TYPE.DOUBLE_PITCH }, + { id: 4, name: getMessage('angle'), type: OUTER_LINE_TYPE.ANGLE }, + { id: 5, name: getMessage('diagonal'), type: OUTER_LINE_TYPE.DIAGONAL_LINE }, + ] + + const { + length1, + setLength1, + length2, + setLength2, + length1Ref, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + angle1, + setAngle1, + angle1Ref, + angle2, + setAngle2, + angle2Ref, + type, + setType, + arrow1Ref, + arrow2Ref, + outerLineDiagonalLength, + setOuterLineDiagonalLength, + outerLineDiagonalLengthRef, + handleRollback, + handleFix, + buttonAct, + setButtonAct, + } = useAuxiliaryDrawing(setShowAuxiliaryModal) + + const outerLineProps = { + length1, + setLength1, + length1Ref, + arrow1, + setArrow1, + } + + const rightAngleProps = { + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + } + + const doublePitchProps = { + angle1, + setAngle1, + angle1Ref, + angle2, + setAngle2, + angle2Ref, + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + arrow1Ref, + arrow2Ref, + } + + const angleProps = { + angle1, + setAngle1, + angle1Ref, + length1, + setLength1, + length1Ref, + } + + const diagonalLineProps = { + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + outerLineDiagonalLength, + setOuterLineDiagonalLength, + outerLineDiagonalLengthRef, + arrow1, + setArrow1, + arrow2, + setArrow2, + } + + const onClickButton = (button) => { + setButtonAct(button.id) + setType(button.type) + } + return ( + +
+
+

{getMessage('modal.auxiliary.drawing')}

+ +
+
+
+ {types.map((type, idx) => ( + + ))} +
+
+
{getMessage('setting')}
+ {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } + {buttonAct === 5 && } +
+
+ + +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryMove.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryMove.jsx new file mode 100644 index 00000000..28674c07 --- /dev/null +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryMove.jsx @@ -0,0 +1,49 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' + +export default function AuxiliaryMove({ setCurrentContextMenu }) { + const { getMessage } = useMessage() + return ( + +
+
+

補助線の移動

+ +
+
+
移動する方向を入力してください
+
+
+
+

長さ

+
+
+ +
+ mm +
+
+
+ +
+ mm +
+
+
+ + + + +
+
+
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx new file mode 100644 index 00000000..c562e8dd --- /dev/null +++ b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx @@ -0,0 +1,61 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' + +export default function AuxiliarySize({ setCurrentContextMenu }) { + const { getMessage } = useMessage() + return ( + +
+
+

補助線サイズ変更

+ +
+
+
+
+ + +
+
+
+ +
+ mm +
+
+ 長さ +
+ +
+ mm +
+
+
+
+ + +
+
+
+ +
+ mm +
+
+ 長さ +
+ +
+ mm +
+
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx new file mode 100644 index 00000000..555cdfcb --- /dev/null +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -0,0 +1,65 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import Orientation from '@/components/floor-plan/modal/basic/step/Orientation' +import Module from '@/components/floor-plan/modal/basic/step/Module' +import PitchModule from '@/components/floor-plan/modal/basic/step/pitch/PitchModule' +import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement' +import Placement from '@/components/floor-plan/modal/basic/step/Placement' +import { useRecoilState } from 'recoil' +import { canvasSettingState } from '@/store/canvasAtom' + +export default function BasicSetting({ setShowBasicSettingModal }) { + const { getMessage } = useMessage() + const [tabNum, setTabNum] = useState(1) + const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) + return ( + +
+
+

{getMessage('plan.menu.module.circuit.setting.default')}

+ +
+
+
+
{getMessage('modal.module.basic.setting.orientation.setting')}
+ +
{getMessage('modal.module.basic.setting.module.setting')}
+ +
{getMessage('modal.module.basic.setting.module.placement')}
+
+ {tabNum === 1 && } + {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 2 && } + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 3 && } + + {/*배치면 초기설정 - 입력방법: 육지붕*/} + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 2 && } + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 3 && } + +
+ {tabNum !== 1 && ( + + )} + {/*{tabNum !== 3 && }*/} + {tabNum !== 3 && ( + + )} + {tabNum === 3 && ( + <> + + + + )} +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/basic/step/Module.jsx b/src/components/floor-plan/modal/basic/step/Module.jsx new file mode 100644 index 00000000..f50bb408 --- /dev/null +++ b/src/components/floor-plan/modal/basic/step/Module.jsx @@ -0,0 +1,188 @@ +import QSelectBox from '@/components/common/select/QSelectBox' +import { useMessage } from '@/hooks/useMessage' + +export default function Module({}) { + const { getMessage } = useMessage() + const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }] + const moduleData = { + header: [ + { name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' }, + { + name: `${getMessage('높이')} (mm)`, + prop: 'height', + }, + { name: `${getMessage('width')} (mm)`, prop: 'width' }, + { name: `${getMessage('output')} (W)`, prop: 'output' }, + ], + rows: [ + { + module: { name: 'Re.RISE-G3 440', color: '#AA6768' }, + height: { name: '1134' }, + width: { name: '1722' }, + output: { name: '440' }, + }, + { + module: { + name: 'Re.RISE MS-G3 290', + color: '#67A2AA', + }, + height: { name: '1134' }, + width: { name: '1722' }, + output: { name: '240' }, + }, + ], + } + return ( + <> +
+
+
+
+ {getMessage('modal.module.basic.setting.module.setting')} +
+ +
+
+
+ + + + {moduleData.header.map((data) => ( + + ))} + + + + {moduleData.rows.map((row) => ( + <> + + {moduleData.header.map((header) => ( + <> + {header.type === 'color-box' && ( + + )} + {!header.type && header.type !== 'color-box' && } + + ))} + + + ))} + + {Array.from({ length: 3 - moduleData.rows.length }).map((_, i) => ( + + + + + + + ))} + +
+ {data.name} +
+
+ + {row[header.prop].name} +
+
{row[header.prop].name}
+
+
+
+
+
+ + + + +
+
+
{getMessage('modal.module.basic.setting.module.roof.material')}: スレーツ(4寸)
+
+
+
{getMessage('modal.module.basic.setting.module.trestle.maker')}
+
+
+ +
+
+
+
+
{getMessage('modal.module.basic.setting.module.construction.method')}
+
+
+ +
+
+
+
+
{getMessage('modal.module.basic.setting.module.under.roof')}
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ {getMessage('modal.module.basic.setting.module.cotton.classification')} +
+ +
+
+
+ {getMessage('modal.module.basic.setting.module.fitting.height')} +
+ +
+
+
+ {getMessage('modal.module.basic.setting.module.standard.wind.speed')} +
+ +
+
+
+ {getMessage('modal.module.basic.setting.module.standard.snowfall.amount')} +
+ +
+
+
+
+
+
+
+
+ {getMessage('modal.module.basic.setting.module.setting.info1')} +
+ {getMessage('modal.module.basic.setting.module.setting.info2')} +
+
+
+
+
+ + + + + +
+
+
+ + +
+
+ + +
+
+ + ) +} diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx new file mode 100644 index 00000000..3ef15a21 --- /dev/null +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -0,0 +1,62 @@ +import { useState } from 'react' +import { useMessage } from '@/hooks/useMessage' + +export default function Orientation({ setTabNum }) { + const { getMessage } = useMessage() + const [compasDeg, setCompasDeg] = useState(0) + const [hasAnglePassivity, setHasAnglePassivity] = useState(false) + + return ( + <> +
+
{getMessage('modal.module.basic.setting.orientation.setting')}
+
+
{getMessage('modal.module.basic.setting.orientation.setting.info')}
+
+
+
+ {Array.from({ length: 180 / 15 }).map((dot, index) => ( +
setCompasDeg(15 * (12 + index))} + > + {index === 0 && 180°} + {index === 6 && 270°} +
+ ))} + {Array.from({ length: 180 / 15 }).map((dot, index) => ( +
setCompasDeg(15 * index)}> + {index === 0 && } + {index === 6 && 90°} +
+ ))} +
+
+
+
+
+
+
+
+ setHasAnglePassivity(!hasAnglePassivity)} /> + +
+
+
+ setCompasDeg(e.target.value !== '' ? Number.parseInt(e.target.value) : 0)} + /> +
+ ° +
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx new file mode 100644 index 00000000..4771ab2a --- /dev/null +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -0,0 +1,140 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Placement() { + const { getMessage } = useMessage() + const moduleData = { + header: [ + { type: 'check', name: '', prop: 'check', width: 70 }, + { type: 'color-box', name: getMessage('module'), prop: 'module' }, + { type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 }, + ], + rows: [ + { + check: false, + module: { name: 'Re.RISE-G3 440', color: '#AA6768' }, + output: { name: '440' }, + }, + { + check: false, + module: { + name: 'Re.RISE MS-G3 290', + color: '#67A2AA', + }, + output: { name: '240' }, + }, + ], + } + return ( + <> +
+
+
+
+ + + + {moduleData.header.map((data) => ( + + ))} + + + + {moduleData.rows.map((row) => ( + <> + + {moduleData.header.map((header) => ( + <> + {header.type === 'color-box' && ( + + )} + {header.type === 'check' && ( + + )} + {header.type && header.type !== 'color-box' && header.type !== 'check' && ( + + )} + + ))} + + + ))} + + + + + + +
+ {data.type === 'check' ? ( +
+ + +
+ ) : ( + data.name + )} +
+
+ + {row[header.prop].name} +
+
+
+ + +
+
{row[header.prop].name}
+
+
+
+
+
+
{getMessage('modal.module.basic.setting.module.placement.select.fitting.type')}
+
+
+
{getMessage('modal.module.basic.setting.module.placement.waterfowl.arrangement')}
+
+
+
+ + +
+
+ + +
+
+
+
+
+
{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+ + +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx new file mode 100644 index 00000000..255833a8 --- /dev/null +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx @@ -0,0 +1,91 @@ +import { useMessage } from '@/hooks/useMessage' +import QSelectBox from '@/components/common/select/QSelectBox' + +export default function PitchModule({}) { + const { getMessage } = useMessage() + const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }] + const moduleData = { + header: [ + { name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' }, + { + name: `${getMessage('높이')} (mm)`, + prop: 'height', + }, + { name: `${getMessage('width')} (mm)`, prop: 'width' }, + { name: `${getMessage('output')} (W)`, prop: 'output' }, + ], + rows: [ + { + module: { name: 'Re.RISE-G3 440', color: '#AA6768' }, + height: { name: '1134' }, + width: { name: '1722' }, + output: { name: '440' }, + }, + { + module: { + name: 'Re.RISE MS-G3 290', + color: '#67A2AA', + }, + height: { name: '1134' }, + width: { name: '1722' }, + output: { name: '240' }, + }, + ], + } + return ( + <> +
+
+
+ {getMessage('modal.module.basic.setting.module.setting')} +
+ +
+
+
+ + + + {moduleData.header.map((data) => ( + + ))} + + + + {moduleData.rows.map((row) => ( + <> + + {moduleData.header.map((header) => ( + <> + {header.type === 'color-box' && ( + + )} + {!header.type && header.type !== 'color-box' && } + + ))} + + + ))} + {Array.from({ length: 3 - moduleData.rows.length }).map((_, i) => ( + + + + + + + ))} + +
+ {data.name} +
+
+ + {row[header.prop].name} +
+
{row[header.prop].name}
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx new file mode 100644 index 00000000..a2dcd556 --- /dev/null +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx @@ -0,0 +1,105 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function PitchPlacement() { + const { getMessage } = useMessage() + const moduleData = { + header: [ + { type: 'check', name: '', prop: 'check', width: 70 }, + { type: 'color-box', name: getMessage('module'), prop: 'module' }, + { type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 }, + ], + rows: [ + { + check: false, + module: { name: 'Re.RISE-G3 440', color: '#AA6768' }, + output: { name: '440' }, + }, + { + check: false, + module: { + name: 'Re.RISE MS-G3 290', + color: '#67A2AA', + }, + output: { name: '240' }, + }, + ], + } + return ( + <> +
+
+
+ + + + {moduleData.header.map((data) => ( + + ))} + + + + {moduleData.rows.map((row) => ( + <> + + {moduleData.header.map((header) => ( + <> + {header.type === 'color-box' && ( + + )} + {header.type === 'check' && ( + + )} + {header.type && header.type !== 'color-box' && header.type !== 'check' && } + + ))} + + + ))} + +
+ {data.type === 'check' ? ( +
+ + +
+ ) : ( + data.name + )} +
+
+ + {row[header.prop].name} +
+
+
+ + +
+
{row[header.prop].name}
+
+
+
+
+
+
+
+
{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting')}
+
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx new file mode 100644 index 00000000..f165bde0 --- /dev/null +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -0,0 +1,57 @@ +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import PowerConditionalSelect from '@/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect' +import CircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation' +import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp' +import { useMessage } from '@/hooks/useMessage' + +export default function CircuitTrestleSetting({ setShowCircuitTrestleSettingModal }) { + const { getMessage } = useMessage() + const [tabNum, setTabNum] = useState(1) + const [circuitAllocationType, setCircuitAllocationType] = useState(1) + const circuitProps = { + circuitAllocationType, + setCircuitAllocationType, + } + return ( + +
+
+

{getMessage('modal.circuit.trestle.setting')}

+ +
+
+
+
+ {getMessage('modal.circuit.trestle.setting.power.conditional.select')} +
+ +
+ {getMessage('modal.circuit.trestle.setting.circuit.allocation')} +
+ +
{getMessage('modal.circuit.trestle.setting.step.up.allocation')}
+
+ {tabNum === 1 && } + {tabNum === 2 && } + {tabNum === 3 && } +
+ {tabNum !== 1 && ( + + )} + {tabNum !== 3 && ( + + )} + {tabNum === 3 && } +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation.jsx new file mode 100644 index 00000000..b980eeb4 --- /dev/null +++ b/src/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation.jsx @@ -0,0 +1,25 @@ +import AutoCircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation' +import PassivityCircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation' +import { useMessage } from '@/hooks/useMessage' + +export default function CircuitAllocation(props) { + const { getMessage } = useMessage() + const { circuitAllocationType, setCircuitAllocationType } = props + return ( + <> +
+ + +
+
+
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}
+ {circuitAllocationType === 1 && } + {circuitAllocationType === 2 && } +
+ + ) +} diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx new file mode 100644 index 00000000..9eadeb7f --- /dev/null +++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx @@ -0,0 +1,146 @@ +import QSelectBox from '@/components/common/select/QSelectBox' +import { useMessage } from '@/hooks/useMessage' +import { useState } from 'react' + +const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }] + +export default function PowerConditionalSelect({ setTabNum }) { + const { getMessage } = useMessage() + const [selectedRowIndex, setSelectedRowIndex] = useState(null) + const [powerConditions, setPowerConditions] = useState([]) + const seriesData = { + header: [ + { name: getMessage('명칭'), width: '15%', prop: 'name', type: 'color-box' }, + { + name: `${getMessage('modal.circuit.trestle.setting.power.conditional.select.rated.output')} (kW)`, + width: '10%', + prop: 'ratedOutput', + }, + { + name: `${getMessage('modal.circuit.trestle.setting.power.conditional.select.circuit.amount')}`, + width: '10%', + prop: 'circuitAmount', + }, + { + name: `${getMessage('modal.circuit.trestle.setting.power.conditional.select.max.connection')}`, + width: '10%', + prop: 'maxConnection', + }, + { + name: `${getMessage('modal.circuit.trestle.setting.power.conditional.select.max.overload')}`, + width: '10%', + prop: 'maxOverload', + }, + { + name: `${getMessage('modal.circuit.trestle.setting.power.conditional.select.output.current')}`, + width: '10%', + prop: 'outputCurrent', + }, + ], + rows: [ + { + name: { name: 'PCSオプションマスター', color: '#AA6768' }, + ratedOutput: { name: '2' }, + circuitAmount: { name: '2' }, + maxConnection: { name: '-' }, + maxOverload: { name: '-' }, + outputCurrent: { name: '-' }, + }, + { + name: { name: 'HQJP-KA40-5', color: '#AA6768' }, + ratedOutput: { name: '2' }, + circuitAmount: { name: '2' }, + maxConnection: { name: '-' }, + maxOverload: { name: '-' }, + outputCurrent: { name: '-' }, + }, + { + name: { name: 'Re.RISE-G3 440', color: '#AA6768' }, + ratedOutput: { name: '2' }, + circuitAmount: { name: '2' }, + maxConnection: { name: '-' }, + maxOverload: { name: '-' }, + outputCurrent: { name: '-' }, + }, + ], + } + return ( + <> +
+ 分類 (余剰) +
+ +
+ 寒冷地仕様 +
+
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+ + + + {seriesData.header.map((header) => ( + + ))} + + + + {seriesData.rows.map((row, index) => ( + setSelectedRowIndex(index)} className={index === selectedRowIndex ? 'on' : ''}> + {seriesData.header.map((header) => ( + + ))} + + ))} + +
+ {header.name} +
{row[header.prop].name}
+
+
+
+ +
+
+ + HQJP-KA40-5 + + + HQJP-KA40-5 + + + HQJP-KA40-5 + +
+
+
+
+
+ + +
+
+ + +
+
+ + ) +} diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx new file mode 100644 index 00000000..6a11ed71 --- /dev/null +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -0,0 +1,414 @@ +import QSelectBox from '@/components/common/select/QSelectBox' +import { useMessage } from '@/hooks/useMessage' + +const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }] + +export default function StepUp({}) { + const { getMessage } = useMessage() + return ( + <> +
+
{getMessage('modal.circuit.trestle.setting.step.up.allocation')}
+
+
+
+
+
HQJP-KA55-5
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
シリアル枚数総回路数
100
100
100
100
100
+
+
+
+
+
接続する
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
名称回路数昇圧回路数
KTN-CBD4C40
KTN-CBD4C40
KTN-CBD4C40
+
+
+
+ +
+
+ + HQJP-KA40-5 + +
+
+
+
+
昇圧オプション
+
+ + + + + + + + + + + + + + + + + +
名称昇圧回路数
--
--
+
+
+
+ +
+
+ + HQJP-KA40-5 + +
+
+
+
+
+ 綿調道区分 +
+ +
+ 回路 + (二重昇圧回路数 +
+ +
+ 回路) +
+
+
+
+
+
+
HQJP-KA55-5
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
シリアル枚数総回路数
100
100
100
100
100
+
+
+
+
+
接続する
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
名称回路数昇圧回路数
KTN-CBD4C40
KTN-CBD4C40
KTN-CBD4C40
+
+
+
+ +
+
+ + HQJP-KA40-5 + +
+
+
+
+
昇圧オプション
+
+ + + + + + + + + + + + + + + + + +
名称昇圧回路数
--
--
+
+
+
+ +
+
+ + HQJP-KA40-5 + +
+
+
+
+
+ 綿調道区分 +
+ +
+ 回路 + (二重昇圧回路数 +
+ +
+ 回路) +
+
+
+
+
+
+
HQJP-KA55-5
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
シリアル枚数総回路数
100
100
100
100
100
+
+
+
+
+
接続する
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
名称回路数昇圧回路数
KTN-CBD4C40
KTN-CBD4C40
KTN-CBD4C40
+
+
+
+ +
+
+ + HQJP-KA40-5 + +
+
+
+
+
昇圧オプション
+
+ + + + + + + + + + + + + + + + + +
名称昇圧回路数
--
--
+
+
+
+ +
+
+ + HQJP-KA40-5 + +
+
+
+
+
+ 綿調道区分 +
+ +
+ 回路 + (二重昇圧回路数 +
+ +
+ 回路) +
+
+
+
+
+
+ + モニターの選択 + +
+ +
+
+
+
+ {/*
*/} + {/* */} + {/* */} + {/*
*/} + + ) +} diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation.jsx new file mode 100644 index 00000000..026bbaee --- /dev/null +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation.jsx @@ -0,0 +1,17 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function AutoCircuitAllocation() { + const { getMessage } = useMessage() + return ( +
+
+
+
+ + +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx new file mode 100644 index 00000000..5233d992 --- /dev/null +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -0,0 +1,104 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function PassivityCircuitAllocation() { + const { getMessage } = useMessage() + const moduleData = { + header: [ + { name: getMessage('屋根面'), prop: 'roofShape' }, + { + name: getMessage('Q.TRON M-G2'), + prop: 'moduleName', + }, + { + name: getMessage('発電量 (kW)'), + prop: 'powerGeneration', + }, + ], + rows: [ + { + roofShape: { name: 'M 1' }, + moduleName: { name: '8' }, + powerGeneration: { name: '3,400' }, + }, + { + roofShape: { name: 'M 1' }, + moduleName: { name: '8' }, + powerGeneration: { name: '3,400' }, + }, + ], + } + return ( + <> +
+
+
{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity')}
+
{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.info')}
+
+ + + + {moduleData.header.map((header) => ( + + ))} + + + + {moduleData.rows.map((row, index) => ( + + {moduleData.header.map((header) => ( + + ))} + + ))} + +
{header.name}
{row[header.prop].name}
+
+
+
+
+
+
+
+
{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional')}
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+ + {getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num')} + +
+ +
+
+
+
+ + + +
+
+ + ) +} diff --git a/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx b/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx new file mode 100644 index 00000000..bab1e696 --- /dev/null +++ b/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx @@ -0,0 +1,65 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import Eaves from '@/components/floor-plan/modal/eavesGable/type/Eaves' +import Gable from '@/components/floor-plan/modal/eavesGable/type/Gable' +import WallMerge from '@/components/floor-plan/modal/eavesGable/type/WallMerge' +import Shed from '@/components/floor-plan/modal/eavesGable/type/Shed' +import { useEavesGableEdit } from '@/hooks/roofcover/useEavesGableEdit' + +export default function EavesGableEdit({ setShowEavesGableEditModal }) { + const { getMessage } = useMessage() + + const { type, setType, buttonMenu, TYPES, pitchRef, offsetRef, widthRef, radioTypeRef } = useEavesGableEdit(setShowEavesGableEditModal) + const eavesProps = { + pitchRef, + offsetRef, + widthRef, + radioTypeRef, + } + + const gableProps = { + pitchRef, + offsetRef, + widthRef, + radioTypeRef, + } + + const wallMergeProps = { + offsetRef, + radioTypeRef, + } + + const shedProps = { + offsetRef, + } + + return ( + +
+
+

{getMessage('modal.eaves.gable.edit')}

+ +
+
+
+ {buttonMenu.map((item) => ( + + ))} +
+
+
{getMessage('setting')}
+ {type === TYPES.EAVES && } + {type === TYPES.GABLE && } + {type === TYPES.WALL_MERGE && } + {type === TYPES.SHED && } +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/eavesGable/type/Eaves.jsx b/src/components/floor-plan/modal/eavesGable/type/Eaves.jsx new file mode 100644 index 00000000..80120107 --- /dev/null +++ b/src/components/floor-plan/modal/eavesGable/type/Eaves.jsx @@ -0,0 +1,81 @@ +import { useMessage } from '@/hooks/useMessage' +import Image from 'next/image' +import { useState } from 'react' + +export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef }) { + const { getMessage } = useMessage() + const [type, setType] = useState('1') + const onChange = (e) => { + setType(e.target.value) + radioTypeRef.current = e.target.value + } + return ( + <> +
+
+ + {getMessage('slope')} + +
+ +
+ +
+
+ + {getMessage('offset')} + +
+ +
+ mm +
+
+
+
+
+
+
+ onChange(e)} /> + +
+
+
+
+ react +
+
+
+
+
+
+ onChange(e)} /> + +
+
+
+
+ react +
+
+
+
+
+
+
+ +
+ mm +
+
+
+
+ react +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/eavesGable/type/Gable.jsx b/src/components/floor-plan/modal/eavesGable/type/Gable.jsx new file mode 100644 index 00000000..23f9c300 --- /dev/null +++ b/src/components/floor-plan/modal/eavesGable/type/Gable.jsx @@ -0,0 +1,93 @@ +import { useMessage } from '@/hooks/useMessage' +import Image from 'next/image' +import { useState } from 'react' + +export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef }) { + const { getMessage } = useMessage() + const [type, setType] = useState('1') + const onChange = (e) => { + setType(e.target.value) + radioTypeRef.current = e.target.value + } + return ( + <> +
+
+ + {getMessage('offset')} + +
+ +
+ mm +
+
+
+
+
+
+
+ onChange(e)} /> + +
+
+
+
+ react +
+
+
+
+
+
+ onChange(e)} /> + +
+
+
+
+ react +
+
+
+
+
+
+ + {getMessage('slope')} + +
+ +
+ +
+
+
+
+ react +
+
+
+
+
+
+ + {getMessage('offset')} + +
+ +
+ mm +
+
+
+
+ react +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/eavesGable/type/Shed.jsx b/src/components/floor-plan/modal/eavesGable/type/Shed.jsx new file mode 100644 index 00000000..436316a3 --- /dev/null +++ b/src/components/floor-plan/modal/eavesGable/type/Shed.jsx @@ -0,0 +1,20 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Shed({ offsetRef }) { + const { getMessage } = useMessage() + return ( + <> +
+
+ + {getMessage('offset')} + +
+ +
+ mm +
+
+ + ) +} diff --git a/src/components/floor-plan/modal/eavesGable/type/WallMerge.jsx b/src/components/floor-plan/modal/eavesGable/type/WallMerge.jsx new file mode 100644 index 00000000..0f80f9ec --- /dev/null +++ b/src/components/floor-plan/modal/eavesGable/type/WallMerge.jsx @@ -0,0 +1,65 @@ +import { useMessage } from '@/hooks/useMessage' +import Image from 'next/image' +import { useState } from 'react' + +export default function WallMerge({ offsetRef, radioTypeRef }) { + const { getMessage } = useMessage() + const [type, setType] = useState('1') + const onChange = (e) => { + setType(e.target.value) + radioTypeRef.current = e.target.value + } + return ( + <> +
+
{getMessage('modal.eaves.gable.edit.wall.merge.info')}
+
+
+
+
+ onChange(e)} /> + +
+
+
+
+ react +
+
+
+
+
+
+ onChange(e)} /> + +
+
+
+
+ react +
+
+
+
+
+
+ + {getMessage('offset')} + +
+ +
+ mm +
+
+
+
+ react +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index db700207..eb5a834e 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -1,12 +1,15 @@ -import WithDraggable from '@/components/common/draggable/withDraggable' +import WithDraggable from '@/components/common/draggable/WithDraggable' import QSelectBox from '@/components/common/select/QSelectBox' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom' -import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' +import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { onlyNumberInputChange } from '@/util/input-utils' import { fabric } from 'fabric' import { gridColorState } from '@/store/gridAtom' +import { settingModalGridOptionsState } from '@/store/settingAtom' +import { useAxios } from '@/hooks/useAxios' +import { useSwal } from '@/hooks/useSwal' const TYPE = { DOT: 'DOT', @@ -15,8 +18,10 @@ const TYPE = { export default function DotLineGrid(props) { // const [modalOption, setModalOption] = useRecoilState(modalState); //modal 열림닫힘 state + const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요 const [close, setClose] = useState(false) const { setShowDotLineGridModal } = props + const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) const gridColor = useRecoilValue(gridColorState) const canvas = useRecoilValue(canvasState) @@ -25,6 +30,19 @@ export default function DotLineGrid(props) { const interval = useRecoilValue(dotLineIntervalSelector) const { getMessage } = useMessage() + const { get, post } = useAxios() + const { swalFire } = useSwal() + + useEffect(() => { + return () => { + setSettingModalGridOptions((prev) => { + const newSettingOptions = [...prev] + newSettingOptions[1].selected = false + return [...newSettingOptions] + }) + } + }, []) + const SelectOption = [ { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, { id: 2, name: '1/2', value: 1 / 2 }, @@ -33,6 +51,12 @@ export default function DotLineGrid(props) { ] const [selectOption, setSelectOption] = useState(SelectOption[0]) + // 데이터를 최초 한 번만 조회 + useEffect(() => { + console.log('DotLineGrid useEffect 실행') + fetchGridSettings() + }, [objectNo]) + const HandleClickClose = () => { // setClose(true) // setTimeout(() => { @@ -51,118 +75,177 @@ export default function DotLineGrid(props) { }) } - const handleSave = () => { - // 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거 - canvas - ?.getObjects() - .filter((obj) => obj.name === 'lineGrid') - .forEach((obj) => canvas?.remove(obj)) - canvas - ?.getObjects() - .filter((obj) => obj.name === 'dotGrid') - .forEach((obj) => canvas?.remove(obj)) + // Canvas Grid Setting 조회 및 초기화 + const fetchGridSettings = async () => { + try { + const res = await get({ url: `/api/canvas-management/canvas-grid-settings/by-object/${objectNo}` }) - const horizontalInterval = interval.horizontalInterval - const verticalInterval = interval.verticalInterval - - if (dotLineGridSetting.DOT) { - const circle = new fabric.Circle({ - radius: 2, - fill: 'red', - strokeWidth: 0.7, - originX: 'center', - originY: 'center', - selectable: false, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - }) - - const patternSourceCanvas = new fabric.StaticCanvas(null, { - width: horizontalInterval, - height: verticalInterval, - }) - - patternSourceCanvas.add(circle) - - circle.set({ - left: patternSourceCanvas.width / 2, - top: patternSourceCanvas.height / 2, - }) - - patternSourceCanvas.renderAll() - - const pattern = new fabric.Pattern({ - source: patternSourceCanvas.getElement(), - repeat: 'repeat', - }) - - const backgroundPolygon = new fabric.Polygon( - [ - { x: 0, y: 0 }, - { x: canvas.width, y: 0 }, - { x: canvas.width, y: canvas.height }, - { x: 0, y: canvas.height }, - ], - { - fill: pattern, - selectable: false, - name: 'dotGrid', + const patternData = { + INTERVAL: { + type: res.gridType, + horizontalInterval: res.gridHorizon, + verticalInterval: res.gridVertical, + ratioInterval: res.gridRatio, }, - ) + dimension: res.gridDimen, + DOT: res.dotGridDisplay, + LINE: res.lineGridDisplay, + } - canvas.add(backgroundPolygon) - backgroundPolygon.sendToBack() - canvas.renderAll() + const matchedOption = SelectOption.find((option) => option.value == res.gridDimen) + + // dimension 값에 맞는 옵션을 선택 + setSelectOption(matchedOption) + + // 서버에서 받은 데이터로 상태 업데이트 + setDotLineGridSettingState(patternData) + } catch (error) { + console.error('Data fetching error:', error) } + } - if (dotLineGridSetting.LINE) { - for (let i = 0; i < canvas.height / verticalInterval + 1; i++) { - const horizontalLine = new fabric.Line( - [0, i * verticalInterval - verticalInterval / 2, canvas.width, i * verticalInterval - verticalInterval / 2], - { - stroke: gridColor, - strokeWidth: 1, - selectable: true, + const handleSave = async () => { + try { + const patternData = { + objectNo, + dotGridDisplay: dotLineGridSetting.DOT, + lineGridDisplay: dotLineGridSetting.LINE, + gridType: dotLineGridSetting.INTERVAL.type, + gridHorizon: dotLineGridSetting.INTERVAL.horizontalInterval, + gridVertical: dotLineGridSetting.INTERVAL.verticalInterval, + gridRatio: dotLineGridSetting.INTERVAL.ratioInterval, + gridDimen: dotLineGridSetting.INTERVAL.dimension, + } + + // HTTP POST 요청 보내기 + await post({ url: `/api/canvas-management/canvas-grid-settings`, data: patternData }).then((res) => { + swalFire({ text: getMessage(res.returnMessage) }) + + // 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거 + canvas + ?.getObjects() + .filter((obj) => obj.name === 'lineGrid') + .forEach((obj) => canvas?.remove(obj)) + canvas + ?.getObjects() + .filter((obj) => obj.name === 'dotGrid') + .forEach((obj) => canvas?.remove(obj)) + + //const horizontalInterval = interval.horizontalInterval + //const verticalInterval = interval.verticalInterval + + if (patternData.dotGridDisplay) { + const circle = new fabric.Circle({ + radius: 2, + fill: 'red', + strokeWidth: 0.7, + originX: 'center', + originY: 'center', + selectable: false, lockMovementX: true, lockMovementY: true, lockRotation: true, lockScalingX: true, lockScalingY: true, - name: 'lineGrid', - strokeDashArray: [5, 2], - opacity: 0.3, - direction: 'horizontal', - }, - ) - canvas.add(horizontalLine) - } + }) - for (let i = 0; i < canvas.width / horizontalInterval + 1; i++) { - const verticalLine = new fabric.Line( - [i * horizontalInterval - horizontalInterval / 2, 0, i * horizontalInterval - horizontalInterval / 2, canvas.height], - { - stroke: 'black', - strokeWidth: 1, - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: 'lineGrid', - strokeDashArray: [5, 2], - opacity: 0.3, - direction: 'vertical', - }, - ) - canvas.add(verticalLine) - } + const patternSourceCanvas = new fabric.StaticCanvas(null, { + width: patternData.gridHorizon, + height: patternData.gridVertical, + }) + + patternSourceCanvas.add(circle) + + circle.set({ + left: patternSourceCanvas.width / 2, + top: patternSourceCanvas.height / 2, + }) + + patternSourceCanvas.renderAll() + + const pattern = new fabric.Pattern({ + source: patternSourceCanvas.getElement(), + repeat: 'repeat', + }) + + const backgroundPolygon = new fabric.Polygon( + [ + { x: 0, y: 0 }, + { x: canvas.width, y: 0 }, + { x: canvas.width, y: canvas.height }, + { x: 0, y: canvas.height }, + ], + { + fill: pattern, + selectable: false, + name: 'dotGrid', + }, + ) + + canvas.add(backgroundPolygon) + backgroundPolygon.sendToBack() + canvas.renderAll() + } + + if (patternData.lineGridDisplay) { + for (let i = 0; i < canvas.height / patternData.gridVertical + 1; i++) { + const horizontalLine = new fabric.Line( + [ + 0, + i * patternData.gridVertical - patternData.gridVertical / 2, + canvas.width, + i * patternData.gridVertical - patternData.gridVertical / 2, + ], + { + stroke: gridColor, + strokeWidth: 1, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: 'lineGrid', + strokeDashArray: [5, 2], + opacity: 0.3, + direction: 'horizontal', + }, + ) + canvas.add(horizontalLine) + } + + for (let i = 0; i < canvas.width / patternData.gridHorizon + 1; i++) { + const verticalLine = new fabric.Line( + [ + i * patternData.gridHorizon - patternData.gridHorizon / 2, + 0, + i * patternData.gridHorizon - patternData.gridHorizon / 2, + canvas.height, + ], + { + stroke: gridColor, + strokeWidth: 1, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: 'lineGrid', + strokeDashArray: [5, 2], + opacity: 0.3, + direction: 'vertical', + }, + ) + canvas.add(verticalLine) + } + } + + canvas.renderAll() + }) + } catch (error) { + swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) } - - canvas.renderAll() } const handleRadioChange = (e) => { @@ -220,7 +303,7 @@ export default function DotLineGrid(props) { } return ( - +

{getMessage('modal.canvas.setting.grid.dot.line.setting')}

diff --git a/src/components/floor-plan/modal/grid/GridColorSetting.jsx b/src/components/floor-plan/modal/grid/GridColorSetting.jsx new file mode 100644 index 00000000..5b7b2ff6 --- /dev/null +++ b/src/components/floor-plan/modal/grid/GridColorSetting.jsx @@ -0,0 +1,39 @@ +import WithDraggable from '@/components/common/draggable/WithDraggable' +import ColorPicker from '@/components/common/color-picker/ColorPicker' +import { useRecoilState, useSetRecoilState } from 'recoil' +import { gridColorState } from '@/store/gridAtom' +import { useMessage } from '@/hooks/useMessage' +import { useEffect } from 'react' +import { settingModalGridOptionsState } from '@/store/settingAtom' + +export default function GridColorSetting(props) { + const { setShowColorPickerModal } = props + const [color, setColor] = useRecoilState(gridColorState) + const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) + const { getMessage } = useMessage() + + useEffect(() => { + return () => { + setSettingModalGridOptions((prev) => { + const newSettingOptions = [...prev] + newSettingOptions[3].selected = false + return [...newSettingOptions] + }) + } + }, []) + return ( + +
+
+

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

+ +
+
+ +
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/grid/GridCopy.jsx b/src/components/floor-plan/modal/grid/GridCopy.jsx index 92609d80..a6709d09 100644 --- a/src/components/floor-plan/modal/grid/GridCopy.jsx +++ b/src/components/floor-plan/modal/grid/GridCopy.jsx @@ -1,4 +1,4 @@ -import WithDraggable from '@/components/common/draggable/withDraggable' +import WithDraggable from '@/components/common/draggable/WithDraggable' import { useMessage } from '@/hooks/useMessage' export default function GridCopy(props) { diff --git a/src/components/floor-plan/modal/grid/GridMove.jsx b/src/components/floor-plan/modal/grid/GridMove.jsx index 1da8b6fa..db226872 100644 --- a/src/components/floor-plan/modal/grid/GridMove.jsx +++ b/src/components/floor-plan/modal/grid/GridMove.jsx @@ -1,4 +1,4 @@ -import WithDraggable from '@/components/common/draggable/withDraggable' +import WithDraggable from '@/components/common/draggable/WithDraggable' import { useMessage } from '@/hooks/useMessage' export default function GridMove(props) { diff --git a/src/components/floor-plan/modal/lineTypes/Angle.jsx b/src/components/floor-plan/modal/lineTypes/Angle.jsx new file mode 100644 index 00000000..83985016 --- /dev/null +++ b/src/components/floor-plan/modal/lineTypes/Angle.jsx @@ -0,0 +1,60 @@ +import Image from 'next/image' +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' + +export default function Angle({ props }) { + const { getMessage } = useMessage() + const { angle1, setAngle1, angle1Ref, length1, setLength1, length1Ref } = props + + return ( + <> +
+
+
+
+ {getMessage('modal.cover.outline.angle')} +
+ onlyNumberWithDotInputChange(e, setAngle1)} + placeholder="45" + /> +
+ +
+
+ {getMessage('modal.cover.outline.length')} +
+ onlyNumberInputChange(e, setLength1)} + placeholder="3000" + /> +
+ +
+
+
+ react +
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/lineTypes/Diagonal.jsx b/src/components/floor-plan/modal/lineTypes/Diagonal.jsx new file mode 100644 index 00000000..84c25329 --- /dev/null +++ b/src/components/floor-plan/modal/lineTypes/Diagonal.jsx @@ -0,0 +1,159 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange } from '@/util/input-utils' + +export default function Diagonal({ props }) { + const { getMessage } = useMessage() + + const { + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + outerLineDiagonalLength, + setOuterLineDiagonalLength, + outerLineDiagonalLengthRef, + arrow1, + setArrow1, + arrow2, + setArrow2, + } = props + return ( + <> +
+
+
+ + {getMessage('modal.cover.outline.diagonal')} +
+ {getMessage('modal.cover.outline.length')} +
+
+ onlyNumberInputChange(e, setOuterLineDiagonalLength)} + placeholder="3000" + /> +
+ +
+
+
+
+ {getMessage('modal.cover.outline.length')} +
+ onlyNumberInputChange(e, setLength1)} + placeholder="3000" + /> +
+ +
+
+ {getMessage('modal.cover.outline.arrow')} +
+ + + + +
+
+
+
+
+ {getMessage('modal.cover.outline.length')} +
+ onlyNumberInputChange(e, setLength2)} + readOnly={true} + placeholder="3000" + /> +
+
+
+ {getMessage('modal.cover.outline.arrow')} +
+ + + + +
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/lineTypes/DoublePitch.jsx b/src/components/floor-plan/modal/lineTypes/DoublePitch.jsx new file mode 100644 index 00000000..5bfa5950 --- /dev/null +++ b/src/components/floor-plan/modal/lineTypes/DoublePitch.jsx @@ -0,0 +1,206 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' +import { getDegreeByChon } from '@/util/canvas-util' + +export default function DoublePitch({ props }) { + const { getMessage } = useMessage() + const { + angle1, + setAngle1, + angle1Ref, + angle2, + setAngle2, + angle2Ref, + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + arrow1Ref, + arrow2Ref, + } = props + + const getLength2 = () => { + const angle1Value = angle1Ref.current.value + const angle2Value = angle2Ref.current.value + const length1Value = length1Ref.current.value + + const arrow1Value = arrow1Ref.current + const arrow2Value = arrow2Ref.current + + if (angle1Value !== 0 && length1Value !== 0 && angle2Value !== 0 && arrow1Value !== '') { + const radian1 = (getDegreeByChon(angle1Value) * Math.PI) / 180 + + const radian2 = (getDegreeByChon(angle2Value) * Math.PI) / 180 + return Math.floor((Math.tan(radian1) * length1Value) / Math.tan(radian2)) + } + + return 0 + } + + return ( + <> +
+
+
+ {getMessage('modal.cover.outline.angle')} +
+ onlyNumberWithDotInputChange(e, setAngle1)} + placeholder="45" + /> +
+ +
+
+
+
+ {getMessage('modal.cover.outline.length')} +
+ onlyNumberInputChange(e, setLength1)} + placeholder="3000" + /> +
+ +
+
+ {getMessage('modal.cover.outline.arrow')} +
+ + + + +
+
+
+
+
+
+
+ {getMessage('modal.cover.outline.angle')} +
+ { + onlyNumberWithDotInputChange(e, setAngle2) + console.log(getLength2()) + setLength2(getLength2()) + }} + placeholder="45" + /> +
+ +
+
+
+
+ {getMessage('modal.cover.outline.length')} +
+ onlyNumberInputChange(e, setLength2)} + readOnly={true} + placeholder="3000" + /> +
+ +
+
+ {getMessage('modal.cover.outline.arrow')} +
+ + + + +
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/lineTypes/OuterLineWall.jsx b/src/components/floor-plan/modal/lineTypes/OuterLineWall.jsx new file mode 100644 index 00000000..f469fba8 --- /dev/null +++ b/src/components/floor-plan/modal/lineTypes/OuterLineWall.jsx @@ -0,0 +1,63 @@ +'use client' + +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange } from '@/util/input-utils' + +export default function OuterLineWall({ props }) { + const { getMessage } = useMessage() + + const { length1, setLength1, length1Ref, arrow1, setArrow1 } = props + return ( +
+
+
+ {getMessage('straight.line')} +
+ onlyNumberInputChange(e, setLength1)} + placeholder="3000" + /> +
+ +
+
+ {getMessage('modal.cover.outline.arrow')} +
+ + + + +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/lineTypes/RightAngle.jsx b/src/components/floor-plan/modal/lineTypes/RightAngle.jsx new file mode 100644 index 00000000..306a09f0 --- /dev/null +++ b/src/components/floor-plan/modal/lineTypes/RightAngle.jsx @@ -0,0 +1,120 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange } from '@/util/input-utils' + +export default function RightAngle({ props }) { + const { getMessage } = useMessage() + const { length1, setLength1, length1Ref, length2, setLength2, length2Ref, arrow1, setArrow1, arrow2, setArrow2 } = props + return ( +
+
+
+ {getMessage('modal.cover.outline.length')} +
+ onlyNumberInputChange(e, setLength1)} + placeholder="3000" + /> +
+ +
+
+ {getMessage('modal.cover.outline.arrow')} +
+ + + + +
+
+
+
+
+ {getMessage('modal.cover.outline.length')} +
+ onlyNumberInputChange(e, setLength2)} + placeholder="3000" + /> +
+ +
+
+ {getMessage('modal.cover.outline.arrow')} +
+ + + + +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/movement/MovementSetting.jsx b/src/components/floor-plan/modal/movement/MovementSetting.jsx new file mode 100644 index 00000000..569249d6 --- /dev/null +++ b/src/components/floor-plan/modal/movement/MovementSetting.jsx @@ -0,0 +1,44 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import FlowLine from '@/components/floor-plan/modal/movement/type/FlowLine' +import Updown from '@/components/floor-plan/modal/movement/type/Updown' + +export default function MovementSetting({ setShowMovementModal }) { + const { getMessage } = useMessage() + const [buttonAct, setButtonAct] = useState(1) + const buttonMenu = [ + { id: 1, name: getMessage('modal.movement.flow.line.move') }, + { id: 2, name: getMessage('modal.movement.flow.line.updown') }, + ] + + return ( + +
+
+

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

+ +
+
+
+ {buttonMenu.map((item) => ( + + ))} +
+
+
{getMessage('setting')}
+ {buttonAct === 1 && } + {buttonAct === 2 && } +
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/movement/type/FlowLine.jsx b/src/components/floor-plan/modal/movement/type/FlowLine.jsx new file mode 100644 index 00000000..d1bf8023 --- /dev/null +++ b/src/components/floor-plan/modal/movement/type/FlowLine.jsx @@ -0,0 +1,46 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function FlowLine({}) { + const { getMessage } = useMessage() + + return ( + <> +
+
{getMessage('modal.movement.flow.line.info')}
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
+ +
+ mm +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/movement/type/Updown.jsx b/src/components/floor-plan/modal/movement/type/Updown.jsx new file mode 100644 index 00000000..2650ca4a --- /dev/null +++ b/src/components/floor-plan/modal/movement/type/Updown.jsx @@ -0,0 +1,46 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Updown({}) { + const { getMessage } = useMessage() + + return ( + <> +
+
{getMessage('modal.movement.flow.line.updown.info')}
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
+ +
+ mm +
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/object/ObjectSetting.jsx b/src/components/floor-plan/modal/object/ObjectSetting.jsx new file mode 100644 index 00000000..d5fe934e --- /dev/null +++ b/src/components/floor-plan/modal/object/ObjectSetting.jsx @@ -0,0 +1,113 @@ +'use client' + +import { useState, useRef, useEffect } from 'react' +import { useRecoilValue } from 'recoil' +import { useMessage } from '@/hooks/useMessage' +import { useEvent } from '@/hooks/useEvent' +import { canvasState } from '@/store/canvasAtom' +import { useSwal } from '@/hooks/useSwal' +import { useObjectBatch } from '@/hooks/object/useObjectBatch' +import { POLYGON_TYPE } from '@/common/common' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import OpenSpace from '@/components/floor-plan/modal/object/type/OpenSpace' +import Shadow from '@/components/floor-plan/modal/object/type/Shadow' +import TriangleDormer from '@/components/floor-plan/modal/object/type/TriangleDormer' +import PentagonDormer from '@/components/floor-plan/modal/object/type/PentagonDormer' + +export default function ObjectSetting({ setShowObjectSettingModal }) { + const { getMessage } = useMessage() + const canvas = useRecoilValue(canvasState) + const [buttonAct, setButtonAct] = useState(1) + const { swalFire } = useSwal() + const { applyOpeningAndShadow, applyDormers } = useObjectBatch() + + const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + + //오브젝트 배치로 넘어오면 면형상 선택 불가 + useEffect(() => { + canvas.discardActiveObject() + surfaceShapePolygons.forEach((obj) => { + obj.set({ selectable: false }) + }) + }, []) + + /** + * 개구배치, 그림자배치 + */ + const objectPlacement = { + typeRef: useRef([]), //프리입력, 치수입력 + widthRef: useRef(null), + heightRef: useRef(null), + isCrossRef: useRef(null), + } + + const dormerPlacement = { + widthRef: useRef(null), + heightRef: useRef(null), + pitchRef: useRef(null), + offsetRef: useRef(null), + directionRef: useRef(null), + } + + const applyObject = () => { + // if (surfaceShapePolygons.length === 0) { + // swalFire({ text: '지붕이 없어요 지붕부터 그리세요', icon: 'error' }) + // return + // } + + //개구배치, 그림자배치 + + console.log(surfaceShapePolygons) + + if (buttonAct === 1 || buttonAct === 2) { + applyOpeningAndShadow(objectPlacement, buttonAct, surfaceShapePolygons) + } else { + applyDormers(dormerPlacement, buttonAct, surfaceShapePolygons) + } + } + + const buttonMenu = [ + { id: 1, name: getMessage('modal.object.setting.type.open.space.placement') }, + { id: 2, name: getMessage('modal.object.setting.type.shadow.placement') }, + { id: 3, name: getMessage('modal.object.setting.type.triangle.dormer') }, + { id: 4, name: getMessage('modal.object.setting.type.pentagon.dormer') }, + ] + return ( + +
+
+

{getMessage('plan.menu.placement.surface.object')}

+ +
+
+
+ {buttonMenu.map((item) => ( + + ))} +
+
+
{getMessage('setting')}
+ {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } +
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/object/type/OpenSpace.jsx b/src/components/floor-plan/modal/object/type/OpenSpace.jsx new file mode 100644 index 00000000..ab4d287d --- /dev/null +++ b/src/components/floor-plan/modal/object/type/OpenSpace.jsx @@ -0,0 +1,94 @@ +import { forwardRef, useState, useEffect } from 'react' +import { useMessage } from '@/hooks/useMessage' +import { INPUT_TYPE } from '@/common/common' + +const OpenSpace = forwardRef((props, refs) => { + const { getMessage } = useMessage() + const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE) + + useEffect(() => { + if (selectedType === INPUT_TYPE.FREE) { + refs.widthRef.current.value = 0 + refs.heightRef.current.value = 0 + } + }, [selectedType]) + + //체크하면 값바꿈 + return ( +
+
+
+ (refs.typeRef.current[0] = el)} + onClick={() => setSelectedType(INPUT_TYPE.FREE)} + /> + +
+
+
+
+ (refs.typeRef.current[1] = el)} + onClick={() => setSelectedType(INPUT_TYPE.DIMENSION)} + /> + +
+
+
+
+
+
+
{getMessage('modal.object.setting.width')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.object.setting.height')}
+
+
+
+ +
+ mm +
+
+
+
+
+
+
+ + +
+
+ ) +}) + +export default OpenSpace diff --git a/src/components/floor-plan/modal/object/type/PentagonDormer.jsx b/src/components/floor-plan/modal/object/type/PentagonDormer.jsx new file mode 100644 index 00000000..e2aeea15 --- /dev/null +++ b/src/components/floor-plan/modal/object/type/PentagonDormer.jsx @@ -0,0 +1,92 @@ +import Image from 'next/image' +import { useMessage } from '@/hooks/useMessage' + +export default function PentagonDormer() { + const { getMessage } = useMessage() + return ( + <> +
+
{getMessage('modal.object.setting.size.setting')}
+
+
+ react +
+
+
+
+
{getMessage('modal.object.setting.agreement.depth')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.object.setting.offset.depth')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('width')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.object.setting.offset.depth')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('slope')}
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
方向の選択
+
+
+ {getMessage('commons.north')} + {getMessage('commons.east')} + {getMessage('commons.south')} + {getMessage('commons.west')} + + + + +
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/object/type/Shadow.jsx b/src/components/floor-plan/modal/object/type/Shadow.jsx new file mode 100644 index 00000000..0945d78c --- /dev/null +++ b/src/components/floor-plan/modal/object/type/Shadow.jsx @@ -0,0 +1,90 @@ +import { forwardRef, useState, useEffect } from 'react' +import { useMessage } from '@/hooks/useMessage' +import { INPUT_TYPE } from '@/common/common' + +const Shadow = forwardRef((props, refs) => { + const { getMessage } = useMessage() + + const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE) + + useEffect(() => { + if (selectedType === INPUT_TYPE.FREE) { + refs.widthRef.current.value = 0 + refs.heightRef.current.value = 0 + } + }, [selectedType]) + + return ( +
+
+
+ (refs.typeRef.current[0] = el)} + onClick={() => setSelectedType(INPUT_TYPE.FREE)} + /> + +
+
+
+
+ (refs.typeRef.current[1] = el)} + onClick={() => setSelectedType(INPUT_TYPE.DIMENSION)} + /> + +
+
+
+
+
+
+
{getMessage('modal.object.setting.width')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.object.setting.height')}
+
+
+
+ +
+ mm +
+
+
+
+
+
+
+ ) +}) + +export default Shadow diff --git a/src/components/floor-plan/modal/object/type/TriangleDormer.jsx b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx new file mode 100644 index 00000000..9ab7712d --- /dev/null +++ b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx @@ -0,0 +1,82 @@ +import Image from 'next/image' +import { useMessage } from '@/hooks/useMessage' +import { forwardRef, useState } from 'react' + +const TriangleDormer = forwardRef((props, refs) => { + const { getMessage } = useMessage() + const [direction, setDirection] = useState('down') + + refs.directionRef.current = direction + + const getDirection = (e) => { + setDirection(e.target.value) + refs.directionRef.current = e.target.value + } + + return ( + <> +
+
{getMessage('modal.object.setting.size.setting')}
+
+
+ react +
+
+
+
+
{getMessage('modal.object.setting.agreement.depth')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.object.setting.offset.depth')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('slope')}
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
方向の選択
+
+
+ {getMessage('commons.north')} + {getMessage('commons.east')} + {getMessage('commons.south')} + {getMessage('commons.west')} + + + + +
+
+
+ + ) +}) + +export default TriangleDormer diff --git a/src/components/floor-plan/modal/outerlinesetting/Angle.jsx b/src/components/floor-plan/modal/outerlinesetting/Angle.jsx deleted file mode 100644 index ca3ea288..00000000 --- a/src/components/floor-plan/modal/outerlinesetting/Angle.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import Image from 'next/image' -import { useMessage } from '@/hooks/useMessage' - -export default function Angle() { - const { getMessage } = useMessage() - return ( - <> -
-
-
-
- {getMessage('modal.cover.outline.angle')} -
- -
- -
-
- {getMessage('modal.cover.outline.arrow')} -
- -
- -
-
-
- react -
-
-
- - ) -} diff --git a/src/components/floor-plan/modal/outerlinesetting/Diagonal.jsx b/src/components/floor-plan/modal/outerlinesetting/Diagonal.jsx deleted file mode 100644 index 9ae9f02e..00000000 --- a/src/components/floor-plan/modal/outerlinesetting/Diagonal.jsx +++ /dev/null @@ -1,59 +0,0 @@ -import { useMessage } from '@/hooks/useMessage' - -export default function Diagonal() { - const { getMessage } = useMessage() - return ( - <> -
-
-
- - {getMessage('modal.cover.outline.diagonal')} -
- {getMessage('modal.cover.outline.length')} -
-
- -
- -
-
-
-
- {getMessage('modal.cover.outline.length')} -
- -
- -
-
- {getMessage('modal.cover.outline.arrow')} -
- - - - -
-
-
-
-
- {getMessage('modal.cover.outline.length')} -
- -
-
-
- {getMessage('modal.cover.outline.arrow')} -
- - - - -
-
-
-
- - ) -} diff --git a/src/components/floor-plan/modal/outerlinesetting/DoublePitch.jsx b/src/components/floor-plan/modal/outerlinesetting/DoublePitch.jsx deleted file mode 100644 index ea386d4b..00000000 --- a/src/components/floor-plan/modal/outerlinesetting/DoublePitch.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useMessage } from '@/hooks/useMessage' - -export default function DoublePitch() { - const { getMessage } = useMessage() - return ( - <> -
-
-
- {getMessage('modal.cover.outline.angle')} -
- -
- -
-
-
-
- {getMessage('modal.cover.outline.length')} -
- -
- -
-
- {getMessage('modal.cover.outline.arrow')} -
- - - - -
-
-
-
-
-
-
- {getMessage('modal.cover.outline.angle')} -
- -
- -
-
-
-
- {getMessage('modal.cover.outline.length')} -
- -
- -
-
- {getMessage('modal.cover.outline.arrow')} -
- - - - -
-
-
-
- - ) -} diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx deleted file mode 100644 index 9dfa85c8..00000000 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client' - -import { useMessage } from '@/hooks/useMessage' -import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall' -import { onlyNumberInputChange } from '@/util/input-utils' - -export default function OuterLineWall(props) { - const { getMessage } = useMessage() - const { length1, setLength1, length1Ref, arrow1, setArrow1 } = useOuterLineWall() - return ( -
-
-
- {getMessage('modal.cover.outline.length')} -
- onlyNumberInputChange(e, setLength1)} - placeholder="3000" - /> -
- -
-
- {getMessage('modal.cover.outline.arrow')} -
- - - - -
-
-
-
- ) -} diff --git a/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx new file mode 100644 index 00000000..d26b2ef3 --- /dev/null +++ b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx @@ -0,0 +1,56 @@ +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useMessage } from '@/hooks/useMessage' +import { usePropertiesSetting } from '@/hooks/roofcover/usePropertiesSetting' + +export default function PropertiesSetting(props) { + const { getMessage } = useMessage() + const { setShowPropertiesSettingModal } = props + + const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting(setShowPropertiesSettingModal) + + return ( + +
+
+

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

+ +
+
+
{getMessage('modal.canvas.setting.wallline.properties.setting.info')}
+
+
{getMessage('setting')}
+
+ + +
+
+
+ + +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/outerlinesetting/RightAngle.jsx b/src/components/floor-plan/modal/outerlinesetting/RightAngle.jsx deleted file mode 100644 index 815ab087..00000000 --- a/src/components/floor-plan/modal/outerlinesetting/RightAngle.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import { useMessage } from '@/hooks/useMessage' - -export default function RightAngle() { - const { getMessage } = useMessage() - return ( -
-
-
- {getMessage('modal.cover.outline.length')} -
- -
- -
-
- {getMessage('modal.cover.outline.arrow')} -
- - - - -
-
-
-
-
- {getMessage('modal.cover.outline.length')} -
- -
- -
-
- {getMessage('modal.cover.outline.arrow')} -
- - - - -
-
-
-
- ) -} diff --git a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx index 7e90bfb9..975a582a 100644 --- a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx @@ -1,22 +1,115 @@ 'use client' -import WithDraggable from '@/components/common/draggable/withDraggable' +import WithDraggable from '@/components/common/draggable/WithDraggable' import { useMessage } from '@/hooks/useMessage' import { OUTER_LINE_TYPE } from '@/store/outerLineAtom' import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall' -import OuterLineWall from '@/components/floor-plan/modal/outerlinesetting/OuterLineWall' -import RightAngle from '@/components/floor-plan/modal/outerlinesetting/RightAngle' -import Angle from '@/components/floor-plan/modal/outerlinesetting/Angle' -import DoublePitch from '@/components/floor-plan/modal/outerlinesetting/DoublePitch' -import Diagonal from '@/components/floor-plan/modal/outerlinesetting/Diagonal' +import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall' +import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle' +import Angle from '@/components/floor-plan/modal/lineTypes/Angle' +import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch' +import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal' export default function WallLineSetting(props) { - const { setShowOutlineModal } = props + const { setShowOutlineModal, setShowPropertiesSettingModal } = props const { getMessage } = useMessage() - const { type, setType, handleFix, handleRollback } = useOuterLineWall() + const { + length1, + setLength1, + length2, + setLength2, + length1Ref, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + angle1, + setAngle1, + angle1Ref, + angle2, + setAngle2, + angle2Ref, + type, + setType, + arrow1Ref, + arrow2Ref, + outerLineDiagonalLength, + setOuterLineDiagonalLength, + outerLineDiagonalLengthRef, + handleRollback, + handleFix, + } = useOuterLineWall(setShowOutlineModal) + + const outerLineProps = { + length1, + setLength1, + length1Ref, + arrow1, + setArrow1, + } + + const rightAngleProps = { + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + } + + const doublePitchProps = { + angle1, + setAngle1, + angle1Ref, + angle2, + setAngle2, + angle2Ref, + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + arrow1Ref, + arrow2Ref, + } + + const angleProps = { + angle1, + setAngle1, + angle1Ref, + length1, + setLength1, + length1Ref, + } + + const diagonalLineProps = { + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + outerLineDiagonalLength, + setOuterLineDiagonalLength, + outerLineDiagonalLengthRef, + arrow1, + setArrow1, + arrow2, + setArrow2, + } return ( - +

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

@@ -55,24 +148,33 @@ export default function WallLineSetting(props) { {getMessage('modal.cover.outline.diagonal')}
- {type === OUTER_LINE_TYPE.OUTER_LINE ? ( - - ) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? ( - - ) : type === OUTER_LINE_TYPE.DOUBLE_PITCH ? ( - - ) : type === OUTER_LINE_TYPE.ANGLE ? ( - - ) : type === OUTER_LINE_TYPE.DIAGONAL_LINE ? ( - - ) : ( - <> - )} +
+
{getMessage('modal.cover.outline.setting')}
+ {type === OUTER_LINE_TYPE.OUTER_LINE ? ( + + ) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? ( + + ) : type === OUTER_LINE_TYPE.DOUBLE_PITCH ? ( + + ) : type === OUTER_LINE_TYPE.ANGLE ? ( + + ) : type === OUTER_LINE_TYPE.DIAGONAL_LINE ? ( + + ) : ( + <> + )} +
-
diff --git a/src/components/floor-plan/modal/placementShape/MaterialGuide.jsx b/src/components/floor-plan/modal/placementShape/MaterialGuide.jsx new file mode 100644 index 00000000..eff09305 --- /dev/null +++ b/src/components/floor-plan/modal/placementShape/MaterialGuide.jsx @@ -0,0 +1,17 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function MaterialGuide({ setShowMaterialGuidModal }) { + const { getMessage } = useMessage() + return ( +
+
+ +
+
+
{getMessage('modal.placement.initial.setting.roof.material.info')}
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx new file mode 100644 index 00000000..0d2c301c --- /dev/null +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx @@ -0,0 +1,164 @@ +import { useMessage } from '@/hooks/useMessage' +import { useState } from 'react' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle' +import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch' +import Angle from '@/components/floor-plan/modal/lineTypes/Angle' +import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal' +import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall' +import { OUTER_LINE_TYPE } from '@/store/outerLineAtom' +import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall' +import { usePlacementShapeDrawing } from '@/hooks/surface/usePlacementShapeDrawing' + +export default function PlacementShapeDrawing({ setShowPlaceShapeDrawingModal }) { + const { getMessage } = useMessage() + const [buttonAct, setButtonAct] = useState(1) + const types = [ + { id: 1, name: getMessage('straight.line'), type: OUTER_LINE_TYPE.OUTER_LINE }, + { id: 2, name: getMessage('right.angle'), type: OUTER_LINE_TYPE.RIGHT_ANGLE }, + { id: 3, name: getMessage('double.pitch'), type: OUTER_LINE_TYPE.DOUBLE_PITCH }, + { id: 4, name: getMessage('angle'), type: OUTER_LINE_TYPE.ANGLE }, + { id: 5, name: getMessage('diagonal'), type: OUTER_LINE_TYPE.DIAGONAL_LINE }, + ] + const { + length1, + setLength1, + length2, + setLength2, + length1Ref, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + angle1, + setAngle1, + angle1Ref, + angle2, + setAngle2, + angle2Ref, + type, + setType, + arrow1Ref, + arrow2Ref, + outerLineDiagonalLength, + setOuterLineDiagonalLength, + outerLineDiagonalLengthRef, + handleRollback, + handleFix, + } = usePlacementShapeDrawing(setShowPlaceShapeDrawingModal) + + const outerLineProps = { + length1, + setLength1, + length1Ref, + arrow1, + setArrow1, + } + + const rightAngleProps = { + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + } + + const doublePitchProps = { + angle1, + setAngle1, + angle1Ref, + angle2, + setAngle2, + angle2Ref, + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + arrow1, + setArrow1, + arrow2, + setArrow2, + arrow1Ref, + arrow2Ref, + } + + const angleProps = { + angle1, + setAngle1, + angle1Ref, + length1, + setLength1, + length1Ref, + } + + const diagonalLineProps = { + length1, + setLength1, + length1Ref, + length2, + setLength2, + length2Ref, + outerLineDiagonalLength, + setOuterLineDiagonalLength, + outerLineDiagonalLengthRef, + arrow1, + setArrow1, + arrow2, + setArrow2, + } + + const onClickButton = (button) => { + setButtonAct(button.id) + setType(button.type) + } + return ( + +
+
+

{getMessage('plan.menu.placement.surface.drawing')}

+ +
+
+
+ {types.map((type, idx) => ( + + ))} +
+
+
{getMessage('setting')}
+ {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } + {buttonAct === 5 && } +
+ +
+ + +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx new file mode 100644 index 00000000..55cfcb6b --- /dev/null +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -0,0 +1,498 @@ +import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide' +import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input, Select, SelectItem } from '@nextui-org/react' +import { useRecoilState } from 'recoil' +import { Fragment, useEffect, useState } from 'react' +import { canvasSettingState } from '@/store/canvasAtom' +import { useMessage } from '@/hooks/useMessage' +import { useAxios } from '@/hooks/useAxios' +import { useSwal } from '@/hooks/useSwal' + +export default function PlacementShapeSetting({ setShowPlaceShapeModal }) { + const [objectNo, setObjectNo] = useState('test123241008001') // 후에 삭제 필요 + const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) + const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) + const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(1) + const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) + const [basicSetting, setBasicSettings] = useState({ + roofSizeSet: 1, + roofAngleSet: 'slope', + roofs: [{ roofApply: true, roofSeq: 1, roofType: 1, roofWidth: 200, roofHeight: 200, roofHajebichi: 200, roofGap: 0, roofLayout: 'parallel' }], + }) + + const { getMessage } = useMessage() + const { get, post } = useAxios() + const { swalFire } = useSwal() + + // 데이터를 최초 한 번만 조회 + useEffect(() => { + console.log('PlacementShapeSetting useEffect 실행') + + fetchSettings() + }, [objectNo]) + + // PlacementShapeSetting 조회 및 초기화 + const fetchSettings = async () => { + try { + await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${objectNo}` }).then((res) => { + if (res.length == 0) return + + // 'roofs' 배열을 생성하여 각 항목을 추가 + const roofsRow = res.map((item) => { + return { + roofSizeSet: item.roofSizeSet, + roofAngleSet: item.roofAngleSet, + } + }) + + const roofsArray = res.some((item) => !item.roofSeq) + ? //최초 지붕재 추가 정보의 경우 roofsArray를 초기화 설정 + res.map(() => ({ + roofApply: true, + roofSeq: 1, + roofType: 1, + roofWidth: 200, + roofHeight: 200, + roofHajebichi: 200, + roofGap: 0, + roofLayout: 'parallel', + })) + : res.map((item) => ({ + roofApply: item.roofApply === '' || item.roofApply === false ? false : true, + roofSeq: item.roofSeq, + roofType: item.roofType, + roofWidth: item.roofWidth, + roofHeight: item.roofHeight, + roofHajebichi: item.roofHajebichi, + roofGap: item.roofGap, + roofLayout: item.roofLayout, + })) + console.log('roofsArray ', roofsArray) + // 나머지 데이터와 함께 'roofs' 배열을 patternData에 넣음 + const patternData = { + roofSizeSet: roofsRow[0].roofSizeSet, // 첫 번째 항목의 값을 사용 + roofAngleSet: roofsRow[0].roofAngleSet, // 첫 번째 항목의 값을 사용 + roofs: roofsArray, // 만들어진 roofs 배열 + } + + // 데이터 설정 + setBasicSettings({ ...patternData }) + }) + } catch (error) { + console.error('Data fetching error:', error) + } + + if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { + setBasicSettings({ ...canvasSetting }) + } + } + + const submitCanvasConfig = async () => { + try { + const patternData = { + objectNo, + roofSizeSet: basicSetting.roofSizeSet, + roofAngleSet: basicSetting.roofAngleSet, + roofMaterialsAddList: basicSetting.roofs, + } + + await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { + swalFire({ text: getMessage(res.returnMessage) }) + }) + + //Recoil 설정 + setCanvasSetting({ ...basicSetting }) + } catch (error) { + swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) + } + } + + // Function to update the roofType and corresponding values + const handleRoofTypeChange = (index, value) => { + const updatedRoofs = [...basicSetting.roofs] + const roofType = parseInt(value, 10) + + // Reset other values based on the selected roofType + if (roofType === 1) { + updatedRoofs[index] = { + ...updatedRoofs[index], + roofType: 1, + roofWidth: 265, + roofHeight: 235, + roofGap: 455, + hajebichi: 0, + } + } else if (roofType === 2) { + updatedRoofs[index] = { + ...updatedRoofs[index], + roofType: 2, + roofGap: 265, + roofHajebichi: 265, + roofWidth: 0, + roofHeight: 0, + } + } else if (roofType === 3) { + updatedRoofs[index] = { + ...updatedRoofs[index], + roofType: 3, + roofHajebichi: 265, + roofGap: 0, + roofWidth: 0, + roofHeight: 0, + } + } else if (roofType === 4) { + updatedRoofs[index] = { + ...updatedRoofs[index], + roofType: 4, + roofHeight: 265, + roofGap: 265, + roofHajebichi: 0, + roofWidth: 0, + } + } + + setBasicSettings({ + ...basicSetting, + roofs: updatedRoofs, + }) + } + + return ( + +
+
+

{getMessage('plan.menu.placement.surface.initial.setting')}

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
{getMessage('modal.placement.initial.setting.plan.drawing')}{getMessage('modal.placement.initial.setting.plan.drawing.size.stuff')}
+ {getMessage('modal.placement.initial.setting.size')} + + +
+
+ setBasicSettings({ ...basicSetting, roofSizeSet: e.target.value })} // 상태 업데이트 + /> + +
+
+ setBasicSettings({ ...basicSetting, roofSizeSet: e.target.value })} // 상태 업데이트 + /> + +
+
+ setBasicSettings({ ...basicSetting, roofSizeSet: e.target.value })} // 상태 업데이트 + /> + +
+
+
{getMessage('modal.placement.initial.setting.roof.angle.setting')} +
+
+ setBasicSettings({ ...basicSetting, roofAngleSet: e.target.value })} // 상태 업데이트 + /> + +
+
+ setBasicSettings({ ...basicSetting, roofAngleSet: e.target.value })} // 상태 업데이트 + /> + +
+
+
+ {getMessage('modal.placement.initial.setting.roof.material')} + + +
+
+ +
+ {basicSetting.roofs[0].roofType === 1 ? ( + <> +
+ W +
+ +
+
+
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : basicSetting.roofs[0].roofType === 2 ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : basicSetting.roofs[0].roofType === 3 ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+ + ) : basicSetting.roofs[0].roofType === 4 ? ( + <> +
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : ( + '' + )} +
+
+
+
+ +
+
+ {showSizeGuideModal && } + {showMaterialGuideModal && } +
+
+ ) +} diff --git a/src/components/floor-plan/modal/placementShape/SizeGuide.jsx b/src/components/floor-plan/modal/placementShape/SizeGuide.jsx new file mode 100644 index 00000000..1f9d2770 --- /dev/null +++ b/src/components/floor-plan/modal/placementShape/SizeGuide.jsx @@ -0,0 +1,39 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function SizeGuide({ setShowSizeGuidModal }) { + const { getMessage } = useMessage() + return ( +
+
+ +
+
+
{getMessage('modal.placement.initial.setting.size.info')}
+
+ + + + + + + + + + + + + + + + + + + +
{getMessage('modal.placement.initial.setting.size.roof')}{getMessage('modal.placement.initial.setting.size.roof.info')}
{getMessage('modal.placement.initial.setting.size.actual')}{getMessage('modal.placement.initial.setting.size.actual.info')}
{getMessage('modal.placement.initial.setting.size.none.pitch')}{getMessage('modal.placement.initial.setting.size.none.pitch.info')}
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx new file mode 100644 index 00000000..d6d08675 --- /dev/null +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx @@ -0,0 +1,106 @@ +import Image from 'next/image' +import { useMessage } from '@/hooks/useMessage' +import { forwardRef, useState } from 'react' + +const PlacementSurface = forwardRef((props, refs) => { + const { getMessage } = useMessage() + const { id, lines, info, rotate, xInversion, yInversion } = props + let { length1, length2, length3, length4, length5, lengthetc, azimuth } = refs + + const [azimuthDirection, setAzimuthDirection] = useState(azimuth.current) + + const num = ['①', '②', '③', '④', '⑤'] + const getImageUrl = () => { + if (xInversion && !yInversion) { + return `/static/images/canvas/shape/re_${(rotate - 2) % 4 !== 0 ? Math.abs((rotate - 2) % 4) * 90 + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` + } + + if (!xInversion && yInversion) { + return `/static/images/canvas/shape/re_${rotate % 4 !== 0 ? Math.abs(rotate % 4) * 90 + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` + } + + if (xInversion && yInversion) { + return `/static/images/canvas/shape/${(rotate + 2) % 4 !== 0 ? Math.abs((rotate + 2) % 4) * 90 + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` + } + + if (rotate < 0) { + return `/static/images/canvas/shape/${rotate !== 0 ? Math.abs((rotate + 4) * 90) + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` + } + + return `/static/images/canvas/shape/${rotate !== 0 ? Math.abs(rotate * 90) + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` + } + + const azimuthButton = (direction, e) => { + setAzimuthDirection(direction) + azimuth.current = direction + } + + return ( + <> +
+
+

{getMessage('setting')}

+
+
+ react +
+
+
+ {lines?.map((line, index) => ( +
+
+ {line.isDiagonal ? getMessage('modal.placement.surface.setting.diagonal.length') : num[index]} +
+
+
+
+ +
+ mm +
+
+
+ ))} +
+
+
+
+
+

{getMessage('setting')}

+
+
+ {getMessage('commons.north')} + {getMessage('commons.east')} + {getMessage('commons.south')} + {getMessage('commons.west')} + + + + +
+
+
+
+ {info &&
{info}
} + + ) +}) + +export default PlacementSurface diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx new file mode 100644 index 00000000..e667667e --- /dev/null +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -0,0 +1,285 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useEffect, useState, useRef } from 'react' +import Image from 'next/image' +import PlacementSurface from '@/components/floor-plan/modal/placementSurface/PlacementSurface' +import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' +import { useRecoilValue } from 'recoil' +import { canvasState } from '@/store/canvasAtom' +import { POLYGON_TYPE } from '@/common/common' + +export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSettingModal }) { + const { getMessage } = useMessage() + const [selectedType, setSelectedType] = useState() + const [rotate, setRotate] = useState(0) + const [xInversion, setXInversion] = useState(false) + const [yInversion, setYInversion] = useState(false) + const canvas = useRecoilValue(canvasState) + + const { applySurfaceShape } = useSurfaceShapeBatch() + + const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + + //오브젝트 배치에서 넘어오면 면형상 선택 가능 + useEffect(() => { + surfaceShapePolygons.forEach((obj) => { + obj.set({ selectable: true }) + }) + }, []) + + const surfaceRefs = { + length1: useRef(null), + length2: useRef(null), + length3: useRef(null), + length4: useRef(null), + length5: useRef(null), + lengthetc: useRef(null), + azimuth: useRef('down'), + } + + /* type + * a: line 2 + * b: line 2 + diagonal 1 + * c: line 3 + * d: line 4 + * e: line 5 + * */ + const types = [ + { + id: 1, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { + isDiagonal: true, + value: 0, + }, + ], + info: getMessage('modal.placement.surface.setting.info'), + }, + { + id: 2, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 3, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 4, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 5, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 6, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + lineAmount: 3, + }, + { + id: 7, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 8, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 9, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 10, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 11, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 12, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 13, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 14, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 15, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 16, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 17, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + { + id: 18, + lines: [ + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + ], + }, + ] + const placementSurfaceProps = { + ...selectedType, + rotate, + xInversion, + yInversion, + } + + const getInversionState = () => { + return `${getScale()} ${getRotate()}` + } + + const getScale = () => { + return `scale(${yInversion ? -1 : 1}, ${xInversion ? -1 : 1})` + } + + const getRotate = () => { + return `rotate(${90 * rotate}deg)` + } + + const applySurfaces = () => { + surfaceRefs.xInversion = xInversion //좌우반전 + surfaceRefs.yInversion = yInversion //상하반전 + surfaceRefs.rotate = rotate * 90 //앵글 + applySurfaceShape(surfaceRefs, selectedType, setShowPlacementSurfaceSettingModal) + } + + useEffect(() => { + setSelectedType(types[0]) + }, []) + + return ( + +
+
+

{getMessage('plan.menu.placement.surface.arrangement')}

+ +
+
+
+ {types.map((type) => ( + + ))} +
+
+ + + +
+ +
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx new file mode 100644 index 00000000..72599bbe --- /dev/null +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -0,0 +1,160 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import QSelectBox from '@/components/common/select/QSelectBox' +import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSetting' + +export default function RoofAllocationSetting({ setShowRoofAllocationSettingModal }) { + const { getMessage } = useMessage() + const { handleSave, onAddRoofMaterial, onDeleteRoofMaterial, values, roofMaterials, selectedRoofMaterial, setSelectedRoofMaterial } = + useRoofAllocationSetting(setShowRoofAllocationSettingModal) + + return ( + +
+
+

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

+ +
+
+
{getMessage('modal.roof.alloc.info')}
+
+ {getMessage('modal.roof.alloc.select.roof.material')} +
+ setSelectedRoofMaterial(e)} /> +
+ +
+
+ {values.map((value, index) => ( +
+
+ + +
+
+
+
+
+ +
+ {index === 0 && 基本屋根材} + {index !== 0 && } +
+
+
+ {value.type === 'A' ? ( + <> +
+ W +
+ +
+
+
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : value.type === 'B' ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : value.type === 'C' ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+ + ) : value.type === 'D' ? ( + <> +
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : ( + '' + )} +
+
+
+ + +
+
+
+
+ ))} +
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx new file mode 100644 index 00000000..ec1684a6 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx @@ -0,0 +1,69 @@ +import WithDraggable from '@/components/common/draggable/WithDraggable' +import Eaves from '@/components/floor-plan/modal/roofShape/passivity/Eaves' +import Gable from '@/components/floor-plan/modal/roofShape/passivity/Gable' +import Shed from '@/components/floor-plan/modal/roofShape/passivity/Shed' +import { useMessage } from '@/hooks/useMessage' +import { useRoofShapePassivitySetting } from '@/hooks/roofcover/useRoofShapePassivitySetting' + +export default function RoofShapePassivitySetting({ setShowRoofShapePassivitySettingModal }) { + const { handleSave, handleConfirm, handleRollback, buttons, type, setType, TYPES, offsetRef, pitchRef } = + useRoofShapePassivitySetting(setShowRoofShapePassivitySettingModal) + const { getMessage } = useMessage() + + const eavesProps = { + offsetRef, + pitchRef, + } + + const gableProps = { + offsetRef, + pitchRef, + } + + const shedProps = { + offsetRef, + } + + return ( + +
+
+

{getMessage('plan.menu.roof.cover.roof.shape.passivity.setting')}

+ +
+
+
+ {buttons.map((button) => ( + + ))} +
+
+
{getMessage('setting')}
+
+ {type === TYPES.EAVES && } + {type === TYPES.GABLE && } + {type === TYPES.SHED && } +
+
+ + +
+
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx new file mode 100644 index 00000000..60355848 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx @@ -0,0 +1,108 @@ +import WithDraggable from '@/components/common/draggable/WithDraggable' +import Ridge from '@/components/floor-plan/modal/roofShape/type/Ridge' +import Pattern from '@/components/floor-plan/modal/roofShape/type/Pattern' +import Side from '@/components/floor-plan/modal/roofShape/type/Side' +import Image from 'next/image' +import Direction from '@/components/floor-plan/modal/roofShape/type/Direction' +import { useRoofShapeSetting } from '@/hooks/roofcover/useRoofShapeSetting' +import { useMessage } from '@/hooks/useMessage' + +export default function RoofShapeSetting({ setShowRoofShapeSettingModal }) { + const { getMessage } = useMessage() + const { + shapeNum, + setShapeNum, + shapeMenu, + handleSave, + pitch, + setPitch, + eavesOffset, + setEavesOffset, + gableOffset, + setGableOffset, + sleeveOffset, + setSleeveOffset, + jerkinHeadWidth, + setJerkinHeadWidth, + jerkinHeadPitch, + setJerkinHeadPitch, + hipAndGableWidth, + setHipAndGableWidth, + shedWidth, + setShedWidth, + hasSleeve, + setHasSleeve, + buttonAct, + setButtonAct, + buttonMenu, + handleConfirm, + handleRollBack, + } = useRoofShapeSetting(setShowRoofShapeSettingModal) + + const ridgeProps = { pitch, setPitch, eavesOffset, setEavesOffset } + const patternProps = { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset } + const sideProps = { + pitch, + setPitch, + eavesOffset, + setEavesOffset, + gableOffset, + setGableOffset, + sleeveOffset, + setSleeveOffset, + jerkinHeadWidth, + setJerkinHeadWidth, + jerkinHeadPitch, + setJerkinHeadPitch, + hipAndGableWidth, + setHipAndGableWidth, + shedWidth, + setShedWidth, + hasSleeve, + setHasSleeve, + buttonAct, + setButtonAct, + buttonMenu, + handleConfirm, + handleRollBack, + } + + const directionProps = { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth } + + return ( + +
+
+

{getMessage('modal.roof.shape.setting')}

+ +
+
+
+ {shapeMenu.map((item) => ( + + ))} +
+
+
{getMessage('setting')}
+ {shapeNum === 1 && } + {(shapeNum === 2 || shapeNum === 3) && } + {shapeNum === 4 && } + {(shapeNum === 5 || shapeNum === 6 || shapeNum === 7 || shapeNum === 8) && } +
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx b/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx new file mode 100644 index 00000000..3a16b5c0 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx @@ -0,0 +1,27 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Eaves({ offsetRef, pitchRef }) { + const { getMessage } = useMessage() + return ( + <> +
+ + {getMessage('slope')} + +
+ +
+ +
+
+ + {getMessage('eaves.offset')} + +
+ +
+ mm +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/passivity/Gable.jsx b/src/components/floor-plan/modal/roofShape/passivity/Gable.jsx new file mode 100644 index 00000000..69b2cf9d --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/passivity/Gable.jsx @@ -0,0 +1,27 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Gable({ offsetRef, pitchRef }) { + const { getMessage } = useMessage() + return ( + <> +
+ + {getMessage('slope')} + +
+ +
+ +
+
+ + {getMessage('gable.offset')} + +
+ +
+ mm +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/passivity/Shed.js b/src/components/floor-plan/modal/roofShape/passivity/Shed.js new file mode 100644 index 00000000..474c2f60 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/passivity/Shed.js @@ -0,0 +1,18 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Shed({ offsetRef }) { + const { getMessage } = useMessage() + return ( + <> +
+ + {getMessage('shed.width')} + +
+ +
+ mm +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/Direction.jsx b/src/components/floor-plan/modal/roofShape/type/Direction.jsx new file mode 100644 index 00000000..51faffcb --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/Direction.jsx @@ -0,0 +1,46 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' + +export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth }) { + const { getMessage } = useMessage() + return ( +
+
+ + {getMessage('slope')} + +
+ onlyNumberWithDotInputChange(e, setPitch)} /> +
+ {getMessage('size')} +
+
+ + {getMessage('eaves.offset')} + +
+ onlyNumberInputChange(e, setEavesOffset)} /> +
+ mm +
+
+ + {getMessage('gable.offset')} + +
+ onlyNumberInputChange(e, setGableOffset)} /> +
+ mm +
+
+ + {getMessage('windage.width')} + +
+ onlyNumberInputChange(e, setShedWidth)} /> +
+ mm +
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/Pattern.jsx b/src/components/floor-plan/modal/roofShape/type/Pattern.jsx new file mode 100644 index 00000000..0c086fbe --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/Pattern.jsx @@ -0,0 +1,38 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' + +export default function Pattern(props) { + const { getMessage } = useMessage() + const { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset } = props + return ( +
+
+ + {getMessage('slope')} + +
+ onlyNumberWithDotInputChange(e, setPitch)} /> +
+ {getMessage('size')} +
+
+ + {getMessage('eaves.offset')} + +
+ onlyNumberInputChange(e, setEavesOffset)} /> +
+ mm +
+
+ + {getMessage('gable.offset')} + +
+ +
+ mm +
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/Ridge.jsx b/src/components/floor-plan/modal/roofShape/type/Ridge.jsx new file mode 100644 index 00000000..13dab6f3 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/Ridge.jsx @@ -0,0 +1,31 @@ +import { useMessage } from '@/hooks/useMessage' +import { useEffect } from 'react' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' + +export default function Ridge(props) { + const { getMessage } = useMessage() + const { pitch, setPitch, eavesOffset, setEavesOffset } = props + + return ( +
+
+ + {getMessage('slope')} + +
+ onlyNumberWithDotInputChange(e, setPitch)} /> +
+ {getMessage('size')} +
+
+ + {getMessage('eaves.offset')} + +
+ onlyNumberInputChange(e, setEavesOffset)} /> +
+ mm +
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/Side.jsx b/src/components/floor-plan/modal/roofShape/type/Side.jsx new file mode 100644 index 00000000..b2f032ba --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/Side.jsx @@ -0,0 +1,75 @@ +import { useState } from 'react' +import { useMessage } from '@/hooks/useMessage' +import Eaves from '@/components/floor-plan/modal/roofShape/type/option/Eaves' +import Gable from '@/components/floor-plan/modal/roofShape/type/option/Gable' +import HipAndGable from '@/components/floor-plan/modal/roofShape/type/option/HipAndGable' +import Wall from '@/components/floor-plan/modal/roofShape/type/option/Wall' +import Jerkinhead from '@/components/floor-plan/modal/roofShape/type/option/Jerkinhead' +import Shed from '@/components/floor-plan/modal/roofShape/type/option/Shed' + +export default function Side(props) { + const { + pitch, + setPitch, + eavesOffset, + setEavesOffset, + gableOffset, + setGableOffset, + sleeveOffset, + setSleeveOffset, + jerkinHeadWidth, + setJerkinHeadWidth, + jerkinHeadPitch, + setJerkinHeadPitch, + hipAndGableWidth, + setHipAndGableWidth, + shedWidth, + setShedWidth, + hasSleeve, + setHasSleeve, + buttonAct, + setButtonAct, + buttonMenu, + handleConfirm, + handleRollBack, + } = props + + const eavesProps = { pitch, setPitch, eavesOffset, setEavesOffset } + const gableProps = { gableOffset, setGableOffset } + const wallProps = { sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve } + const hipAndGableProps = { pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth } + const jerkinheadProps = { gableOffset, setGableOffset, jerkinHeadWidth, setJerkinHeadWidth, jerkinHeadPitch, setJerkinHeadPitch } + const shedProps = { shedWidth, setShedWidth } + + const { getMessage } = useMessage() + + return ( +
+
+
+ {buttonMenu.map((item, idx) => ( + + ))} +
+
+
+ {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } + {buttonAct === 5 && } + {buttonAct === 6 && } +
+
+ + +
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/option/Eaves.jsx b/src/components/floor-plan/modal/roofShape/type/option/Eaves.jsx new file mode 100644 index 00000000..8d061a7b --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/option/Eaves.jsx @@ -0,0 +1,28 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' + +export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset }) { + const { getMessage } = useMessage() + return ( + <> +
+ + {getMessage('slope')} + +
+ onlyNumberWithDotInputChange(e, setPitch)} /> +
+ {getMessage('size')} +
+
+ + {getMessage('eaves.offset')} + +
+ onlyNumberInputChange(e, setEavesOffset)} /> +
+ mm +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/option/Gable.jsx b/src/components/floor-plan/modal/roofShape/type/option/Gable.jsx new file mode 100644 index 00000000..08e503d2 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/option/Gable.jsx @@ -0,0 +1,19 @@ +import { useMessage } from '@/hooks/useMessage' +import { useEffect } from 'react' +import { onlyNumberInputChange } from '@/util/input-utils' + +export default function Gable({ gableOffset, setGableOffset }) { + const { getMessage } = useMessage() + + return ( + <> +
+ {getMessage('gable.offset')} +
+ onlyNumberInputChange(e, setGableOffset)} /> +
+ mm +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/option/HipAndGable.jsx b/src/components/floor-plan/modal/roofShape/type/option/HipAndGable.jsx new file mode 100644 index 00000000..ce4a57cc --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/option/HipAndGable.jsx @@ -0,0 +1,42 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' + +export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth }) { + const { getMessage } = useMessage() + return ( + <> +
+ + {getMessage('slope')} + +
+ onlyNumberWithDotInputChange(e, setPitch)} /> +
+ {getMessage('size')} +
+
+ + {getMessage('eaves.offset')} + +
+ onlyNumberInputChange(e, setEavesOffset)} /> +
+ mm +
+
+ + {getMessage('hipandgable.width')} + +
+ onlyNumberInputChange(e, setHipAndGableWidth)} + /> +
+ mm +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/option/Jerkinhead.jsx b/src/components/floor-plan/modal/roofShape/type/option/Jerkinhead.jsx new file mode 100644 index 00000000..be846e94 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/option/Jerkinhead.jsx @@ -0,0 +1,42 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' + +export default function Jerkinhead({ gableOffset, setGableOffset, jerkinHeadWidth, setJerkinHeadWidth, jerkinHeadPitch, setJerkinHeadPitch }) { + const { getMessage } = useMessage() + return ( + <> +
+ + {getMessage('gable.offset')} + +
+ onlyNumberInputChange(e, setGableOffset)} /> +
+ mm +
+
+ + {getMessage('jerkinhead.width')} + +
+ onlyNumberInputChange(e, setJerkinHeadWidth)} /> +
+ mm +
+
+ + {getMessage('jerkinhead.slope')} + +
+ onlyNumberWithDotInputChange(e, setJerkinHeadPitch)} + /> +
+ {getMessage('size')} +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/option/Shed.jsx b/src/components/floor-plan/modal/roofShape/type/option/Shed.jsx new file mode 100644 index 00000000..40ccdbef --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/option/Shed.jsx @@ -0,0 +1,17 @@ +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange } from '@/util/input-utils' + +export default function Shed({ shedWidth, setShedWidth }) { + const { getMessage } = useMessage() + return ( + <> +
+ {getMessage('shed.width')} +
+ onlyNumberInputChange(e, setShedWidth)} /> +
+ mm +
+ + ) +} diff --git a/src/components/floor-plan/modal/roofShape/type/option/Wall.jsx b/src/components/floor-plan/modal/roofShape/type/option/Wall.jsx new file mode 100644 index 00000000..c7b04b2d --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/type/option/Wall.jsx @@ -0,0 +1,44 @@ +import { useState } from 'react' +import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange } from '@/util/input-utils' + +export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) { + const { getMessage } = useMessage() + return ( + <> + {hasSleeve} +
+
+
+
+ setHasSleeve(e.target.value)} /> + +
+
+
+
+
+
+ setHasSleeve(e.target.value)} /> + +
+
+
+
+
+ onlyNumberInputChange(e, setSleeveOffset)} + readOnly={hasSleeve === '0'} + /> +
+ mm +
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index ac8f08d6..c4e75ea4 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -116,11 +116,21 @@ export default function FirstOption() { } } - const onClickDimension = async (item) => { - const options = settingModalFirstOptions?.dimensionDisplay.map((option) => { - option.selected = option.id === item.id - return option - }) + const onClickOnlyOne = async (item) => { + //화면 표시 + if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') { + const options2 = settingModalFirstOptions?.option2.map((option2) => { + option2.selected = option2.id === item.id + return option2 + }) + + //치수 표시 + } else { + const options = settingModalFirstOptions?.dimensionDisplay.map((option) => { + option.selected = option.id === item.id + return option + }) + } setSettingModalFirstOptions({ option1, option2, dimensionDisplay }) @@ -205,7 +215,7 @@ export default function FirstOption() {
{settingModalFirstOptions && settingModalFirstOptions.dimensionDisplay.map((item) => ( - @@ -217,7 +227,7 @@ export default function FirstOption() {
{settingModalFirstOptions && settingModalFirstOptions.option2.map((item) => ( - diff --git a/src/components/floor-plan/modal/setting01/GridOption.jsx b/src/components/floor-plan/modal/setting01/GridOption.jsx index edf1e802..39af3a10 100644 --- a/src/components/floor-plan/modal/setting01/GridOption.jsx +++ b/src/components/floor-plan/modal/setting01/GridOption.jsx @@ -8,7 +8,7 @@ import { gridColorState } from '@/store/gridAtom' import { useColor } from 'react-color-palette' export default function GridOption(props) { - const { setShowDotLineGridModal } = props + const { setShowDotLineGridModal, setShowColorPickerModal } = props const [gridOptions, setGridOptions] = useRecoilState(settingModalGridOptionsState) const [gridColor, setGridColor] = useRecoilState(gridColorState) const [adsorptionPointAddMode, setAdsorptionPointAddMode] = useRecoilState(adsorptionPointAddModeState) @@ -18,7 +18,7 @@ export default function GridOption(props) { const [color, setColor] = useColor(gridColor) useEffect(() => { - console.log(color) + console.log('GridOption useEffect 실행') setGridColor(color.hex) }, [color]) @@ -55,7 +55,9 @@ export default function GridOption(props) { if (option.id === 4) { // 그리드 색 설정 if (option.selected) { - setColorPickerShow(true) + setShowColorPickerModal(true) + } else { + setShowColorPickerModal(false) } } diff --git a/src/components/floor-plan/modal/setting01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx index 293d29df..78511548 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -2,18 +2,25 @@ import { useState } from 'react' import FirstOption from './FirstOption' -import WithDraggable from '@/components/common/draggable/withDraggable' +import WithDraggable from '@/components/common/draggable/WithDraggable' import SecondOption from '@/components/floor-plan/modal/setting01/SecondOption' import { useMessage } from '@/hooks/useMessage' import GridOption from '@/components/floor-plan/modal/setting01/GridOption' +import { canGridOptionSeletor } from '@/store/canvasAtom' +import { useRecoilValue } from 'recoil' export default function SettingModal01(props) { - const { setShowCanvasSettingModal, setShowDotLineGridModal } = props + const { setShowCanvasSettingModal, setShowDotLineGridModal, setShowColorPickerModal } = props const [buttonAct, setButtonAct] = useState(1) const { getMessage } = useMessage() + const canGridOptionSeletorValue = useRecoilValue(canGridOptionSeletor) + + const handleBtnClick = (num) => { + setButtonAct(num) + } return ( - +

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

@@ -23,20 +30,22 @@ export default function SettingModal01(props) {
- - - + {canGridOptionSeletorValue && ( + + )}
{buttonAct === 1 && } {buttonAct === 2 && } - {buttonAct === 3 && } + {buttonAct === 3 && }
diff --git a/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx b/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx new file mode 100644 index 00000000..7e5230b1 --- /dev/null +++ b/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx @@ -0,0 +1,71 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import WallLine from '@/components/floor-plan/modal/wallLineOffset/type/WallLine' +import Offset from '@/components/floor-plan/modal/wallLineOffset/type/Offset' +import { useWallLineOffsetSetting } from '@/hooks/roofcover/useWallLineOffsetSetting' + +export default function WallLineOffsetSetting({ setShowWallLineOffsetSettingModal }) { + const { getMessage } = useMessage() + const { + type, + setType, + buttonMenu, + currentWallLineRef, + TYPES, + radioTypeRef, + arrow1Ref, + arrow2Ref, + length1Ref, + length2Ref, + handleSave, + wallLineEditRef, + } = useWallLineOffsetSetting(setShowWallLineOffsetSettingModal) + + const wallLineProps = { + length1Ref, + length2Ref, + arrow1Ref, + arrow2Ref, + radioTypeRef, + currentWallLineRef, + } + + const offsetProps = { + length1Ref, + arrow1Ref, + currentWallLineRef, + } + + return ( + +
+
+

{getMessage('modal.wallline.offset.setting')}

+ +
+
+
+ {buttonMenu.map((item) => ( + + ))} +
+
+
{getMessage('setting')}
+ {type === TYPES.WALL_LINE_EDIT && } + {type === TYPES.OFFSET && } +
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/wallLineOffset/type/Offset.jsx b/src/components/floor-plan/modal/wallLineOffset/type/Offset.jsx new file mode 100644 index 00000000..11fcd84f --- /dev/null +++ b/src/components/floor-plan/modal/wallLineOffset/type/Offset.jsx @@ -0,0 +1,100 @@ +import { useMessage } from '@/hooks/useMessage' +import { useEffect, useState } from 'react' +import { useEvent } from '@/hooks/useEvent' + +export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) { + const { getMessage } = useMessage() + const { addDocumentEventListener, initEvent } = useEvent() + + useEffect(() => { + addDocumentEventListener('keydown', document, keyDown) + + return () => { + initEvent() + } + }, []) + + const handleBtnClick = (direction) => { + document.dispatchEvent(new KeyboardEvent('keydown', { key: direction })) + } + + const [arrow, setArrow] = useState(null) + + const keyDown = (e) => { + if (currentWallLineRef.current === null) { + alert('보조선을 먼저 선택하세요') + return + } + + const direction = currentWallLineRef.current.direction + + const key = e.key + + switch (key) { + case 'Down': // IE/Edge에서 사용되는 값 + case 'ArrowDown': { + if (direction === 'left' || direction === 'right') { + setArrow('down') + arrow1Ref.current = 'down' + } + break + } + case 'Up': // IE/Edge에서 사용되는 값 + case 'ArrowUp': + if (direction === 'left' || direction === 'right') { + setArrow('up') + arrow1Ref.current = 'up' + } + break + case 'Left': // IE/Edge에서 사용되는 값 + case 'ArrowLeft': + if (direction === 'bottom' || direction === 'top') { + setArrow('left') + arrow1Ref.current = 'left' + } + break + case 'Right': // IE/Edge에서 사용되는 값 + case 'ArrowRight': + if (direction === 'bottom' || direction === 'top') { + setArrow('right') + arrow1Ref.current = 'right' + } + break + } + } + return ( + <> +
+
{getMessage('modal.wallline.offset.setting.offset.info')}
+
+
+
+
{getMessage('length')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.cover.outline.arrow')}
+
+
+
+ + + + +
+
+
+
+
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx b/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx new file mode 100644 index 00000000..15ccefa3 --- /dev/null +++ b/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx @@ -0,0 +1,107 @@ +import { useMessage } from '@/hooks/useMessage' +import { forwardRef, useEffect, useImperativeHandle, useState } from 'react' +import { useEvent } from '@/hooks/useEvent' + +export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref, arrow2Ref, radioTypeRef, currentWallLineRef }, ref) { + const { getMessage } = useMessage() + const { addDocumentEventListener, initEvent } = useEvent() + const [type, setType] = useState(1) + const [arrow1, setArrow1] = useState('up') + const [arrow2, setArrow2] = useState('up') + + useEffect(() => { + return () => { + initEvent() + } + }, []) + + useImperativeHandle(ref, () => ({ + setArrow, + })) + + const setArrow = () => { + setArrow1(arrow1Ref.current) + setArrow2(arrow2Ref.current) + } + + const onChange = (e) => { + setType(Number(e.target.value)) + radioTypeRef.current = e.target.value + } + + return ( + <> +
+
{getMessage('modal.wallline.offset.setting.wallline.edit.info')}
+
+
+ onChange(e)} /> + +
+
+
+
+
{getMessage('length')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.cover.outline.arrow')}
+
+
+
+ + + + +
+
+
+
+
+
+
+
+
+ onChange(e)} /> + +
+
+
+
+
{getMessage('length')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.cover.outline.arrow')}
+
+
+
+ + + + +
+
+
+
+
+
+
+
+ + ) +}) diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 04fd56c6..c12d237e 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -12,6 +12,10 @@ import { logout } from '@/lib/authActions' import QSelectBox from '@/components/common/select/QSelectBox' +import UserInfoModal from '@/components/myInfo/UserInfoModal' +import { useAxios } from '@/hooks/useAxios' +import { globalLocaleStore } from '@/store/localeAtom' + export const ToggleonMouse = (e, act, target) => { const listWrap = e.target.closest(target) const ListItem = Array.from(listWrap.childNodes) @@ -28,6 +32,8 @@ export const ToggleonMouse = (e, act, target) => { } export default function Header(props) { + const [userInfoModal, setUserInfoModal] = useState(false) + const { userSession } = props const [sessionState, setSessionState] = useRecoilState(sessionStore) const { getMessage } = useMessage() @@ -40,12 +46,42 @@ export default function Header(props) { const dimmedState = useRecoilValue(dimmedStore) const isDimmed = dimmedState ? 'opacity-50 bg-black' : '' - 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' }, - ] + // Link 이동 자동 로그인 + const [globalLocaleState, setGlbalLocaleState] = useRecoilState(globalLocaleStore) + const { promisePost } = useAxios(globalLocaleState) + + const qOrderUrl = process.env.NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL + const qMusubiUrl = process.env.NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL + + const [SelectOptions, setSelectOptions] = useState( + userSession.groupId === '60000' ? [{ id: 0, name: 'Q.ORDER', link: `${qOrderUrl}` }] : [{ id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}` }], + ) + + const getAutoLoginParam = async () => { + await promisePost({ url: '/api/login/v1.0/user/login/autoLoginEncryptData', data: { loginId: userSession.userId } }) + .then((res) => { + if (res) { + setSelectOptions( + userSession.groupId === '60000' + ? [{ id: 0, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` }] + : [{ id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` }], + ) + setSelected( + userSession.groupId === '60000' + ? { id: 0, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` } + : { id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` }, + ) + } + }) + .catch((error) => { + alert(error.response.data.message) + }) + } + + useEffect(() => { + getAutoLoginParam() + }, [userSession]) + const menus = [ { id: 0, name: 'header.menus.home', url: '/', children: [] }, { @@ -124,7 +160,7 @@ export default function Header(props) { } return ( - !(pathName.includes('login') || pathName.includes('join')) && ( + !(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && (
@@ -137,9 +173,15 @@ export default function Header(props) {
- + { + setUserInfoModal(true) + }} + > + {userInfoModal && }
- +
+ +
+
+
+
+
+ ) +} diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx new file mode 100644 index 00000000..ba9a8d77 --- /dev/null +++ b/src/components/main/MainContents.jsx @@ -0,0 +1,174 @@ +import React, { useEffect, useState } from 'react' +import ProductItem from './ProductItem' +import { useMessage } from '@/hooks/useMessage' +import Image from 'next/image' +import dayjs from 'dayjs' +import { useAxios } from '@/hooks/useAxios' +import { useRecoilValue } from 'recoil' +import { useRouter } from 'next/navigation' +import { globalLocaleStore } from '@/store/localeAtom' +import { queryStringFormatter } from '@/util/common-utils' +export default function MainContents({ objectList, businessCharger, businessChargerMail, businessChargerTel }) { + const { getMessage } = useMessage() + const router = useRouter() + const globalLocaleState = useRecoilValue(globalLocaleStore) + const { get } = useAxios(globalLocaleState) + + //공지사항 + const [recentNoticeList, setRecentNoticeList] = useState([]) + + //FAQ + const [recentFaqList, setRecentFaqList] = useState([]) + + useEffect(() => { + fetchNoticeList() + fetchFaqList() + }, []) + + //공지사항 호출 + const fetchNoticeList = async () => { + try { + const param = { + schNoticeTpCd: 'QC', + schNoticeClsCd: 'NOTICE', + startRow: 1, + endRow: 1, + } + // const noticeApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=NOTICE&schTitle=&startRow=1&endRow=1` + const noticeApiUrl = `api/board/list?${queryStringFormatter(param)}` + const res = await get({ url: noticeApiUrl }) + //console.log('공지res::', res) + if (res) { + if (res.data.length > 0) { + setRecentNoticeList(res.data) + } + } + } catch (error) { + console.error('NOTICE fetching error:', error) + } + } + + //FAQ 호출 + const fetchFaqList = async () => { + try { + const param = { + schNoticeTpCd: 'QC', + schNoticeClsCd: 'FAQ', + startRow: 1, + endRow: 3, + } + // const faqApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=FAQ&schTitle=&startRow=1&endRow=1` + const faqApiUrl = `api/board/list?${queryStringFormatter(param)}` + const res = await get({ url: faqApiUrl }) + //console.log('FAQres::', res) + if (res) { + if (res.data.length > 0) { + setRecentFaqList(res.data) + } + } + } catch (error) { + console.error('FAQ fetching error:', error) + } + } + + return ( +
+
+ +
    + {objectList?.length > 0 ? ( + <> + {objectList.map((row) => { + return ( +
  • { + if (row.objectNo.substring(0, 1) === 'R') { + router.push(`/management/stuff/detail?objectNo=${row.objectNo.toString()}`) + } else { + router.push(`/management/stuff/tempdetail?objectNo=${row.objectNo.toString()}`) + } + }} + > +
    + {dayjs(row.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')} + {row.objectNo} + {row.objectName} + {row.saleStoreName} +
    +
  • + ) + })} + + ) : ( + <> +
  • +
    최근 갱신 물건이 없습니다
    +
  • + + )} +
+
+ +
+ {recentNoticeList.length > 0 ? ( + <> +
{dayjs(recentNoticeList[0]?.regDt).format('YYYY.MM.DD')}
+
{recentNoticeList[0]?.title}
+
{recentNoticeList[0]?.contents}
+ + ) : null} +
+
+
+
+ +
    + {recentFaqList.length > 0 ? ( + <> + {recentFaqList.map((row) => { + return ( +
  • +
    +
    FAQ {row.noticeNo}
    +
    {row.title}
    +
    {dayjs(row.regDt).format('YYYY.MM.DD')}
    +
    +
  • + ) + })} + + ) : null} +
+
+ +
+ + +
+
+ +
    +
  • +
    + react +
    +
    {businessCharger}
    +
  • +
  • +
    + react +
    +
    {businessChargerMail}
    +
  • +
+
+
+
+ ) +} diff --git a/src/components/main/ProductItem.jsx b/src/components/main/ProductItem.jsx new file mode 100644 index 00000000..928bc269 --- /dev/null +++ b/src/components/main/ProductItem.jsx @@ -0,0 +1,35 @@ +import React from 'react' +import { useRouter } from 'next/navigation' +export default function ProductItem({ num, name, children }) { + const router = useRouter() + + // 더보기 페이지 이동 + const pageMove = (num) => { + if (num === 1) { + router.push('/management/stuff') + } else if (num === 2) { + router.push('/community/notice') + } else { + router.push('/community/faq') + } + } + return ( +
+
+

+ + {name} +

+ {num !== 4 && num !== 5 && ( + + )} +
+
{children}
+
+ ) +} diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 638126ee..cedf1975 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -10,22 +10,30 @@ import { useRecoilValue, useRecoilState } from 'recoil' import { stuffSearchState } from '@/store/stuffAtom' import { queryStringFormatter, isEmptyArray } from '@/util/common-utils' import dayjs from 'dayjs' -import isLeapYear from 'dayjs/plugin/isLeapYear' // 윤년 판단 플러그인 -dayjs.extend(isLeapYear) -import { globalLocaleStore } from '@/store/localeAtom' +import { isObjectNotEmpty } from '@/util/common-utils' +import { convertNumberToPriceDecimal } from '@/util/common-utils' +import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' +import KO from '@/locales/ko.json' +import JA from '@/locales/ja.json' +import QPagination from '../common/pagination/QPagination' +import '@/styles/grid.scss' +import { sessionStore } from '@/store/commonAtom' + export default function Stuff() { + const sessionState = useRecoilValue(sessionStore) + const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore) const stuffSearchParams = useRecoilValue(stuffSearchState) const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) const { getMessage } = useMessage() - const [curPage, setCurPage] = useState(1) //현재 페이지 번호 - const [defaultSize, setDefaultSize] = useState(100) //페이지 당 게시물 수 + const [pageNo, setPageNo] = useState(1) //현재 페이지 번호 + const [pageSize, setPageSize] = useState(100) //페이지 당 게시물 수 + const [totalCount, setTotalCount] = useState(0) //총 갯수 const [defaultSortType, setDefaultSortType] = useState('R') const globalLocaleState = useRecoilValue(globalLocaleStore) const { get } = useAxios(globalLocaleState) const gridRef = useRef() - const [gridCount, setGridCount] = useState(0) const [selectedRowData, setSelectedRowData] = useState([]) const [selectedRowDataCount, setSelectedRowDataCount] = useState(0) @@ -45,12 +53,9 @@ 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()}`) } } @@ -58,10 +63,6 @@ export default function Stuff() { const [gridProps, setGridProps] = useState({ gridData: [], isPageable: false, - // sets 10 rows per page (default is 100) - // paginationPageSize: 100, - // allows the user to select the page size from a predefined list of page sizes - // paginationPageSizeSelector: [100, 200, 300, 400], gridColumns: [ { field: 'lastEditDatetime', @@ -70,17 +71,7 @@ export default function Stuff() { headerCheckboxSelectionCurrentPageOnly: true, //페이징시 현재 페이지만 체크되도록 checkboxSelection: true, showDisabledCheckboxes: true, - // headerClass: 'centered', //_test.scss에 추가 테스트 - // .centered { - // .ag-header-cell-label { - // justify-content: center !important; - // } - // } cellStyle: { textAlign: 'center' }, - //suppressMovable: true, //헤더 못움직이게 - // width : 100 - // minWidth : 100 - // maxWidth : 100 valueFormatter: function (params) { if (params.value) { return dayjs(params?.value).format('YYYY.MM.DD HH:mm:ss') @@ -91,8 +82,8 @@ export default function Stuff() { }, { field: 'objectNo', + minWidth: 230, headerName: getMessage('stuff.gridHeader.objectNo'), - // headerClass: 'centered', //_test.scss에 추가 테스트 cellRenderer: function (params) { if (params.data.objectNo) { return ( @@ -126,7 +117,7 @@ export default function Stuff() { headerName: getMessage('stuff.gridHeader.saleStoreId'), cellStyle: { textAlign: 'left' }, }, - { field: 'saleStoreName', headerName: getMessage('stuff.gridHeader.saleStoreName'), cellStyle: { textAlign: 'left' } }, + { field: 'saleStoreName', minWidth: 300, headerName: getMessage('stuff.gridHeader.saleStoreName'), cellStyle: { textAlign: 'left' } }, { field: 'address', headerName: getMessage('stuff.gridHeader.address'), cellStyle: { textAlign: 'left' } }, { field: 'dispCompanyName', headerName: getMessage('stuff.gridHeader.dispCompanyName'), cellStyle: { textAlign: 'left' } }, { field: 'receiveUser', headerName: getMessage('stuff.gridHeader.receiveUser'), cellStyle: { textAlign: 'left' } }, @@ -163,14 +154,11 @@ export default function Stuff() { if (event.column.colId === 'objectNo') { return } else { - console.log(' 상세이동::::::::', event.data) //T 면 임시 R은 진짜 if (event.data.objectNo) { 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()}`) } } @@ -236,75 +224,95 @@ export default function Stuff() { // 진입시 그리드 데이터 조회 useEffect(() => { - if (stuffSearchParams?.code === 'S') { - const params = { - schObjectNo: '', - schSaleStoreId: '', - schAddress: '', - schObjectName: '', - schSaleStoreName: '', - schSpecDateYn: '', - schReceiveUser: '', - schDispCompanyName: '', - schDateType: 'U', - schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), - schToDt: dayjs(new Date()).format('YYYY-MM-DD'), - startRow: (curPage - 1) * defaultSize + 1, - endRow: curPage * defaultSize, - schSelSaleStoreId: '', - schSortType: 'R', + if (isObjectNotEmpty(sessionState)) { + //물건 메뉴 눌러서 최초 진입 sessionState + if (stuffSearchParams?.code === 'S') { + const params = { + schObjectNo: stuffSearchParams?.schObjectNo, + schAddress: stuffSearchParams?.schAddress, + schObjectName: stuffSearchParams?.schObjectName, + schSaleStoreName: stuffSearchParams?.schSaleStoreName, + schReceiveUser: stuffSearchParams?.schReceiveUser, + schDispCompanyName: stuffSearchParams?.schDispCompanyName, + schDateType: stuffSearchParams.schDateType, + schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), + schToDt: dayjs(new Date()).format('YYYY-MM-DD'), + startRow: (pageNo - 1) * pageSize + 1, + endRow: pageNo * pageSize, + schSelSaleStoreId: '', + schSortType: stuffSearchParams.schSortType, + } + + async function fetchData() { + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}` + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(params)}` + + await get({ + url: apiUrl, + }).then((res) => { + if (!isEmptyArray(res)) { + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setTotalCount(res[0].totCnt) + } + }) + } + fetchData() + } else { + //메인화면에서 진입 + const params = { + schObjectNo: stuffSearchParams.schObjectNo, + schAddress: '', + schObjectName: '', + schSaleStoreName: '', + schReceiveUser: '', + schDispCompanyName: '', + schDateType: 'U', + schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), + schToDt: dayjs(new Date()).format('YYYY-MM-DD'), + startRow: (pageNo - 1) * pageSize + 1, + endRow: pageNo * pageSize, + schSelSaleStoreId: '', + schSortType: 'R', + } + + async function fetchData() { + const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}` + + await get({ + url: apiUrl, + }).then((res) => { + if (!isEmptyArray(res)) { + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setTotalCount(res[0].totCnt) + } + }) + } + fetchData() } - - async function fetchData() { - console.log('화면진입:::::::::::::', params) - //api에 넘길값 startRow, endRow - // let startRow - // let endRow - // startRow = (curPage - 1) * size + 1 - // endRow = curPage * size - // console.log('startrow::', startRow) - // console.log('endRow::', endRow) - - // let curPage - // let totalpage - // let totalCount - // let size - // let pageCount - - // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` - const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}` - - await get({ - url: apiUrl, - }).then((res) => { - if (!isEmptyArray(res)) { - console.log('화면진입API결과::', res) - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) - } - }) - } - fetchData() } - }, []) + }, [pageNo, sessionState]) useEffect(() => { if (stuffSearchParams?.code === 'E') { - stuffSearchParams.startRow = (curPage - 1) * defaultSize + 1 - stuffSearchParams.endRow = curPage * defaultSize + //console.log('조회누름::::::::', stuffSearchParams, sessionState) + // stuffSearchParams.startRow = (pageNo - 1) * pageSize + 1 + // stuffSearchParams.endRow = pageNo * pageSize + stuffSearchParams.startRow = 1 + stuffSearchParams.endRow = 1 * pageSize stuffSearchParams.schSortType = defaultSortType - console.log('조회 눌럿을때 ::::::::::::::', stuffSearchParams) + + setPageNo(1) + async function fetchData() { - // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` await get({ url: apiUrl }).then((res) => { - console.log('API결과:::::::', res) if (!isEmptyArray(res)) { - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setTotalCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) - setGridCount(0) + setTotalCount(0) } }) } @@ -314,56 +322,84 @@ export default function Stuff() { //페이지 갯수 변경 이벤트 const onChangePerPage = (e) => { - let startRow = (curPage - 1) * e.target.value + 1 + let startRow = (1 - 1) * e.target.value + 1 stuffSearchParams.startRow = startRow - stuffSearchParams.endRow = curPage * e.target.value - setDefaultSize(e.target.value) + stuffSearchParams.endRow = 1 * e.target.value + setPageSize(e.target.value) setStuffSearch({ ...stuffSearch, code: 'S', startRow: startRow, - endRow: curPage * e.target.value, + endRow: 1 * e.target.value, }) - console.log('셋팅된 검색조건:::', stuffSearchParams) - //조회API호출 - // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` + + setPageNo(1) + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}` get({ url: apiUrl }).then((res) => { - console.log('보여줄개수바꿨을때 조회 ::::::::::', res) if (!isEmptyArray(res)) { - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setTotalCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) - setGridCount(0) + setTotalCount(0) } }) } //최근 등록일 수정일 정렬 이벤트 const onChangeSortType = (e) => { + let startRow = (1 - 1) * pageSize + 1 + stuffSearchParams.startRow = startRow + stuffSearchParams.endRow = 1 * pageSize + stuffSearchParams.schSortType = e.target.value - console.log('셋팅된 검색조건:::', stuffSearchParams) setDefaultSortType(e.target.value) setStuffSearch({ ...stuffSearch, code: 'S', + startRow: startRow, + endRow: 1 * pageSize, schSortType: e.target.value, }) - // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` - // console.log('apiUrl::', apiUrl) + + setPageNo(1) + + const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` get({ url: apiUrl }).then((res) => { - console.log('정렬바꿨을때 조회 ::::::::::', res) if (!isEmptyArray(res)) { - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setTotalCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) - setGridCount(0) + setTotalCount(0) } }) } + + useEffect(() => { + if (globalLocaleState === 'ko') { + setAppMessageState(KO) + } else { + setAppMessageState(JA) + } + }, [globalLocaleState]) + + // 페이징 현재페이지 변경 + const handleChangePage = (page) => { + stuffSearchParams.code = 'S' + + setStuffSearch({ + ...stuffSearch, + code: 'S', + startRow: (page - 1) * pageSize + 1, + endRow: page * pageSize, + }) + + setPageNo(page) + } + return ( <> {/* 퍼블시작 */} @@ -374,11 +410,11 @@ export default function Stuff() {
  • 전체 - {gridCount} + {convertNumberToPriceDecimal(totalCount)}
  • 선택 - {selectedRowDataCount} + {convertNumberToPriceDecimal(selectedRowDataCount)}
@@ -401,7 +437,9 @@ export default function Stuff() {
-
페이징 컴포넌트예정
+
+ +
diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 898b4176..7167fc63 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -1,23 +1,30 @@ 'use client' -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 React, { useState, useEffect, useRef } from 'react' +import { useRouter, useSearchParams, usePathname } from 'next/navigation' +import { Button } from '@nextui-org/react' +import Select from 'react-select' import Link from 'next/link' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' -import { queryStringFormatter, isEmptyArray } from '@/util/common-utils' -import dayjs from 'dayjs' +import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty } from '@/util/common-utils' import { useMessage } from '@/hooks/useMessage' import { useForm } from 'react-hook-form' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilValue } from 'recoil' +import { sessionStore } from '@/store/commonAtom' +import FindAddressPop from './popup/FindAddressPop' +import PlanRequestPop from './popup/PlanRequestPop' +import WindSelectPop from './popup/WindSelectPop' export default function StuffDetail() { + const sessionState = useRecoilValue(sessionStore) + const router = useRouter() + const pathname = usePathname() const searchParams = useSearchParams() const { getMessage } = useMessage() const globalLocaleState = useRecoilValue(globalLocaleStore) - - const { get, post, del } = useAxios(globalLocaleState) + const ref = useRef() + const { get, post, del, promisePost } = useAxios(globalLocaleState) //form const formInitValue = { // 물건번호 T...(임시) R...(진짜) @@ -26,22 +33,24 @@ export default function StuffDetail() { objectName: '', //물건명 objectNameOmit: '', //경칭선택 objectNameKana: '', //물건명 후리가나 - saleStoreId: '', //판매점ID - saleStoreName: '', //판매점명 - otherSaleStoreId: '', - otherSaleStoreName: '', + saleStoreLevel: '', //1차점스토어레벨 + saleStoreId: '', //1차점판매점ID + saleStoreName: '', //1차점판매점명 + otherSaleStoreId: '', //1차점 외 판매점ID + otherSaleStoreName: '', //1차점 외 판매점명 + otherSaleStoreLevel: '', //1차점 외 스토어레벨 zipNo: '', //우편번호 prefId: '', //도도부현 prefName: '', address: '', //주소 - powerSimArea: '', //발전량시뮬레이션지역 + areaId: '', //발전량시뮬레이션지역id windSpeed: '', //기준풍속 - snowCover: '', //수직적설량 - coldAreaChk: false, //한랭지대책시행 - surfaceType: 'Ⅲ・Ⅳ', //면조도구분(Ⅲ・Ⅳ / Ⅱ) - saltAreaChk: false, //염해지역용아이템사용 + verticalSnowCover: '', //수직적설량NEW + coldRegionFlg: false, //한랭지대책시행(true : 1 / false : 0) + surfaceType: 'III・IV', //면조도구분(III・IV / Ⅱ) + saltAreaFlg: false, //염해지역용아이템사용 (true : 1 / false : 0) installHeight: '', //설치높이 - powerConTerms: '0', //계약조건(잉여 / 전량) + conType: '0', //계약조건(잉여 / 전량) remarks: '', //메모 tempFlag: 'T', //임시저장(1) 저장(0) } @@ -55,19 +64,25 @@ export default function StuffDetail() { const [prefValue, setPrefValue] = useState('') const [saleStoreList, setSaleStoreList] = useState([]) // 판매점 리스트 const [otherSaleStoreList, setOtherSaleStoreList] = useState([]) + const [originOtherSaleStoreList, setOriginOtherSaleStoreList] = useState([]) - const [powerSimAreaList, setPowerSimAreaList] = useState([]) //발전시뮬레이션 리스트 + const [areaIdList, setAreaIdList] = useState([]) //발전시뮬레이션 리스트 + // const [windSpeedList, setWindSpeedList] = useState([]) //기준풍속 리스트 팝업으로이동 const [isFormValid, setIsFormValid] = useState(false) //임시저장, 진짜저장 버튼 컨트롤 - const [buttonValid, setButtonValid] = useState(false) //주소검색 활성화 컨트롤 + const [showAddressButtonValid, setShowAddressButtonValid] = useState(false) //주소검색팝업 활성화 컨트롤 + const [showDesignRequestButtonValid, setShowDesignRequestButtonValid] = useState(false) //설계의뢰팝업 활성화 컨트롤 + const [showWindSpeedButtonValid, setShowWindSpeedButtonValid] = useState(false) //풍속선택팝업 활성화 컨트롤 const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set const [editMode, setEditMode] = useState('NEW') const [detailData, setDetailData] = useState({}) useEffect(() => { + console.log('objectNo::', objectNo) + if (objectNo) { - //console.log('수정화면') + console.log('수정화면') setEditMode('EDIT') if (objectNo.substring(0, 1) === 'R') { @@ -75,95 +90,132 @@ 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) setDetailData(res) - - // 신규 상세 공통APi - // 도도부현API - get({ url: '/api/object/prefecture/list' }).then((res) => { - if (!isEmptyArray(res)) { - //console.log('도도부현API 결과:::', res) - setPrefCodeList(res) - } - }) - // 판매점목록 API /api/object/saleStore/판매점코드/list - 판매점 목록 조회 - // 임시 1차점 판매점코드 saleStoreId=201TES01 - // T01 - //1차점 : X167 - get({ url: `/api/object/saleStore/X167/list` }).then((res) => { - if (!isEmptyArray(res)) { - // console.log('판매점 결과:::::', res) - setSaleStoreList(res) - //1차 판매점 자동완성 값 셋팅 - form.setValue('saleStoreId', res[0].saleStoreId) - //1차 판매점 번호 셋팅 - form.setValue('saleStoreName', res[0].saleStoreId) - setOtherSaleStoreList([]) - } - }) } }) } else { - console.log('신규화면') // 신규 상세 공통APi // 도도부현API get({ url: '/api/object/prefecture/list' }).then((res) => { if (!isEmptyArray(res)) { - //console.log('도도부현API 결과:::', res) + // console.log('신규화면 도도부현API 결과:::', res) setPrefCodeList(res) } }) - // 판매점목록 API /api/object/saleStore/판매점코드/list - 판매점 목록 조회 + // 임시 1차점 판매점코드 saleStoreId=201TES01 // T01 //1차점 : X167 - get({ url: `/api/object/saleStore/X167/list` }).then((res) => { + get({ url: `/api/object/saleStore/T01/list` }).then((res) => { + // get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => { if (!isEmptyArray(res)) { - console.log('판매점 결과:::::', 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', firstList[0].saleStoreId) - //1차 판매점 번호 셋팅 - form.setValue('saleStoreName', firstList[0].saleStoreId) - //1차점 아닌 판매점 셀렉트박스 + setOriginOtherSaleStoreList(otherList) setOtherSaleStoreList(otherList) } }) } }, [objectNo]) + useEffect(() => { + if (isObjectNotEmpty(detailData)) { + console.log('상세데이타:::::::', detailData) + + // 도도부현API + get({ url: '/api/object/prefecture/list' }).then((res) => { + if (!isEmptyArray(res)) { + // console.log('도도부현API 결과:::', res) + setPrefCodeList(res) + } + }) + + //상세정보로 1차점 목록등 셋팅?? + // 임시 1차점 판매점코드 saleStoreId=201TES01 + // T01 + //1차점 : X167 + get({ url: `/api/object/saleStore/T01/list` }).then((res) => { + // get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => { + if (!isEmptyArray(res)) { + const firstList = res.filter((row) => row.saleStoreLevel === '1') + const otherList = res.filter((row) => row.saleStoreLevel !== '1') + //1차점 셀렉트박스 + setSaleStoreList(firstList) + //1차점 아닌 판매점 셀렉트박스 + setOriginOtherSaleStoreList(otherList) + setOtherSaleStoreList(otherList) + } + }) + } + }, [detailData]) + //1차점 변경 이벤트 const onSelectionChange = (key) => { - if (key == null) { + if (isObjectNotEmpty(key)) { + setOtherSaleStoreList(otherSaleStoreList) + form.setValue('saleStoreId', key.saleStoreId) + form.setValue('saleStoreName', key.saleStoreName) + form.setValue('saleStoreLevel', key.saleStoreLevel) + //선택한 1차점 정보로 2차점 list 추리기 + //長府工産株式会社 大阪支社 + let newOtherSaleStoreList = originOtherSaleStoreList.filter((row) => row.firstAgentId === key.saleStoreId) + setOtherSaleStoreList(newOtherSaleStoreList) + } else { + //X누름 form.setValue('saleStoreId', '') form.setValue('saleStoreName', '') - } else { - form.setValue('saleStoreId', key) - form.setValue('saleStoreName', key) + form.setValue('saleStoreLevel', '') + form.setValue('otherSaleStoreId', '') + form.setValue('otherSaleStoreName', '') + form.setValue('otherSaleStoreLevel', '') + setOtherSaleStoreList(originOtherSaleStoreList) + //1차점 지웠을때 2차점 자동완성 초기화 + handleClear() } } //2차점 변경 이벤트 const onSelectionChange2 = (key) => { - console.log(key) - } - // 우편번호 숫자만 체크 - const _zipNo = watch('zipNo') - useEffect(() => { - if (_zipNo !== '' && _zipNo.length === 7 && !_zipNo.match(/\D/g)) { - setButtonValid(true) + if (isObjectNotEmpty(key)) { + form.setValue('otherSaleStoreId', key.saleStoreId) + form.setValue('otherSaleStoreName', key.saleStoreName) + form.setValue('otherSaleStoreLevel', key.saleStoreLevel) } else { - setButtonValid(false) + form.setValue('otherSaleStoreId', '') + form.setValue('otherSaleStoreName', '') + form.setValue('otherSaleStoreLevel', '') } - }, [_zipNo]) + } + + //1차점 지웠을때 2차점 자동완성 초기화 + const handleClear = () => { + if (ref.current) { + ref.current.clearValue() + } + } + + //팝업에서 넘어온 우편정보 + const setZipInfo = (info) => { + // console.log('팝업에서 넘어온 데이타::::::::', info) + setPrefValue(info.prefId) + form.setValue('prefId', info.prefId) + form.setValue('prefName', info.address1) + form.setValue('address', info.address2 + info.address3) + form.setValue('zipNo', info.zipNo) + } + + //팝업에서 넘어온 설계의뢰 정보 + const setPlanReqInfo = (info) => {} + + //팝업에서 넘어온 바람정보 + const setWindSppedInfo = (info) => { + form.setValue('windSpeed', info.windSpeed) + } //임시저장 저장 버튼 컨트롤 // dispCompanyName: '', //담당자 @@ -173,127 +225,139 @@ export default function StuffDetail() { // zipNo: '', //우편번호 // prefId: '', //도도부현 // address: '', //주소 - // powerSimArea: '', //발전량시뮬레이션지역 + // areaId: '', //발전량시뮬레이션지역new // windSpeed: '', //기준풍속 - // snowCover: '', //수직적설량 - // coldAreaChk: false, //한랭지대책시행 + // verticalSnowCover: '', //수직적설량 + // coldRegionFlg: false, //한랭지대책시행 // surfaceType: 'Ⅲ・Ⅳ', //면조도구분(Ⅲ・Ⅳ / Ⅱ) - // saltAreaChk: false, //염해지역용아이템사용 + // saltAreaFlg: false, //염해지역용아이템사용 // installHeight: '', //설치높이 - // powerConTerms: '0', //계약조건(잉여 / 전량) + // conType : '0' //계약조건(잉여 / 전량) // remarks: '', //메모 // tempFlag: 'T', //임시저장(1) 저장(0) const _dispCompanyName = watch('dispCompanyName') const _objectName = watch('objectName') const _objectNameOmit = watch('objectNameOmit') const _saleStoreId = watch('saleStoreId') + const _saleStoreLevel = watch('saleStoreLevel') const _prefId = watch('prefId') const _address = watch('address') - const _powerSimArea = watch('powerSimArea') + const _areaId = watch('areaId') //new const _windSpeed = watch('windSpeed') - const _snowCover = watch('snowCover') + const _verticalSnowCover = watch('verticalSnowCover') const _installHeight = watch('installHeight') + useEffect(() => { - // 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) { + if (!formData.dispCompanyName || formData.dispCompanyName.trim().length === 0) { errors.dispCompanyName = true } - if (!_objectName || _objectName.trim().length === 0) { + if (!formData.objectName || formData.objectName.trim().length === 0) { errors.objectName = true } - if (!_objectNameOmit) { + if (!formData.objectNameOmit) { errors.objectNameOmit = true } - if (!_saleStoreId) { + if (!formData.saleStoreId) { errors.saleStoreId = true } - if (!_zipNo || _zipNo.length != 7) { - errors.zipCode = true - } - - if (!_prefId) { + if (!formData.prefId) { errors.prefId = true } - if (!_address.trim().length === 0) { - errors.address = true + if (!formData.areaId) { + errors.areaId = true } - if (!_powerSimArea) { - errors.powerSimArea = true - } - - if (!_windSpeed) { + if (!formData.windSpeed) { errors.windSpeed = true } - if (!_snowCover) { - errors.snowCover = true + if (!formData.verticalSnowCover) { + errors.verticalSnowCover = true } - if (!_installHeight) { + if (!formData.installHeight) { errors.installHeight = true } - // console.log('errors::', errors) + // console.log('임시저장용::', errors) setIsFormValid(Object.keys(errors).length === 0) } else { - // console.log('상세일때 폼체크') + console.log('상세일때 폼체크') } - }, [_dispCompanyName, _objectName, _objectNameOmit, _saleStoreId, _zipNo, _prefId, _address, _powerSimArea, _windSpeed, _snowCover, _installHeight]) + }, [ + _dispCompanyName, + _objectName, + _objectNameOmit, + _saleStoreId, + _saleStoreLevel, + // _otherSaleStoreId, + // _otherSaleStoreLevel, + _prefId, + _address, + _areaId, + _windSpeed, + _verticalSnowCover, + _installHeight, + ]) - // 주소검색 API - const onSearchPostNumber = () => { - const params = { - zipcode: _zipNo, + // 주소검색 팝업오픈 + const onSearchPostNumberPopOpen = () => { + setShowAddressButtonValid(true) + } + + //설계의뢰 팝업 오픈 + const onSearchDesignRequestPopOpen = () => { + setShowDesignRequestButtonValid(true) + } + + // 풍속선택 팝업 오픈 + const onSearchWindSpeedPopOpen = () => { + const prefName = form.watch('prefName') + if (prefName === '') { + alert(getMessage('stuff.windSelectPopup.error.message1')) + } else { + setShowWindSpeedButtonValid(true) } - get({ url: `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter(params)}` }).then((res) => { - //7830060 - //9302226 - if (res.status === 200) { - if (res.results != null) { - // 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('') - setPowerSimAreaList([]) - form.setValue('powerSimArea', '') - } - } else { - alert(res.message) - } - }) } useEffect(() => { if (prefValue !== '') { - // console.log('우편번호 검색해서 도도부현골랐을때::::', prefValue) // 발전량시뮬레이션 지역 목록 - // /api/object/prefecture/도도부현코드/list get({ url: `/api/object/prefecture/${prefValue}/list` }).then((res) => { if (!isEmptyArray(res)) { - // console.log('발전시뮬레이션::::::::', res) - setPowerSimAreaList(res) + // console.log('발전량 시뮬레이션::::::::', res) + form.setValue('areaId', res[0].areaId) + form.setValue('areaName', res[0].prefName) + setAreaIdList(res) } }) } }, [prefValue]) + // 발전량 시뮬레이션 변경 + const handleAreaIdOnChange = (e) => { + form.setValue('areaId', e.target.value) + } + + // useEffect(() => { + // if (!isEmptyArray(areaIdList)) { + // let _prefName = form.watch('prefName') + // // console.log('기준풍속 가져오는 API', _prefName) + // get({ url: `/api/object/windSpeed/${_prefName}/list` }).then((res) => { + // // console.log('res::', res) + // if (!isEmptyArray(res)) { + // setWindSpeedList(res) + // } + // }) + // } + // }, [areaIdList]) + //필수값 다 입력했을때 const onValid = (data) => { // 수정모드일때는 PUT @@ -307,7 +371,7 @@ export default function StuffDetail() { // const _zipNo = watch('zipNo') // const _prefId = watch('prefId') // const _address = watch('address') - // const _coldAreaChk = watch('coldAreaChk') + // const _coldRegionFlg = watch('coldRegionFlg') // console.log(_dispCompanyName) // console.log(_objectStatusId) // console.log(_objectNameOmit) @@ -315,7 +379,7 @@ export default function StuffDetail() { // console.log(_prefId) // console.log('prefValue::', prefValue) // console.log(_address) - // console.log('_coldAreaChk::', _coldAreaChk) + // console.log('_coldRegionFlg::', _coldRegionFlg) } //필수값 안넣었을때 임시저장 form required사용시 @@ -328,11 +392,11 @@ export default function StuffDetail() { // 임시저장 const onTempSave = async () => { const formData = form.getValues() - //console.log('임시저장::::::::', formData) - + // console.log('formData::', formData) const params = { - saleStoreId: formData.saleStoreId, - saleStoreName: formData.saleStoreName, + saleStoreId: formData.otherSaleStoreId ? formData.otherSaleStoreId : formData.saleStoreId, + saleStoreName: formData.otherSaleStoreName ? formData.otherSaleStoreName : formData.saleStoreName, + saleStoreLevel: formData.otherSaleStoreLevel ? formData.otherSaleStoreLevel : formData.saleStoreLevel, objectStatusId: formData.objectStatusId, objectName: formData.objectName, objectNameOmit: formData.objectNameOmit, @@ -341,31 +405,31 @@ export default function StuffDetail() { prefId: formData.prefId, prefName: formData.prefName, address: formData.address, - powerSimArea: formData.powerSimArea, + areaId: formData.areaId, receiveUser: formData.dispCompanyName, installHeight: formData.installHeight, windSpeed: formData.windSpeed, - snowCover: formData.snowCover, + verticalSnowCover: formData.verticalSnowCover, surfaceType: formData.surfaceType, - powerConTerms: formData.powerConTerms, - saltAreaChk: formData.saltAreaChk, - coldAreaChk: formData.coldAreaChk, + conType: formData.conType, + coldRegionFlg: formData.coldRegionFlg, + saltAreaFlg: formData.saltAreaFlg, 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) - }) - } + //1차점 or 2차점 안고르고 임시저장하면 + if (params.saleStoreId == '') { + params.saleStoreId = sessionState.storeId + params.saleStoreLevel = sessionState.storeLvl + } - // 발전량 시뮬레이션 변경 - const handlePowerSimAreaOnChange = (e) => { - // console.log('가지고있는 도도부현코드:::::::::', prefValue) - // console.log('발전량시뮬레이션변경:::::::::', e.target.value) - //값 set해주고 그거 useEffect로 api호출 + await promisePost({ url: '/api/object/save-object', data: params }).then((res) => { + if (res.status === 201) { + alert('임시저장 되었습니다. 물건번호를 획득하려면 필수 항목을 모두 입력해 주십시오.') + router.push(`${pathname}?objectNo=${res.data.objectNo.toString()}`) + } + }) } // 물건삭제 @@ -389,7 +453,8 @@ export default function StuffDetail() {
- * 필수 입력항목 + * + {getMessage('stuff.detail.required')}
@@ -398,9 +463,22 @@ export default function StuffDetail() { + + + + - + + + + + - - - - + + + + - - - - - + - + @@ -663,6 +782,111 @@ export default function StuffDetail() { )) || ( <> + +
+
+ * {getMessage('stuff.detail.required')} +
+
+
{getMessage('stuff.detail.planReqNo')} +
+
+ +
+ +
+
- 담당자 * + {getMessage('stuff.detail.dispCompanyName')} *
@@ -410,24 +488,24 @@ export default function StuffDetail() {
- 물건구분/물건명 * + {getMessage('stuff.detail.objectStatusId')} *
- +
- +
- + @@ -437,7 +515,7 @@ export default function StuffDetail() {
물건명 후리가나{getMessage('stuff.detail.objectNameKana')}
@@ -448,23 +526,59 @@ export default function StuffDetail() {
- 1차 판매점명 / ID + {getMessage('stuff.detail.saleStoreId')} *
-
+
+ {getMessage('stuff.detail.tooltip.saleStoreId')} +
-
- +
+ +
+
+
+
+
{getMessage('stuff.detail.otherSaleStoreId')}
+
+ {getMessage('stuff.detail.tooltip.saleStoreId')} +
+
+
+
+
+
@@ -473,62 +587,37 @@ export default function StuffDetail() {
-
-
- 2차 판매점명 / ID * -
-
-
-
-
-
- -
-
-
- -
-
- 우편번호 * + {getMessage('stuff.detail.zipNo')} *
- +
- -
*우편번호 7자리를 입력한 후, 주소검색 버튼을 클릭해 주십시오
+
{getMessage('stuff.detail.btn.addressPop.guide')}
- 도도부현 / 주소 * + {getMessage('stuff.detail.prefId')} + *
-
- {/* {prefCodeList?.length > 0 && ( - - )} */} +
+ {prefCodeList?.length > 0 && ( + + )}
@@ -538,48 +627,78 @@ export default function StuffDetail() {
- 발전량시뮬레이션지역 * + {getMessage('stuff.detail.areaId')} * -
+
+ +
- 기준풍속 * + {getMessage('stuff.detail.windSpeed')} * + +
+
+ +
+ {/*
+ +
*/} + {getMessage('stuff.detail.windSpeedSpan')} + +
+
+ {getMessage('stuff.detail.verticalSnowCover')} *
- + - - +
- m/s이하 -
-
- 수직적설량 * - -
-
cm
- - + +
- 면조도구분 * + {getMessage('stuff.detail.surfaceType')} *
@@ -592,8 +711,8 @@ export default function StuffDetail() {
- - + +
@@ -601,7 +720,7 @@ export default function StuffDetail() {
- 설치높이 * + {getMessage('stuff.detail.installHeight')} *
@@ -618,25 +737,25 @@ export default function StuffDetail() {
계약조건{getMessage('stuff.detail.conType')}
- - + +
- - + +
메모{getMessage('stuff.detail.remarks')}
- +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
{getMessage('stuff.detail.planReqNo')} +
+
+ +
+ +
+
+ {getMessage('stuff.detail.dispCompanyName')} * + +
+ {/* */} +
+
+ {getMessage('stuff.detail.objectStatusId')} * + +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+
{getMessage('stuff.detail.objectNameKana')} +
+ +
+
+
+
+ {getMessage('stuff.detail.saleStoreId')} + * +
+
+
+
+
+
+ {/* */} +
+
+ +
+
+
+
+
+ {objectNo.substring(0, 1) === 'R' ? ( <> @@ -679,245 +903,31 @@ export default function StuffDetail() { ) : ( <> + {!isFormValid ? ( + + ) : ( + + )} - )} )} - {/* {(editMode === 'NEW' && ( -
-
-
(*필수 입력항목)
-
- - -
-
- - - - - - -
- -
-
-
- - -
-
- -
- {saleStoreList?.length > 0 && ( - - {(option) => {option.saleStoreName}} - - )} - -
-
-
- -
- {otherSaleStoreList?.length > 0 && ( - - {(option) => {option.saleStoreName}} - - )} -
-
-
- - - - *우편번호 7자리를 입력한 후, 주소검색 버튼을 클릭해 주십시오 -
-
- -
- {prefCodeList?.length > 0 && ( - - )} -
- - -
-
- - {powerSimAreaList?.length > 0 && ( - - )} -
-
- -
- -
-
-
- - {' '} - cm - { - form.setValue('coldAreaChk', e) - }} - {...form.register('coldAreaChk')} - > - 한랭지대책시행 - -
-
- - - - - - { - form.setValue('saltAreaChk', e) - }} - > - 염해지역용아이템사용 - -
-
- -
- -
-
-
- - - - - -
-
- -