diff --git a/package.json b/package.json index 5355cae6..260bfe8e 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "prettier": "^3.3.3", "prisma": "^5.18.0", "react-color-palette": "^7.2.2", + "react-dropdown-select": "^4.11.3", "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/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..a4ebac98 --- /dev/null +++ b/public/static/images/canvas/object_img01.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + 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/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/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..f7aafcd0 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -61,18 +61,21 @@ export default async function RootLayout({ children }) { - {/*{headerPathname !== '/login' && }*/} -
-
- -
- - {children} -
-
-
+ {headerPathname !== '/login' ? ( +
+
+ +
+ + {children} +
+
+
+ ) : ( + {children} + )} - + {/* */}
diff --git a/src/app/login/page.jsx b/src/app/login/page.jsx index 0686da2e..3ff0edd7 100644 --- a/src/app/login/page.jsx +++ b/src/app/login/page.jsx @@ -1,9 +1,10 @@ import Login from '@/components/auth/Login' +import NewLogin from '@/components/auth/NewLogin' export default function LoginPage() { return ( <> - + ) } 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 f9ca6fff..ae96db06 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 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..69c90071 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -1,9 +1,169 @@ 'use client' +import React, { useEffect, useState } from 'react' + +import { useRouter } from 'next/navigation' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { modalContent, modalState, modalProps } from '@/store/modalAtom' +import { sessionStore } from '@/store/commonAtom' +import { useAxios } from '@/hooks/useAxios' +import { globalLocaleStore } from '@/store/localeAtom' +import MainContents from './main/MainContents' +import { useMessage } from '@/hooks/useMessage' +import { stuffSearchState } from '@/store/stuffAtom' +import { useForm } from 'react-hook-form' +import '@/styles/contents.scss' +import ChangePasswordPop from './main/ChangePasswordPop' +export default function MainPage() { + const [sessionState, setSessionState] = useRecoilState(sessionStore) + + const globalLocaleState = useRecoilValue(globalLocaleStore) + + const { get } = useAxios(globalLocaleState) + const router = useRouter() + const { getMessage } = useMessage() + + const [searchTxt, setSearchTxt] = useState('') + + const [searchRadioType, setSearchRadioType] = useState('object') + //컨텐츠 관련 + const [saleStoreId, setSaleStoreId] = useState('') + const [saleStoreName, setSaleStoreName] = useState('') + + const [objectList, setObjectList] = useState([]) + const [businessCharger, setBusinessCharger] = useState('') + const [businessChargerMail, setBusinessChargerMail] = useState('') + const [businessChargerTel, setBusinessChargerTel] = useState('') + + const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) + + useEffect(() => { + if (sessionState.pwdInitYn === 'Y') { + fetchObjectList() + } + }, [sessionState]) + + const fetchObjectList = async () => { + try { + // const apiUrl = `/api/main-page/object/X167/list` + const apiUrl = `/api/main-page/object/${sessionState?.storeId}/list` + const res = await get({ url: apiUrl }) + if (res) { + setSaleStoreId(res.saleStoreId) + setSaleStoreName(res.saleStoreName) + setObjectList(res.objectList) + setBusinessCharger(res.businessCharger) + setBusinessChargerMail(res.businessChargerMail) + setBusinessChargerTel(res.businessChargerTel) + } + } catch (error) { + console.error('MAIN API fetching error:', error) + } + } + + // 엔터 이벤트 + const handleByOnKeyUp = (e) => { + if (e.key === 'Enter') { + //물건번호 일떄 + if (searchRadioType === 'object') { + setStuffSearch({ + ...stuffSearch, + schObjectNo: searchTxt, + code: 'M', + }) + router.push('/management/stuff') + } else { + alert('작업중') + return + + //FAQ일떄 + //faq리코일에 + //searchValue= e.target.value + //mainFlag:'Y' + // router.push('/community/faq') + } + } + } + + // 라디오 변경 이벤트 + const handleOnChangeRadio = (e) => { + setSearchRadioType(e.target.value) + } + + // 돋보기 클릭 + const handleOnSubmit = () => { + if (searchRadioType === 'object') { + setStuffSearch({ + ...stuffSearch, + schObjectNo: searchTxt, + code: 'M', + }) + + router.push('/management/stuff') + } else { + alert('작업중') + return + //FAQ일떄 + //faq리코일에 + //searchValue= e.target.value + //mainFlag:'Y' + // router.push('/community/faq') + } + } -export default function MainPage(props) { return ( <> -

Main page

+ {(sessionState?.pwdInitYn !== 'N' && ( + <> +
+
+
+
+
+ {getMessage('main.storeId')}/ {getMessage('main.storeName')} +
+
+ +
+ {saleStoreId} / {saleStoreName} +
+
+
+
+
+ + +
+
+ + +
+
+
+ { + setSearchTxt(e.target.value) + }} + /> + +
+
+ +
+ + )) || ( + <> + + + )} ) } diff --git a/src/components/Playground.jsx b/src/components/Playground.jsx index 200a0337..5d54c858 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,9 @@ 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' + export default function Playground() { const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) @@ -35,6 +37,23 @@ 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 = { @@ -116,7 +135,98 @@ export default function Playground() {
이 영역은 테스트입니다.
- + + + +
+ + +
+ + +
+
+
+ + + +
{testVar}
diff --git a/src/components/auth/Join.jsx b/src/components/auth/Join.jsx index 03fc8ecb..ae100e68 100644 --- a/src/components/auth/Join.jsx +++ b/src/components/auth/Join.jsx @@ -1,11 +1,12 @@ 'use client' -import { post } from '@/lib/Axios' +import { useAxios } from '@/hooks/useAxios' import { redirect } from 'next/navigation' import { useMessage } from '@/hooks/useMessage' export default function Join() { const { getMessage } = useMessage() + const { post } = useAxios() const joinProcess = async (formData) => { const param = { diff --git a/src/components/auth/NewLogin.jsx b/src/components/auth/NewLogin.jsx new file mode 100644 index 00000000..61c02abf --- /dev/null +++ b/src/components/auth/NewLogin.jsx @@ -0,0 +1,244 @@ +'use client' + +import { useState, useRef, useEffect } from 'react' +import Image from 'next/image' +import Link from 'next/link' +import { redirect } from 'next/navigation' +import { useRecoilState } from 'recoil' +import { useAxios } from '@/hooks/useAxios' +import { setSession } from '@/lib/authActions' +import { useMessage } from '@/hooks/useMessage' +import { globalLocaleStore } from '@/store/localeAtom' +import { sessionStore } from '@/store/commonAtom' +import { modalContent, modalState } from '@/store/modalAtom' +import '@/styles/style.scss' +import { useRouter } from 'next/navigation' + +export default function NewLogin() { + const [passwordVisible, setPasswordVisible] = useState(false) + const passwordRef = useRef(null) + const router = useRouter() + + useEffect(() => { + setOpen(false) + }, []) + + useEffect(() => { + if (passwordVisible) { + passwordRef.current.type = 'text' + } else { + passwordRef.current.type = 'password' + } + }, [passwordVisible]) + + const { patch } = useAxios() + + 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') + } + + setIsSelected(!isSelected) + } + + // 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) + // } + // } + // }) + + // 임시 로그인 처리 + setSession({ + userId: 'NEW016610', + saleStoreId: null, + name: null, + mail: null, + tel: null, + storeId: 'TEMP02', + userNm: 'ㅇㅇ6610', + userNmKana: '신규사용자 16610', + category: '인상6610', + telNo: '336610', + fax: null, + email: 't10t@naver.com', + pwdInitYn: 'Y', + }) + + setSessionState({ + userId: 'NEW016610', + saleStoreId: null, + name: null, + mail: null, + tel: null, + storeId: 'TEMP02', + userNm: 'ㅇㅇ6610', + userNmKana: '신규사용자 16610', + category: '인상6610', + telNo: '336610', + fax: null, + email: 't10t@naver.com', + pwdInitYn: 'Y', + }) + + // redirect('/') + router.push('/') + // 임시 로그인 처리 끝 + } + + // 비밀번호 초기화 관련 + const [open, setOpen] = useRecoilState(modalState) + const [contents, setContent] = useRecoilState(modalContent) + + const initPasswordProcess = async (formData) => { + const param = { + langCd: currentLocale, + lastEditUser: formData.get('checkId'), + loginId: formData.get('checkId'), + email: formData.get('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) + } + } + }) + } + + const initPasswordContent = ( +
+
+

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

+

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

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

+ +

+
+
+ ) + + return ( +
+
+ + react + +
+
+
+ Q.CAST III + 太陽光発電システム図面管理サイト +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ パスワードの初期化 +
+
+
+
+
+ 当サイトをご利用の際は、事前申請が必要です。 +
+ IDがない方は ID申請 クリックしてください。 +
+
+
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 similarity index 60% rename from src/components/common/draggable/WithDraggable.jsx rename to 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/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/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 9e034ac9..43661bf2 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 { @@ -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 @@ -194,14 +200,14 @@ 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) 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..3b823460 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -1,13 +1,19 @@ 'use client' -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' import { useCanvas } from '@/hooks/useCanvas' import { useEvent } from '@/hooks/useEvent' +import QContextMenu from '@/components/common/context-menu/QContextMenu' +import { useRecoilValue } from 'recoil' +import { currentMenuState } from '@/store/canvasAtom' +import { MENU } from '@/common/common' export default function CanvasFrame({ plan }) { const canvasRef = useRef(null) const { canvas } = useCanvas('canvas') + const currentMenu = useRecoilValue(currentMenuState) + const [contextMenu, setContextMenu] = useState([[]]) useEvent() const loadCanvas = () => { @@ -25,9 +31,142 @@ export default function CanvasFrame({ plan }) { loadCanvas() }, [plan]) + useEffect(() => { + switch (currentMenu) { + case MENU.PLAN_DRAWING: + setContextMenu([ + [ + { + name: '그리드 이동', + }, + { + name: '그리드 복사', + }, + { + name: '그리드 색 변경', + }, + { + name: '삭제', + }, + { + name: '전체 삭제', + }, + ], + ]) + break + case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE: + case MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS: + case MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS: + case MENU.ROOF_COVERING.ROOF_SHAPE_EDITING: + case MENU.ROOF_COVERING.HELP_LINE_DRAWING: + case MENU.ROOF_COVERING.EAVES_KERAVA_EDIT: + case MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN: + case MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET: + case MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC: + case MENU.ROOF_COVERING.DEFAULT: + console.log('지붕덮개') + setContextMenu([ + [ + { + name: '지붕재 배치', + }, + { + name: '지붕재 삭제', + }, + { + name: '지붕재 전체 삭제', + }, + { + name: '선택・이동', + }, + { + name: '외벽선 삭제', + }, + ], + [ + { + name: '사이즈 변경', + }, + { + name: '보조선 이동(M)', + }, + { + name: '보조선 복사(C)', + }, + { + name: '보조선 삭제(D)', + }, + { + name: '보조선 수직이등분선', + }, + { + name: '보조선 절삭', + }, + { + name: '보조선 전체 삭제', + }, + ], + ]) + break + case MENU.BATCH_CANVAS.SLOPE_SETTING: + case MENU.BATCH_CANVAS.BATCH_DRAWING: + case MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH: + case MENU.BATCH_CANVAS.OBJECT_BATCH: + case MENU.BATCH_CANVAS.ALL_REMOVE: + case MENU.BATCH_CANVAS.DEFAULT: + console.log('배치면') + setContextMenu([ + [ + { + name: '사이즈 변경', + }, + { + name: '삭제(D)', + }, + { + name: '이동(M)', + }, + { + name: '복사(C)', + }, + ], + [ + { + name: '지붕재 변경', + }, + { + name: '각 변 속성 변경', + }, + { + name: '흐름 방향 변경', + }, + ], + ]) + break + default: + console.log('default') + setContextMenu([]) + break + } + }, [currentMenu]) + + useEffect(() => { + console.log('currentMenu', currentMenu) + console.log('contextMenu', contextMenu) + }, [contextMenu]) + return (
+ + {contextMenu.map((menus, index) => ( +
    + {menus.map((menu) => ( +
  • {menu.name}
  • + ))} +
+ ))} +
) } diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 3abebd85..7a3e9323 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -7,39 +7,53 @@ 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 { getMessage } = useMessage() const { swalFire } = useSwal() - const { getCanvasByObjectNo, delCanvasById } = usePlan() + const { getCanvasByObjectNo, delCanvasById, checkModifiedCanvasPlan, saveCanvas } = usePlan() const handleCurrentPlan = (newCurrentId) => { + // console.log('currentPlan newCurrentId: ', 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 } - }), - ) + 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() // 이벤트 버블링 방지 @@ -48,20 +62,21 @@ export default function CanvasLayout() { delCanvasById(id) .then((res) => { swalFire({ text: getMessage('common.message.delete') }) - console.log('[DELETE] canvas-statuses res :::::::: %o', res) + // 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) + // console.error('[DELETE] canvas-statuses res error :::::::: %o', error) }) } else { - setAddCanvasPlans(addCanvasPlans.filter((plan) => plan.id !== id)) + setPlans((plans) => plans.filter((plan) => plan.id !== id)) swalFire({ text: getMessage('common.message.delete') }) } // 삭제 후 last 데이터에 포커싱 - const lastPlan = [...initCanvasPlans, ...addCanvasPlans].filter((plan) => plan.id !== id).at(-1) + const lastPlan = plans.filter((plan) => plan.id !== id).at(-1) if (!lastPlan) { setPlanNum(0) setCurrentCanvasPlan(null) @@ -71,7 +86,7 @@ export default function CanvasLayout() { } const addNewPlan = () => { - setAddCanvasPlans([...addCanvasPlans, { id: planNum, name: `Plan ${planNum + 1}`, objectNo: `${objectNo}` }]) + setPlans([...plans, { id: planNum, name: `Plan ${planNum + 1}`, objectNo: `${objectNo}` }]) handleCurrentPlan(planNum) setPlanNum(planNum + 1) } @@ -81,6 +96,7 @@ export default function CanvasLayout() { console.log('canvas 목록 ', res) if (res.length > 0) { setInitCanvasPlans(res) + setPlans(res) handleCurrentPlan(res.at(-1).id) // last 데이터에 포커싱 setPlanNum(res.length) } else { @@ -93,7 +109,7 @@ export default function CanvasLayout() {
- {[...initCanvasPlans, ...addCanvasPlans].map((plan) => ( + {plans.map((plan) => (
- plan.isCurrent === true)} /> + plan.isCurrent === true)} />
) } diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 07b248cb..eae0ea4e 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -10,7 +10,7 @@ import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' import { usePlan } from '@/hooks/usePlan' import { useSwal } from '@/hooks/useSwal' -import { canvasState, canvasZoomState, currentMenuState, currentCanvasPlanState, verticalHorizontalModeState } from '@/store/canvasAtom' +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' @@ -31,7 +31,24 @@ 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, + } = props const [menuNumber, setMenuNumber] = useState(null) const [type, setType] = useState('') @@ -57,6 +74,10 @@ export default function CanvasMenu(props) { setCurrentMenu(menu.title) switch (menu.index) { + case 1: + setType('placementShape') + onClickPlacementInitialMenu() + break case 2: setType('outline') break @@ -70,12 +91,28 @@ export default function CanvasMenu(props) { } const menuProps = { setShowOutlineModal, + setShowPlaceShapeModal, + setShowRoofShapeSettingModal, + setShowRoofShapePassivitySettingModal, + setShowAuxiliaryModal, + setShowEavesGableEditModal, + setShowMovementModal, + setShowSlopeSettingModal, + setShowPlacementSurfaceSettingModal, + setShowPlaceShapeDrawingModal, + setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, + setShowObjectSettingModal, + setShowBasicSettingModal, type, } const settingsModalOptions = useRecoilState(settingModalFirstOptionsState) useEffect(() => { + if (menuNumber === 1) { + onClickPlacementInitialMenu() + } if (menuNumber !== 2 && showOutlineModal) setShowOutlineModal(false) }, [menuNumber, type]) @@ -90,6 +127,14 @@ export default function CanvasMenu(props) { }) } + const onClickPlacementInitialMenu = () => { + setShowOutlineModal(false) + setShowCanvasSettingModal(false) + setShowEavesGableEditModal(false) + setShowMovementModal(false) + setShowPlaceShapeModal(true) + } + const handleClear = () => { setPoints([]) canvas?.clear() @@ -135,7 +180,7 @@ export default function CanvasMenu(props) {
}
- +
diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 55b700c1..d614a809 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -12,11 +12,39 @@ 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' 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 globalLocaleState = useRecoilValue(globalLocaleStore) const { get } = useAxios(globalLocaleState) @@ -27,9 +55,11 @@ 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 = { @@ -41,6 +71,19 @@ export default function FloorPlan() { setShowCanvasSettingModal, showOutlineModal, setShowOutlineModal, + setShowPlaceShapeModal, + setShowSlopeSettingModal, + setShowPlacementSurfaceSettingModal, + setShowPlaceShapeDrawingModal, + setShowRoofShapeSettingModal, + setShowObjectSettingModal, + setShowRoofShapePassivitySettingModal, + setShowAuxiliaryModal, + setShowEavesGableEditModal, + setShowMovementModal, + setShowWallLineOffsetSettingModal, + setShowRoofAllocationSettingModal, + setShowBasicSettingModal, } useEffect(() => { @@ -78,6 +121,10 @@ export default function FloorPlan() { setShowDotLineGridModal, } + const gridColorProps = { + setShowColorPickerModal, + } + const propertiesSettingProps = { setShowPropertiesSettingModal, } @@ -91,10 +138,26 @@ export default function FloorPlan() {
{showCanvasSettingModal && } - {/*{showOutlineModal && }*/} {showOutlineModal && } {showDotLineGridModal && } + {showColorPickerModal && } {showPropertiesSettingModal && } + + {showPlaceShapeModal && } + {showRoofShapeSettingModal && } + {showRoofShapePassivitySettingModal && ( + + )} + {showAuxiliaryModal && } + {showSlopeSettingModal && } + {showPlaceShapeDrawingModal && } + {showEavesGableEditModal && } + {showMovementModal && } + {showRoofAllocationSettingModal && } + {showWallLineOffsetSettingModal && } + {showObjectSettingModal && } + {showPlacementSurfaceSettingModal && } + {showBasicSettingModal && }
diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index a6b12877..c7642894 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -7,7 +7,23 @@ import { currentMenuState } from '@/store/canvasAtom' import { useSetRecoilState } from 'recoil' 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, + } = props const { getMessage } = useMessage() const [activeMenu, setActiveMenu] = useState() const setCurrentMenu = useSetRecoilState(currentMenuState) @@ -15,8 +31,45 @@ export default function MenuDepth01(props) { 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) + } + + if (type === 'surface') { + setShowOutlineModal(false) + setShowRoofShapeSettingModal(false) + setShowRoofShapePassivitySettingModal(false) + setShowAuxiliaryModal(false) + setShowEavesGableEditModal(false) + setShowMovementModal(false) + setShowWallLineOffsetSettingModal(false) + setShowRoofAllocationSettingModal(false) + + setShowSlopeSettingModal(id === 0) + setShowPlaceShapeDrawingModal(id === 1) + setShowPlacementSurfaceSettingModal(id === 2) + setShowObjectSettingModal(id === 3) + } + + if (type === 'module') { + setShowOutlineModal(false) + setShowRoofShapeSettingModal(false) + setShowRoofShapePassivitySettingModal(false) + setShowAuxiliaryModal(false) + setShowEavesGableEditModal(false) + setShowMovementModal(false) + setShowWallLineOffsetSettingModal(false) + setShowRoofAllocationSettingModal(false) + setShowBasicSettingModal(id === 0) } } 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..1732f3f7 --- /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() + + 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/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx new file mode 100644 index 00000000..d28e3ef5 --- /dev/null +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -0,0 +1,56 @@ +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 Placement from '@/components/floor-plan/modal/basic/step/Placement' + +export default function BasicSetting({ setShowBasicSettingModal }) { + const { getMessage } = useMessage() + const [tabNum, setTabNum] = useState(1) + + 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 && } + {tabNum === 2 && } + {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..8109da08 --- /dev/null +++ b/src/components/floor-plan/modal/basic/step/Module.jsx @@ -0,0 +1,185 @@ +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' && } + + ))} + + + ))} + + + + + + + +
+ {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/eavesGable/EavesGableEdit.jsx b/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx new file mode 100644 index 00000000..1267fe98 --- /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() + 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 1609f5a0..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 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/outerlinesetting/Angle.jsx b/src/components/floor-plan/modal/lineTypes/Angle.jsx similarity index 100% rename from src/components/floor-plan/modal/outerlinesetting/Angle.jsx rename to src/components/floor-plan/modal/lineTypes/Angle.jsx diff --git a/src/components/floor-plan/modal/outerlinesetting/Diagonal.jsx b/src/components/floor-plan/modal/lineTypes/Diagonal.jsx similarity index 100% rename from src/components/floor-plan/modal/outerlinesetting/Diagonal.jsx rename to src/components/floor-plan/modal/lineTypes/Diagonal.jsx diff --git a/src/components/floor-plan/modal/outerlinesetting/DoublePitch.jsx b/src/components/floor-plan/modal/lineTypes/DoublePitch.jsx similarity index 100% rename from src/components/floor-plan/modal/outerlinesetting/DoublePitch.jsx rename to src/components/floor-plan/modal/lineTypes/DoublePitch.jsx diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/lineTypes/OuterLineWall.jsx similarity index 96% rename from src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx rename to src/components/floor-plan/modal/lineTypes/OuterLineWall.jsx index a3493f17..f469fba8 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/lineTypes/OuterLineWall.jsx @@ -11,7 +11,7 @@ export default function OuterLineWall({ props }) {
- {getMessage('modal.cover.outline.length')} + {getMessage('straight.line')}
+
+
+

{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..c1405e1d --- /dev/null +++ b/src/components/floor-plan/modal/object/ObjectSetting.jsx @@ -0,0 +1,49 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +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 [buttonAct, setButtonAct] = useState(1) + 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..1c79dc09 --- /dev/null +++ b/src/components/floor-plan/modal/object/type/OpenSpace.jsx @@ -0,0 +1,53 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function OpenSpace() { + const { getMessage } = useMessage() + return ( +
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
{getMessage('modal.object.setting.width')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.object.setting.height')}
+
+
+
+ +
+ mm +
+
+
+
+
+
+
+ + +
+
+ ) +} 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..bef52631 --- /dev/null +++ b/src/components/floor-plan/modal/object/type/Shadow.jsx @@ -0,0 +1,49 @@ +import { useMessage } from '@/hooks/useMessage' + +export default function Shadow() { + const { getMessage } = useMessage() + return ( +
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
{getMessage('modal.object.setting.width')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.object.setting.height')}
+
+
+
+ +
+ mm +
+
+
+
+
+
+
+ ) +} 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..8cfa55e4 --- /dev/null +++ b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx @@ -0,0 +1,81 @@ +import Image from 'next/image' +import { useMessage } from '@/hooks/useMessage' + +export default function TriangleDormer() { + 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('slope')}
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
方向の選択
+
+
+ {getMessage('commons.north')} + {getMessage('commons.east')} + {getMessage('commons.south')} + {getMessage('commons.west')} + + + + +
+
+
+ + ) +} diff --git a/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx index cd2973e7..248567e3 100644 --- a/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx @@ -9,7 +9,7 @@ export default function PropertiesSetting(props) { const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting() return ( - +

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

diff --git a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx index 8a9c1979..54bd6844 100644 --- a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx @@ -4,11 +4,11 @@ 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, setShowPropertiesSettingModal } = props @@ -109,7 +109,7 @@ export default function WallLineSetting(props) { } return ( - +

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

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..c705b0eb --- /dev/null +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx @@ -0,0 +1,155 @@ +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' + +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, + } = useOuterLineWall() + + 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) => ( + + ))} +
+
+
{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..d2c3022a --- /dev/null +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -0,0 +1,273 @@ +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' + +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 { applySurfaceShape } = useSurfaceShapeBatch() + + 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..d42f7fb2 --- /dev/null +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -0,0 +1,222 @@ +import { useMessage } from '@/hooks/useMessage' +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useState } from 'react' +import QSelectBox from '@/components/common/select/QSelectBox' + +export default function RoofAllocationSetting({ setShowRoofAllocationSettingModal }) { + const { getMessage } = useMessage() + const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(null) + const [values, setValues] = useState([ + { + id: '1', + type: 'A', + roofMaterial: { name: '기와1' }, + width: { name: '200' }, + length: { name: '250' }, + rafter: { name: '300' }, + alignType: 'stairs', + }, + ]) + + const roofMaterials = [ + { + id: 'A', + name: '기와1', + type: 'A', + width: '200', + length: '200', + alignType: 'parallel', + }, + { + id: 'B', + name: '기와2', + type: 'B', + rafter: '200', + alignType: 'parallel', + }, + { + id: 'C', + name: '기와3', + type: 'C', + hajebichi: '200', + alignType: 'stairs', + }, + { + id: 'D', + name: '기와4', + type: 'D', + length: '200', + alignType: 'stairs', + }, + ] + const widths = [ + { name: '200', id: 'q' }, + { name: '250', id: 'q1' }, + { name: '300', id: 'q2' }, + ] + const lengths = [ + { name: '200', id: 'w' }, + { name: '250', id: 'w1' }, + { name: '300', id: 'w2' }, + ] + const rafters = [ + { name: '200', id: 'e' }, + { name: '250', id: 'e1' }, + { name: '300', id: 'e2' }, + ] + + const onAddRoofMaterial = () => { + setValues([...values, selectedRoofMaterial]) + } + + const onDeleteRoofMaterial = (id) => { + setValues(values.filter((value) => value.id !== id)) + } + + return ( + +
+
+

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

+ +
+
+
{getMessage('modal.roof.alloc.info')}
+
+ {getMessage('modal.roof.alloc.select.roof.material')} +
+ setSelectedRoofMaterial(e)} /> +
+ +
+
+ {values.map((value, index) => ( +
+
+ + +
+
+
+
+
+ +
+ {index === 0 && 基本屋根材} + {index !== 0 && } +
+
+
+ {value.type === 'A' ? ( + <> +
+ W +
+ +
+
+
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : value.type === 'B' ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : value.type === 'C' ? ( + <> +
+ {getMessage('hajebichi')} +
+ +
+
+ + ) : value.type === 'D' ? ( + <> +
+ L +
+ +
+
+
+ {getMessage('modal.placement.initial.setting.rafter')} +
+ +
+
+ + ) : ( + '' + )} +
+
+
+ + +
+
+
+
+ ))} +
+
+ +
+
+
+
+ ) +} diff --git a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx new file mode 100644 index 00000000..ebdc6bb9 --- /dev/null +++ b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx @@ -0,0 +1,52 @@ +import { useState } from 'react' +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' + +export default function RoofShapePassivitySetting({ setShowRoofShapePassivitySettingModal }) { + const { getMessage } = useMessage() + const [buttonAct, setButtonAct] = useState(1) + const buttons = [ + { id: 1, name: getMessage('eaves') }, + { id: 2, name: getMessage('gable') }, + { id: 3, name: getMessage('windage') }, + ] + return ( + +
+
+

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

+ +
+
+
+ {buttons.map((button) => ( + + ))} +
+
+
{getMessage('setting')}
+
+ {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } +
+
+ + +
+
+
+ +
+
+
+
+ ) +} 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..f906a67e --- /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() + + 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..22e15a34 --- /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() { + 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..e2eb6342 --- /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() { + 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..dfdee92c --- /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() { + 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 263fc924..78511548 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -6,14 +6,21 @@ 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..fcd48af1 --- /dev/null +++ b/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx @@ -0,0 +1,60 @@ +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 } = + useWallLineOffsetSetting() + const [buttonAct, setButtonAct] = useState(1) + + 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..4f5c6ea7 --- /dev/null +++ b/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx @@ -0,0 +1,158 @@ +import { useMessage } from '@/hooks/useMessage' +import { useEffect, useState } from 'react' +import { useEvent } from '@/hooks/useEvent' + +export default function WallLine({ length1Ref, length2Ref, arrow1Ref, arrow2Ref, radioTypeRef, currentWallLineRef }) { + const { getMessage } = useMessage() + const { addDocumentEventListener, initEvent } = useEvent() + const [type, setType] = useState(1) + const [arrow1, setArrow1] = useState('up') + const [arrow2, setArrow2] = useState('up') + + useEffect(() => { + addDocumentEventListener('keydown', document, keyDown) + + return () => { + initEvent() + } + }, []) + + const onChange = (e) => { + setType(Number(e.target.value)) + radioTypeRef.current = e.target.value + } + + const handleBtnClick = (direction) => { + document.dispatchEvent(new KeyboardEvent('keydown', { key: direction })) + } + + const keyDown = (e) => { + if (currentWallLineRef.current === null) { + alert('보조선을 먼저 선택하세요') + return + } + + const key = e.key + + switch (key) { + case 'Down': // IE/Edge에서 사용되는 값 + case 'ArrowDown': { + if (radioTypeRef.current === '1') { + setArrow1('down') + arrow1Ref.current = 'down' + } else { + setArrow2('down') + arrow2Ref.current = 'down' + } + + break + } + case 'Up': // IE/Edge에서 사용되는 값 + case 'ArrowUp': + if (radioTypeRef.current === '1') { + setArrow1('up') + arrow1Ref.current = 'up' + } else { + setArrow2('up') + arrow2Ref.current = 'up' + } + break + case 'Left': // IE/Edge에서 사용되는 값 + case 'ArrowLeft': + if (radioTypeRef.current === '1') { + setArrow1('left') + arrow1Ref.current = 'left' + } else { + setArrow2('left') + arrow2Ref.current = 'left' + } + break + case 'Right': // IE/Edge에서 사용되는 값 + case 'ArrowRight': + if (radioTypeRef.current === '1') { + setArrow1('right') + arrow1Ref.current = 'right' + } else { + setArrow2('right') + arrow2Ref.current = 'right' + } + break + } + } + + 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..65da6051 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -124,7 +124,7 @@ export default function Header(props) { } return ( - !(pathName.includes('login') || pathName.includes('join')) && ( + !(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && (
diff --git a/src/components/main/ChangePasswordPop.jsx b/src/components/main/ChangePasswordPop.jsx new file mode 100644 index 00000000..45685c26 --- /dev/null +++ b/src/components/main/ChangePasswordPop.jsx @@ -0,0 +1,168 @@ +import React from 'react' +import { useMessage } from '@/hooks/useMessage' +import { useForm } from 'react-hook-form' +import { sessionStore } from '@/store/commonAtom' +import { useRecoilValue, useRecoilState } from 'recoil' +import { useAxios } from '@/hooks/useAxios' +import { globalLocaleStore } from '@/store/localeAtom' + +export default function ChangePasswordPop() { + const globalLocaleState = useRecoilValue(globalLocaleStore) + + const { patch } = useAxios(globalLocaleState) + const { getMessage } = useMessage() + const [sessionState, setSessionState] = useRecoilState(sessionStore) + + const formInitValue = { + password1: '', + password2: '', + } + const { register, setValue, getValues, handleSubmit, resetField, control, watch } = useForm({ + defaultValues: formInitValue, + }) + + const form = { register, setValue, getValues, handleSubmit, resetField, control, watch } + + //자리수체크 + const checkLength = (pwd1) => { + let str = new String(pwd1) + let _byte = 0 + if (str.length !== 0) { + for (let i = 0; i < str.length; i++) { + let str2 = str.charAt(i) + if (encodeURIComponent(str2).length > 4) { + _byte += 2 + } else { + _byte++ + } + } + } + return _byte + } + + //공백제거 + const checkValue = (e) => { + let spaceChk = /\s/ + if (spaceChk.exec(e.target.value)) { + e.target.value = e.target.value.replace(/\s|/gi, '') + return false + } + } + + //비밀번호 변경 + const updateProcess = async () => { + const _password1 = form.watch('password1') + const _password2 = form.watch('password2') + + if (_password1 !== _password2) { + alert(getMessage('main.popup.login.validate1')) + return false + } + + //패스워드 길이수 체크 + if (checkLength(_password1) > 10) { + alert(getMessage('main.popup.login.validate2')) + } + + const param = { + loginId: sessionState.userId, + chgType: 'I', + chgPwd: _password1, + } + await patch({ url: '/api/login/v1.0/user/change-password', data: param }).then((res) => { + if (res) { + if (res.result.resultCode === 'S') { + alert(getMessage('main.popup.login.success')) + setSessionState({ ...sessionState, pwdInitYn: 'Y' }) + } else { + alert(res.result.resultMsg) + } + } + }) + } + + return ( +
+
+
+
+

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

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

+ + {name} +

+ {num !== 4 && num !== 5 && ( + + )} +
+
{children}
+
+ ) +} diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 638126ee..02f44561 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -10,22 +10,29 @@ 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 '@/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 [gridCount, setGridCount] = 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,7 +52,6 @@ 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()}`) @@ -70,7 +76,6 @@ export default function Stuff() { headerCheckboxSelectionCurrentPageOnly: true, //페이징시 현재 페이지만 체크되도록 checkboxSelection: true, showDisabledCheckboxes: true, - // headerClass: 'centered', //_test.scss에 추가 테스트 // .centered { // .ag-header-cell-label { // justify-content: center !important; @@ -236,72 +241,121 @@ 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)) { + if (stuffSearchParams?.code === 'S') { + const params = { + schObjectNo: '', + schAddress: '', + schObjectName: '', + schSaleStoreName: '', + schReceiveUser: '', + schDispCompanyName: '', + schDateType: 'U', + schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), + schToDt: dayjs(new Date()).format('YYYY-MM-DD'), + startRow: (curPage - 1) * defaultSize + 1, + endRow: curPage * defaultSize, + schSelSaleStoreId: '', + schSortType: 'R', + } + + async function fetchData() { + //api에 넘길값 startRow, endRow + // let startRow + // let endRow + // startRow = (curPage - 1) * size + 1 + // endRow = curPage * size + // console.log('startrow::', startRow) + // console.log('endRow::', endRow) + + // let curPage + // let totalpage + // let totalCount + // let size + // let pageCount + + // console.log('화면진입 세션정보::::::::::', sessionState) + // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` + // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}` + const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}` + + await get({ + url: apiUrl, + }).then((res) => { + if (!isEmptyArray(res)) { + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setGridCount(res[0].totCnt) + } + }) + } + fetchData() + } else { + const params = { + schObjectNo: '', + schAddress: '', + schObjectName: '', + schSaleStoreName: '', + schReceiveUser: '', + schDispCompanyName: '', + schDateType: 'U', + schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), + schToDt: dayjs(new Date()).format('YYYY-MM-DD'), + startRow: (curPage - 1) * defaultSize + 1, + endRow: curPage * defaultSize, + schSelSaleStoreId: '', + schSortType: 'R', + } + + async function fetchData() { + //api에 넘길값 startRow, endRow + // let startRow + // let endRow + // startRow = (curPage - 1) * size + 1 + // endRow = curPage * size + // console.log('startrow::', startRow) + // console.log('endRow::', endRow) + + // let curPage + // let totalpage + // let totalCount + // let size + // let pageCount + + // console.log('화면진입 세션정보::::::::::', sessionState) + // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` + // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}` + const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}` + + await get({ + url: apiUrl, + }).then((res) => { + if (!isEmptyArray(res)) { + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setGridCount(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() } - }, []) + }, [sessionState]) useEffect(() => { if (stuffSearchParams?.code === 'E') { + //console.log('조회누름::::::::', stuffSearchParams) stuffSearchParams.startRow = (curPage - 1) * defaultSize + 1 stuffSearchParams.endRow = curPage * defaultSize stuffSearchParams.schSortType = defaultSortType - console.log('조회 눌럿을때 ::::::::::::::', stuffSearchParams) async function fetchData() { + // console.log('조회누름 세션정보:::::::::::::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` + const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}` await get({ url: apiUrl }).then((res) => { - console.log('API결과:::::::', 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 }) + setGridCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) setGridCount(0) @@ -324,15 +378,15 @@ export default function Stuff() { startRow: startRow, endRow: curPage * e.target.value, }) - console.log('셋팅된 검색조건:::', stuffSearchParams) - //조회API호출 + // console.log('페이지 갯수 변경 때 셋팅된 검색조건:::', stuffSearchParams) + // console.log('페이지 갯수 변경 때 sessionState:::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` + // const apiUrl = `/api/object/list?saleStoreId=X167&${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 }) + setGridCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) setGridCount(0) @@ -343,27 +397,36 @@ export default function Stuff() { //최근 등록일 수정일 정렬 이벤트 const onChangeSortType = (e) => { stuffSearchParams.schSortType = e.target.value - console.log('셋팅된 검색조건:::', stuffSearchParams) + // console.log('셋팅된 검색조건:::', stuffSearchParams) setDefaultSortType(e.target.value) setStuffSearch({ ...stuffSearch, code: 'S', schSortType: e.target.value, }) + // console.log('정렬 변경시 세션정보::::::::::::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` - const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` - // console.log('apiUrl::', apiUrl) + // const apiUrl = `/api/object/list?saleStoreId=X167&${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 }) + setGridCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) setGridCount(0) } }) } + + useEffect(() => { + if (globalLocaleState === 'ko') { + setAppMessageState(KO) + } else { + setAppMessageState(JA) + } + }, [globalLocaleState]) + return ( <> {/* 퍼블시작 */} @@ -374,11 +437,11 @@ export default function Stuff() {
  • 전체 - {gridCount} + {convertNumberToPriceDecimal(gridCount)}
  • 선택 - {selectedRowDataCount} + {convertNumberToPriceDecimal(selectedRowDataCount)}
diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 898b4176..bca2fd17 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -2,15 +2,15 @@ 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 { Button } from '@nextui-org/react' +import Select from 'react-dropdown-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 { useMessage } from '@/hooks/useMessage' import { useForm } from 'react-hook-form' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilValue } from 'recoil' export default function StuffDetail() { const router = useRouter() const searchParams = useSearchParams() @@ -34,14 +34,15 @@ export default function StuffDetail() { prefId: '', //도도부현 prefName: '', address: '', //주소 - powerSimArea: '', //발전량시뮬레이션지역 + areaId: '', //발전량시뮬레이션지역id + // areaName: '', //발전량시뮬레이션지역명 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) } @@ -56,8 +57,9 @@ export default function StuffDetail() { const [saleStoreList, setSaleStoreList] = useState([]) // 판매점 리스트 const [otherSaleStoreList, setOtherSaleStoreList] = useState([]) - const [powerSimAreaList, setPowerSimAreaList] = useState([]) //발전시뮬레이션 리스트 + const [areaIdList, setAreaIdList] = useState([]) //발전시뮬레이션 리스트 + const [windSpeedList, setWindSpeedList] = useState([]) //기준풍속 리스트 const [isFormValid, setIsFormValid] = useState(false) //임시저장, 진짜저장 버튼 컨트롤 const [buttonValid, setButtonValid] = useState(false) //주소검색 활성화 컨트롤 const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set @@ -77,14 +79,13 @@ export default function StuffDetail() { get({ url: `/api/object/${objectNo}/detail` }).then((res) => { // 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) + // console.log('도도부현API 결과:::', res) setPrefCodeList(res) } }) @@ -106,12 +107,11 @@ export default function StuffDetail() { } }) } 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) } }) @@ -121,11 +121,11 @@ export default function StuffDetail() { //1차점 : X167 get({ url: `/api/object/saleStore/X167/list` }).then((res) => { if (!isEmptyArray(res)) { - console.log('판매점 결과:::::', 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) + // console.log('first:::::', firstList) + // console.log('otherList:::::', otherList) //1차점 셀렉트박스 setSaleStoreList(firstList) //1차 판매점 자동완성 값 셋팅 @@ -135,6 +135,8 @@ export default function StuffDetail() { //1차점 아닌 판매점 셀렉트박스 setOtherSaleStoreList(otherList) + form.setValue('otherSaleStoreId', otherList[0].saleStoreId) + form.setValue('otherSaleStoreName', otherList[0].saleStoreId) } }) } @@ -146,14 +148,17 @@ export default function StuffDetail() { form.setValue('saleStoreId', '') form.setValue('saleStoreName', '') } else { - form.setValue('saleStoreId', key) - form.setValue('saleStoreName', key) + const name = saleStoreList.find((obj) => obj.saleStoreId === key.target.value).saleStoreName + form.setValue('saleStoreId', key.target.value) + form.setValue('saleStoreName', name) } } //2차점 변경 이벤트 const onSelectionChange2 = (key) => { - console.log(key) + const name = otherSaleStoreList.find((obj) => obj.saleStoreId === key.target.value).saleStoreName + form.setValue('otherSaleStoreId', key.target.value) + form.setValue('otherSaleStoreNm', name) } // 우편번호 숫자만 체크 const _zipNo = watch('zipNo') @@ -173,26 +178,28 @@ 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 _otherSaleStoreId = watch('otherSaleStoreId') 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') { @@ -212,6 +219,10 @@ export default function StuffDetail() { errors.saleStoreId = true } + // if (!_otherSaleStoreId) { + // errors.otherSaleStoreId = true + // } + if (!_zipNo || _zipNo.length != 7) { errors.zipCode = true } @@ -224,16 +235,16 @@ export default function StuffDetail() { errors.address = true } - if (!_powerSimArea) { - errors.powerSimArea = true + if (!_areaId) { + errors.areaId = true } if (!_windSpeed) { errors.windSpeed = true } - if (!_snowCover) { - errors.snowCover = true + if (!_verticalSnowCover) { + errors.verticalSnowCover = true } if (!_installHeight) { @@ -245,19 +256,34 @@ export default function StuffDetail() { } else { // console.log('상세일때 폼체크') } - }, [_dispCompanyName, _objectName, _objectNameOmit, _saleStoreId, _zipNo, _prefId, _address, _powerSimArea, _windSpeed, _snowCover, _installHeight]) + }, [ + _dispCompanyName, + _objectName, + _objectNameOmit, + _saleStoreId, + // _otherSaleStoreId, + _zipNo, + _prefId, + _address, + _areaId, + _windSpeed, + _verticalSnowCover, + _installHeight, + ]) // 주소검색 API const onSearchPostNumber = () => { const params = { zipcode: _zipNo, } + get({ url: `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter(params)}` }).then((res) => { //7830060 //9302226 + //0790177 3개짜리 if (res.status === 200) { if (res.results != null) { - // console.log('주소검색::', res.results) + 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) @@ -271,8 +297,11 @@ export default function StuffDetail() { form.setValue('address', '') form.setValue('zipNo', '') setPrefValue('') - setPowerSimAreaList([]) - form.setValue('powerSimArea', '') + setAreaIdList([]) + form.setValue('areaId', '') + // form.setValue('areaName', '') + setWindSpeedList([]) + form.setValue('windSpeed', '') } } else { alert(res.message) @@ -282,18 +311,39 @@ export default function StuffDetail() { 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].prefId) + form.setValue('areaName', res[0].prefName) + setAreaIdList(res) } }) } }, [prefValue]) + // 발전량 시뮬레이션 변경 + const handleAreaIdOnChange = (e) => { + form.setValue('areaId', e.target.value) + } + + useEffect(() => { + if (!isEmptyArray(areaIdList)) { + //도도부현넘기는지 발전량시뮬레이션지역 넘기는지 ->도도부현넘기기 + console.log('prefName::', form.watch('prefName')) + let _prefName = form.watch('prefName') + //http://localhost:8080/api/object/windSpeed/兵庫県/list + get({ url: `/api/object/windSpeed/${_prefName}/list` }).then((res) => { + if (!isEmptyArray(res)) { + // console.log('기준풍속결과:::::::::', res) + setWindSpeedList(res) + } + }) + } + }, [areaIdList]) + //필수값 다 입력했을때 const onValid = (data) => { // 수정모드일때는 PUT @@ -307,7 +357,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 +365,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,7 +378,6 @@ export default function StuffDetail() { // 임시저장 const onTempSave = async () => { const formData = form.getValues() - //console.log('임시저장::::::::', formData) const params = { saleStoreId: formData.saleStoreId, @@ -341,15 +390,15 @@ 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, @@ -361,13 +410,6 @@ export default function StuffDetail() { }) } - // 발전량 시뮬레이션 변경 - const handlePowerSimAreaOnChange = (e) => { - // console.log('가지고있는 도도부현코드:::::::::', prefValue) - // console.log('발전량시뮬레이션변경:::::::::', e.target.value) - //값 set해주고 그거 useEffect로 api호출 - } - // 물건삭제 const onDelete = () => { //http://localhost:8080/api/object/R201TES01240910023 @@ -426,7 +468,7 @@ export default function StuffDetail() {
- @@ -457,16 +499,20 @@ export default function StuffDetail() {
- + {saleStoreList?.length > 0 && ( + + )}
- +
@@ -474,20 +520,34 @@ export default function StuffDetail() {
-
- 2차 판매점명 / ID * -
+
2차 판매점명 / ID
- + {otherSaleStoreList?.length > 0 && ( + + )} +
+
+
-
-
-
@@ -522,6 +582,7 @@ export default function StuffDetail() {
+ {/* {prefCodeList?.length > 0 && ( )} */} + {/* {prefCodeList?.length > 0 && ( + + )} */}
@@ -541,7 +607,24 @@ export default function StuffDetail() { 발전량시뮬레이션지역 * -
+
+ +
@@ -552,13 +635,17 @@ export default function StuffDetail() {
m/s이하 +
@@ -568,11 +655,17 @@ export default function StuffDetail() {
-
+
+ +
cm
- - + +
@@ -592,8 +685,8 @@ export default function StuffDetail() {
- - + +
@@ -622,12 +715,12 @@ export default function StuffDetail() {
- - + +
- - + +
@@ -691,233 +784,6 @@ export default function StuffDetail() { )} )} - {/* {(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) - }} - > - 염해지역용아이템사용 - -
-
- -
- -
-
-
- - - - - -
-
- -