
--- client/resources/css/common.css
+++ client/resources/css/common.css
... | ... | @@ -10,8 +10,8 @@ |
10 | 10 |
.main-grid-guardian{ |
11 | 11 |
height: 100%; |
12 | 12 |
display: grid; |
13 |
- grid-template-columns: 0.9fr 0.9fr 1.1fr 1.1fr; |
|
14 |
- grid-template-rows: 0.5fr 0.1fr; |
|
13 |
+ grid-template-columns: 0.9fr 0.9fr; |
|
14 |
+ grid-template-rows: 0.1fr 0.5fr 0.5fr; |
|
15 | 15 |
gap: 1rem; |
16 | 16 |
} |
17 | 17 |
.main-grid-government { |
... | ... | @@ -19,13 +19,6 @@ |
19 | 19 |
display: grid; |
20 | 20 |
grid-template-columns: 1fr 1fr 1fr 1fr; |
21 | 21 |
grid-template-rows: 0.1fr 0.5fr 0.3fr 0.3fr 0.3fr; |
22 |
- gap: 1rem; |
|
23 |
-} |
|
24 |
-.main-grid-agency { |
|
25 |
- height: 100%; |
|
26 |
- display: grid; |
|
27 |
- grid-template-columns: 1fr 1fr 1fr 1fr; |
|
28 |
- grid-template-rows: 0.1fr 0.5fr 0.5fr 0.5fr 0.5fr 0.5fr 0.5fr; |
|
29 | 22 |
gap: 1rem; |
30 | 23 |
} |
31 | 24 |
.main-grid-government-2 { |
... | ... | @@ -47,7 +40,7 @@ |
47 | 40 |
.statistics-grid{ |
48 | 41 |
display: grid; |
49 | 42 |
grid-template-columns: 1fr 1fr; |
50 |
- grid-template-rows: 1fr 1fr 1fr; |
|
43 |
+ grid-template-rows: 1fr 1fr; |
|
51 | 44 |
gap: 2rem; |
52 | 45 |
} |
53 | 46 |
|
... | ... | @@ -55,14 +48,8 @@ |
55 | 48 |
.combine-left { |
56 | 49 |
grid-column: 1/3; |
57 | 50 |
} |
58 |
-.combine-left2 { |
|
59 |
- grid-column: 1/2; |
|
60 |
-} |
|
61 | 51 |
|
62 | 52 |
.combine-left-government { |
63 |
- grid-column: 2/4; |
|
64 |
-} |
|
65 |
-.combine-left-government2 { |
|
66 | 53 |
grid-column: 1/4; |
67 | 54 |
} |
68 | 55 |
|
... | ... | @@ -71,9 +58,6 @@ |
71 | 58 |
} |
72 | 59 |
.combine-right2 { |
73 | 60 |
grid-column: 3/5; |
74 |
-} |
|
75 |
-.combine-right3 { |
|
76 |
- grid-column: 2/3; |
|
77 | 61 |
} |
78 | 62 |
|
79 | 63 |
.combine-right-government { |
... | ... | @@ -91,6 +75,9 @@ |
91 | 75 |
.combine-all-government { |
92 | 76 |
grid-row: 1/2; |
93 | 77 |
} |
78 |
+.combine-all-government2 { |
|
79 |
+ grid-row: 1/4; |
|
80 |
+} |
|
94 | 81 |
.combine-middle-government { |
95 | 82 |
grid-row: 2/4; |
96 | 83 |
} |
... | ... | @@ -101,18 +88,6 @@ |
101 | 88 |
|
102 | 89 |
.combine-bottom-government2 { |
103 | 90 |
grid-row: 2/5; |
104 |
-} |
|
105 |
-.combine-bottom-government3 { |
|
106 |
- grid-row: 3/4; |
|
107 |
-} |
|
108 |
-.combine-bottom-government5 { |
|
109 |
- grid-row: 5/8; |
|
110 |
-} |
|
111 |
-.combine-bottom-government6 { |
|
112 |
- grid-row: 4/6; |
|
113 |
-} |
|
114 |
-.combine-bottom-government7 { |
|
115 |
- grid-row: 6/8; |
|
116 | 91 |
} |
117 | 92 |
|
118 | 93 |
|
... | ... | @@ -242,11 +217,9 @@ |
242 | 217 |
.content-box { |
243 | 218 |
padding: 1.5rem; |
244 | 219 |
border-radius: 0.5rem; |
245 |
- border: 1px solid #eeeeee; |
|
246 |
- background: #ffffff; |
|
247 |
- box-shadow: 1px 1px 5px 2px rgba(238, 238, 238, 0.5); |
|
220 |
+ background-color: rgb(255, 255, 255); |
|
248 | 221 |
} |
249 |
-.main-main{background: #f0ebe352;} |
|
222 |
+ |
|
250 | 223 |
/*체크박스 크기*/ |
251 | 224 |
.checkCon { |
252 | 225 |
width: 50%; |
... | ... | @@ -328,6 +301,3 @@ |
328 | 301 |
|
329 | 302 |
hr{border-top: 1px solid #d1e4e3; margin-top: 2rem} |
330 | 303 |
|
331 |
-/* background */ |
|
332 |
-.bg-1{background-image: linear-gradient(to right top, #fff1eb 0%, #f3f6f7 100%);} |
|
333 |
-.bg-2{background-image: linear-gradient(to left top, #f1f7fa 0%, #fff1eb 100%);}(No newline at end of file) |
--- client/resources/css/layout.css
+++ client/resources/css/layout.css
... | ... | @@ -127,8 +127,8 @@ |
127 | 127 |
max-width: 100%; |
128 | 128 |
height: 100%; |
129 | 129 |
padding: 4rem; |
130 |
+ background-color: #e6e5e5; |
|
130 | 131 |
grid-area: main; |
131 |
- box-shadow: 1px 1px 20px 1px rgba(238, 238, 238, 0.5) inset; |
|
132 | 132 |
} |
133 | 133 |
|
134 | 134 |
|
--- client/resources/css/main.css
+++ client/resources/css/main.css
... | ... | @@ -13,11 +13,102 @@ |
13 | 13 |
display: none; |
14 | 14 |
} |
15 | 15 |
|
16 |
-.join-btn{ |
|
16 |
+.join-btn { |
|
17 | 17 |
background-color: transparent; |
18 | 18 |
} |
19 |
+ |
|
20 |
+/* -----------------------------------------------보호자 */ |
|
21 |
+.guardian-table { |
|
22 |
+ width: 100%; |
|
23 |
+} |
|
24 |
+ |
|
25 |
+.guardian-table th { |
|
26 |
+ background: none; |
|
27 |
+} |
|
28 |
+.guardian-table td { |
|
29 |
+ border: 0; |
|
30 |
+} |
|
31 |
+ |
|
32 |
+.guardian-table { |
|
33 |
+ border: 0; |
|
34 |
+} |
|
35 |
+ |
|
36 |
+.guardian-table-inner { |
|
37 |
+ width: 100%; |
|
38 |
+} |
|
39 |
+ |
|
40 |
+.guardian-table-text { |
|
41 |
+ width: 20%; |
|
42 |
+ border-right: 3px solid #7D9D9C; |
|
43 |
+ font-size: 1.8rem; |
|
44 |
+ font-weight: bold; |
|
45 |
+ margin-right: 2rem; |
|
46 |
+} |
|
47 |
+.guardian-table1 { |
|
48 |
+ width: 100%; |
|
49 |
+} |
|
50 |
+ |
|
51 |
+.guardian-table1 th { |
|
52 |
+ background: none; |
|
53 |
+ font-size: 1.9rem; |
|
54 |
+} |
|
55 |
+.guardian-table1 th:nth-child(1){ |
|
56 |
+ background: #f48d8d; |
|
57 |
+ border: 6px solid rgba(255, 254, 254, 0.5); |
|
58 |
+} |
|
59 |
+.guardian-table1 th:nth-child(2){ |
|
60 |
+ background: #efa33a; |
|
61 |
+ border: 6px solid rgba(255, 254, 254, 0.5); |
|
62 |
+} |
|
63 |
+.guardian-table1 th:nth-child(3){ |
|
64 |
+ background: #eeeb3c; |
|
65 |
+ border: 6px solid rgba(255, 254, 254, 0.5); |
|
66 |
+} |
|
67 |
+.guardian-table1 th:nth-child(4){ |
|
68 |
+ background: #9be32e; |
|
69 |
+ border: 6px solid rgba(255, 254, 254, 0.5); |
|
70 |
+} |
|
71 |
+.guardian-table1 th:nth-child(5){ |
|
72 |
+ background: #9fa6f2; |
|
73 |
+ border: 6px solid rgba(255, 254, 254, 0.5); |
|
74 |
+} |
|
75 |
+.guardian-table1 th:nth-child(6){ |
|
76 |
+ background: #b089ed; |
|
77 |
+ border: 6px solid rgba(255, 254, 254, 0.5); |
|
78 |
+} |
|
79 |
+.guardian-table1 th:nth-child(7){ |
|
80 |
+ background: #e057f0; |
|
81 |
+ border: 6px solid rgba(255, 254, 254, 0.5); |
|
82 |
+} |
|
83 |
+.guardian-table1 td { |
|
84 |
+ border: 0; |
|
85 |
+} |
|
86 |
+ |
|
87 |
+.guardian-table1 { |
|
88 |
+ border: 0; |
|
89 |
+} |
|
90 |
+ |
|
91 |
+.guardian-table-inner { |
|
92 |
+ width: 100%; |
|
93 |
+} |
|
94 |
+ |
|
95 |
+.guardian-table-text { |
|
96 |
+ width: 20%; |
|
97 |
+ border-right: 3px solid #7D9D9C; |
|
98 |
+ font-size: 1.8rem; |
|
99 |
+ font-weight: bold; |
|
100 |
+ margin-right: 2rem; |
|
101 |
+} |
|
102 |
+.red{color: red;} |
|
103 |
+ |
|
19 | 104 |
/* -----------------------------------------------지자체 */ |
20 |
-.react-calendar{width: 100%;} |
|
105 |
+.react-calendar { |
|
106 |
+ width: 100%; |
|
107 |
+ height: 77%; |
|
108 |
+ border: 0; |
|
109 |
+ border-radius: 10px; |
|
110 |
+} |
|
111 |
+ |
|
21 | 112 |
.map { |
22 | 113 |
width: 100%; |
23 | 114 |
height: calc(100% - 31px); |
... | ... | @@ -26,16 +117,69 @@ |
26 | 117 |
align-items: center; |
27 | 118 |
} |
28 | 119 |
|
120 |
+.main-grid-guardian .statistics li { |
|
121 |
+ padding: 1rem 3rem; |
|
122 |
+ background: rgba(255, 254, 254, 0.5); |
|
123 |
+ border-radius: 10px; |
|
124 |
+ margin: 0 auto; |
|
125 |
+ margin-bottom: 1rem; |
|
126 |
+} |
|
127 |
+ |
|
128 |
+.main-grid-guardian .statistics li p { |
|
129 |
+ padding: 0 2rem; |
|
130 |
+} |
|
131 |
+ |
|
132 |
+.main-grid-guardian .statistics li:nth-child(2), |
|
133 |
+.main-grid-guardian .statistics li:nth-child(3), |
|
134 |
+.main-grid-guardian .statistics li:nth-child(4), |
|
135 |
+.main-grid-guardian .statistics li:nth-child(5), |
|
136 |
+.main-grid-guardian .statistics li:nth-child(6), |
|
137 |
+.main-grid-guardian .statistics li:nth-child(7) { |
|
138 |
+ background: rgba(255, 254, 254, 0.5); |
|
139 |
+} |
|
140 |
+ |
|
141 |
+.main-grid-guardian .statistics li p:nth-child(3) { |
|
142 |
+ font-size: 1.5rem; |
|
143 |
+} |
|
144 |
+ |
|
145 |
+.main-grid-guardian .statistics li p:nth-of-type(1) { |
|
146 |
+ position: inherit; |
|
147 |
+ font-size: 1.5rem; |
|
148 |
+ font-weight: bold; |
|
149 |
+} |
|
150 |
+ |
|
151 |
+.main-grid-guardian .statistics li p:nth-of-type(2) { |
|
152 |
+ padding: 0; |
|
153 |
+ font-size: 2rem; |
|
154 |
+} |
|
155 |
+ |
|
29 | 156 |
.statistics { |
30 | 157 |
border: 1px solid #eeeeee; |
31 | 158 |
border-radius: 5px; |
32 | 159 |
padding: 1rem; |
33 | 160 |
} |
34 | 161 |
|
162 |
+ |
|
35 | 163 |
.statistics li { |
36 | 164 |
position: relative; |
37 | 165 |
padding-left: 5rem; |
38 | 166 |
text-align: center; |
167 |
+} |
|
168 |
+ |
|
169 |
+.statistics:nth-child(1) { |
|
170 |
+ background: #fbe4e4; |
|
171 |
+} |
|
172 |
+ |
|
173 |
+.statistics:nth-child(2) { |
|
174 |
+ background: #edf7df; |
|
175 |
+} |
|
176 |
+ |
|
177 |
+.statistics:nth-child(3) { |
|
178 |
+ background: #f9f7e0; |
|
179 |
+} |
|
180 |
+ |
|
181 |
+.statistics:nth-child(4) { |
|
182 |
+ background: #e9e7fe; |
|
39 | 183 |
} |
40 | 184 |
|
41 | 185 |
.statistics li p:nth-of-type(1) { |
... | ... | @@ -48,14 +192,12 @@ |
48 | 192 |
font-size: 1.6rem; |
49 | 193 |
font-weight: bold; |
50 | 194 |
} |
195 |
+ |
|
51 | 196 |
.statistics li p:nth-of-type(3) { |
52 | 197 |
font-size: 1.6rem; |
53 | 198 |
font-weight: bold; |
54 | 199 |
} |
55 | 200 |
|
56 |
-.statistics li p:nth-of-type(3)::after { |
|
57 |
- content: "명"; |
|
58 |
-} |
|
59 | 201 |
|
60 | 202 |
.main-battery-title span::after { |
61 | 203 |
content: " 님의"; |
... | ... | @@ -67,7 +209,11 @@ |
67 | 209 |
font-size: 1.6rem; |
68 | 210 |
font-weight: 900; |
69 | 211 |
} |
70 |
-.main-battery-title p{padding-right: 1rem;} |
|
212 |
+ |
|
213 |
+.main-battery-title p { |
|
214 |
+ padding-right: 1rem; |
|
215 |
+} |
|
216 |
+ |
|
71 | 217 |
.map svg { |
72 | 218 |
display: block; |
73 | 219 |
} |
... | ... | @@ -79,11 +225,13 @@ |
79 | 225 |
text-align: center; |
80 | 226 |
padding-right: 1rem; |
81 | 227 |
} |
228 |
+ |
|
82 | 229 |
.temp::after { |
83 | 230 |
content: " 입니다."; |
84 | 231 |
font-size: 1.6rem; |
85 | 232 |
font-weight: 500; |
86 | 233 |
} |
234 |
+ |
|
87 | 235 |
.battery p { |
88 | 236 |
font-size: 3rem; |
89 | 237 |
font-weight: bold; |
... | ... | @@ -186,11 +334,13 @@ |
186 | 334 |
max-height: 100%; |
187 | 335 |
background-color: #f8f8f8; |
188 | 336 |
} |
189 |
-.login-wrap .tab-container{ |
|
337 |
+ |
|
338 |
+.login-wrap .tab-container { |
|
190 | 339 |
width: 50%; |
191 | 340 |
margin: auto; |
192 | 341 |
padding-top: 10rem; |
193 | 342 |
} |
343 |
+ |
|
194 | 344 |
.login-wrap h1 { |
195 | 345 |
max-width: 100%; |
196 | 346 |
text-align: center; |
... | ... | @@ -210,6 +360,16 @@ |
210 | 360 |
text-align: center; |
211 | 361 |
} |
212 | 362 |
|
363 |
+.login-form-guardian { |
|
364 |
+ padding: 3rem; |
|
365 |
+ background: #ffffff; |
|
366 |
+} |
|
367 |
+ |
|
368 |
+.login-form-guardian h3 { |
|
369 |
+ font-size: 2.4rem; |
|
370 |
+ margin-bottom: 2rem; |
|
371 |
+} |
|
372 |
+ |
|
213 | 373 |
.login-form { |
214 | 374 |
position: relative; |
215 | 375 |
width: 500px; |
... | ... | @@ -218,6 +378,7 @@ |
218 | 378 |
background-color: #ffffff; |
219 | 379 |
border-radius: 1rem; |
220 | 380 |
} |
381 |
+ |
|
221 | 382 |
.login-form .login-inner { |
222 | 383 |
margin-bottom: 2rem; |
223 | 384 |
position: absolute; |
... | ... | @@ -251,43 +412,21 @@ |
251 | 412 |
height: calc(100% - 92px); |
252 | 413 |
} |
253 | 414 |
|
415 |
+.login-select { |
|
416 |
+ width: 20%; |
|
417 |
+ height: 20%; |
|
418 |
+ background: #ffffff; |
|
419 |
+ padding: 5rem; |
|
420 |
+ margin-right: 2rem; |
|
421 |
+ box-shadow: 1px 1px 5px 1px rgba(0, 0, 0, 0.2); |
|
422 |
+ cursor: pointer; |
|
254 | 423 |
|
255 |
-.login-form-management h3 { |
|
424 |
+} |
|
425 |
+ |
|
426 |
+.login-select h3 { |
|
256 | 427 |
font-size: 2rem; |
257 |
- text-align: center; |
|
258 |
- margin-bottom: 2rem; |
|
259 | 428 |
} |
260 | 429 |
|
261 |
-.login-form-management { |
|
262 |
- width: 500px; |
|
263 |
- padding: 5rem 3rem; |
|
264 |
- margin: auto; |
|
265 |
- background-color: #ffffff; |
|
266 |
- border-radius: 1rem; |
|
267 |
-} |
|
268 |
- |
|
269 |
-.login-form-management .login-inner { |
|
270 |
- margin-bottom: 2rem; |
|
271 |
-} |
|
272 |
- |
|
273 |
-.login-form-management .login-inner .content { |
|
274 |
- width: 100%; |
|
275 |
- margin-bottom: 1rem; |
|
276 |
-} |
|
277 |
- |
|
278 |
-.login-form-management .login-inner .fa-solid { |
|
279 |
- font-size: 2rem; |
|
280 |
- margin-bottom: 1rem; |
|
281 |
- color: #eee; |
|
282 |
-} |
|
283 |
- |
|
284 |
-.login-form-management .login-inner input { |
|
285 |
- outline: none; |
|
286 |
- border: 0; |
|
287 |
- margin-bottom: 1rem; |
|
288 |
- padding: 1.5rem; |
|
289 |
- background: #eee; |
|
290 |
-} |
|
291 | 430 |
|
292 | 431 |
/* ------------------------------------- 회원가입 page --------------------------------- */ |
293 | 432 |
.join-group { |
... | ... | @@ -346,7 +485,6 @@ |
346 | 485 |
} |
347 | 486 |
|
348 | 487 |
.search-group .btn-box { |
349 |
- margin-top: 2rem; |
|
350 | 488 |
padding-bottom: 0.5rem; |
351 | 489 |
} |
352 | 490 |
|
... | ... | @@ -652,11 +790,8 @@ |
652 | 790 |
} |
653 | 791 |
|
654 | 792 |
/* 장비등록 */ |
655 |
-.equipment-insert input[type="checkbox" i]{ |
|
656 |
- width: 10%; |
|
657 |
-} |
|
658 |
-.equipment-insert label{width: 30%;} |
|
659 |
-.user-list{ |
|
793 |
+ |
|
794 |
+.user-list { |
|
660 | 795 |
background-color: #eeeeee; |
661 | 796 |
height: 57.8vh; |
662 | 797 |
} |
... | ... | @@ -707,7 +842,10 @@ |
707 | 842 |
} |
708 | 843 |
|
709 | 844 |
/* 사용자 관리 */ |
710 |
-.tab-menu-mobile{display: none;} |
|
845 |
+.tab-menu-mobile { |
|
846 |
+ display: none; |
|
847 |
+} |
|
848 |
+ |
|
711 | 849 |
.tab-menu { |
712 | 850 |
display: flex; |
713 | 851 |
} |
... | ... | @@ -722,7 +860,7 @@ |
722 | 860 |
border: 1px solid #eeeeee; |
723 | 861 |
} |
724 | 862 |
|
725 |
-.tab-menu li.active { |
|
863 |
+.tab-menu li.active { |
|
726 | 864 |
font-weight: bold; |
727 | 865 |
background-color: #242d2e; |
728 | 866 |
color: #ffffff; |
... | ... | @@ -747,14 +885,17 @@ |
747 | 885 |
color: #7D9D9C; |
748 | 886 |
} |
749 | 887 |
|
750 |
-.tab-container{ |
|
751 |
-} |
|
888 |
+.tab-container {} |
|
889 |
+ |
|
752 | 890 |
.tab-container>div>div:nth-child(2) { |
753 | 891 |
margin: 1rem 0; |
754 | 892 |
} |
755 | 893 |
|
756 | 894 |
/* 권한 설정 */ |
757 |
-.authority-table-mobile{display: none;} |
|
895 |
+.authority-table-mobile { |
|
896 |
+ display: none; |
|
897 |
+} |
|
898 |
+ |
|
758 | 899 |
.authority-table-pc th, |
759 | 900 |
.authority-table-pc td { |
760 | 901 |
padding: 1.5rem; |
... | ... | @@ -786,6 +927,6 @@ |
786 | 927 |
} |
787 | 928 |
} |
788 | 929 |
|
789 |
-.mobile{ |
|
930 |
+.mobile { |
|
790 | 931 |
display: none; |
791 | 932 |
}(No newline at end of file) |
+++ client/resources/files/images/login-img.png
Binary file is not shown |
--- client/views/component/DetailSearch.jsx
+++ client/views/component/DetailSearch.jsx
... | ... | @@ -199,7 +199,7 @@ |
199 | 199 |
<td colSpan={3}> |
200 | 200 |
<div className="flex"> |
201 | 201 |
<select name="" id=""> |
202 |
- <option value="">사용자등록번호</option> |
|
202 |
+ <option value="">구분</option> |
|
203 | 203 |
<option value="">어르신 성함</option> |
204 | 204 |
<option value="">보호사 성함</option> |
205 | 205 |
</select> |
--- client/views/component/Table.jsx
+++ client/views/component/Table.jsx
... | ... | @@ -51,6 +51,6 @@ |
51 | 51 |
// padding: 1rem 0; |
52 | 52 |
// border-top: 1px solid #ececec; |
53 | 53 |
// text-align: center; |
54 |
-// font-size: 1.3rem; |
|
54 |
+// font-size: 1.6rem; |
|
55 | 55 |
// background-color: #ffffff; |
56 | 56 |
// `; |
--- client/views/component/chart/Chart.jsx
+++ client/views/component/chart/Chart.jsx
... | ... | @@ -5,174 +5,104 @@ |
5 | 5 |
|
6 | 6 |
class Chart extends Component { |
7 | 7 |
componentDidMount() { |
8 |
- let root = am5.Root.new("chart"); |
|
8 |
+ let root5 = am5.Root.new("chart"); |
|
9 | 9 |
|
10 | 10 |
|
11 |
- root._logo.dispose(); |
|
11 |
+ root5._logo.dispose(); |
|
12 | 12 |
// Set themes |
13 | 13 |
// https://www.amcharts.com/docs/v5/concepts/themes/ |
14 |
-root.setThemes([ |
|
15 |
- am5themes_Animated.new(root) |
|
14 |
+root5.setThemes([ |
|
15 |
+ am5themes_Animated.new(root5) |
|
16 | 16 |
]); |
17 | 17 |
|
18 | 18 |
|
19 | 19 |
// Create chart |
20 | 20 |
// https://www.amcharts.com/docs/v5/charts/xy-chart/ |
21 |
-let chart = root.container.children.push( |
|
22 |
- am5xy.XYChart.new(root, { |
|
23 |
- panX: false, |
|
24 |
- panY: false, |
|
25 |
- wheelX: "panX", |
|
26 |
- wheelY: "zoomX", |
|
27 |
- layout: root.verticalLayout |
|
28 |
- }) |
|
29 |
-); |
|
21 |
+let chart = root5.container.children.push(am5xy.XYChart.new(root5, { |
|
22 |
+ panX: true, |
|
23 |
+ panY: true, |
|
24 |
+ wheelX: "panX", |
|
25 |
+ wheelY: "zoomX", |
|
26 |
+ pinchZoomX:true |
|
27 |
+})); |
|
30 | 28 |
|
29 |
+// Add cursor |
|
30 |
+// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/ |
|
31 |
+let cursor = chart.set("cursor", am5xy.XYCursor.new(root5, {})); |
|
32 |
+cursor.lineY.set("visible", false); |
|
31 | 33 |
|
32 |
-let data = [ |
|
33 |
- { |
|
34 |
- year: "1월", |
|
35 |
- income: 22, |
|
36 |
- expenses: 44 |
|
37 |
- }, |
|
38 |
- { |
|
39 |
- year: "2월", |
|
40 |
- income: 20, |
|
41 |
- expenses: 40 |
|
42 |
- }, |
|
43 |
- { |
|
44 |
- year: "3월", |
|
45 |
- income: 15, |
|
46 |
- expenses: 30 |
|
47 |
- }, |
|
48 |
- { |
|
49 |
- year: "4월", |
|
50 |
- income: 15, |
|
51 |
- expenses: 30 |
|
52 |
- }, |
|
53 |
- { |
|
54 |
- year: "5월", |
|
55 |
- income: 15, |
|
56 |
- expenses: 30, |
|
57 |
- strokeSettings: { |
|
58 |
- stroke: chart.get("colors").getIndex(1), |
|
59 |
- strokeWidth: 3, |
|
60 |
- strokeDasharray: [5, 5] |
|
61 |
- } |
|
62 |
- }, |
|
63 |
- { |
|
64 |
- year: "6월", |
|
65 |
- income: 10, |
|
66 |
- expenses: 20, |
|
67 |
- columnSettings: { |
|
68 |
- strokeWidth: 1, |
|
69 |
- strokeDasharray: [5], |
|
70 |
- fillOpacity: 0.2 |
|
71 |
- }, |
|
72 |
- info: "(projection)" |
|
73 |
- } |
|
74 |
-]; |
|
75 | 34 |
|
76 | 35 |
// Create axes |
77 | 36 |
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/ |
78 |
-let xRenderer = am5xy.AxisRendererX.new(root, {}); |
|
79 |
-let xAxis = chart.xAxes.push( |
|
80 |
- am5xy.CategoryAxis.new(root, { |
|
81 |
- categoryField: "year", |
|
82 |
- renderer: xRenderer, |
|
83 |
- tooltip: am5.Tooltip.new(root, {}) |
|
37 |
+let xRenderer = am5xy.AxisRendererX.new(root5, { minGridDistance: 30 }); |
|
38 |
+xRenderer.labels.template.setAll({ |
|
39 |
+ rotation: -90, |
|
40 |
+ centerY: am5.p50, |
|
41 |
+ centerX: am5.p100, |
|
42 |
+ paddingRight: 15 |
|
43 |
+}); |
|
44 |
+ |
|
45 |
+let xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root5, { |
|
46 |
+ maxDeviation: 0.3, |
|
47 |
+ categoryField: "country", |
|
48 |
+ renderer: xRenderer, |
|
49 |
+ tooltip: am5.Tooltip.new(root5, {}) |
|
50 |
+})); |
|
51 |
+ |
|
52 |
+let yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root5, { |
|
53 |
+ maxDeviation: 0.3, |
|
54 |
+ renderer: am5xy.AxisRendererY.new(root5, {}) |
|
55 |
+})); |
|
56 |
+ |
|
57 |
+ |
|
58 |
+// Create series |
|
59 |
+// https://www.amcharts.com/docs/v5/charts/xy-chart/series/ |
|
60 |
+let series = chart.series.push(am5xy.ColumnSeries.new(root5, { |
|
61 |
+ name: "Series 1", |
|
62 |
+ xAxis: xAxis, |
|
63 |
+ yAxis: yAxis, |
|
64 |
+ valueYField: "value", |
|
65 |
+ sequencedInterpolation: true, |
|
66 |
+ categoryXField: "country", |
|
67 |
+ tooltip: am5.Tooltip.new(root5, { |
|
68 |
+ labelText:"{valueY}" |
|
84 | 69 |
}) |
85 |
-); |
|
86 |
-xRenderer.grid.template.setAll({ |
|
87 |
- location: 1 |
|
88 |
-}) |
|
70 |
+})); |
|
71 |
+ |
|
72 |
+series.columns.template.setAll({ cornerRadiusTL: 5, cornerRadiusTR: 5 }); |
|
73 |
+series.columns.template.adapters.add("fill", function(fill, target) { |
|
74 |
+ return chart.get("colors").getIndex(series.columns.indexOf(target)); |
|
75 |
+}); |
|
76 |
+ |
|
77 |
+series.columns.template.adapters.add("stroke", function(stroke, target) { |
|
78 |
+ return chart.get("colors").getIndex(series.columns.indexOf(target)); |
|
79 |
+}); |
|
80 |
+ |
|
81 |
+ |
|
82 |
+// Set data |
|
83 |
+let data = [{ |
|
84 |
+ country: "1주", |
|
85 |
+ value: 80 |
|
86 |
+}, { |
|
87 |
+ country: "2주", |
|
88 |
+ value: 80 |
|
89 |
+}, { |
|
90 |
+ country: "3주", |
|
91 |
+ value: 70 |
|
92 |
+}, { |
|
93 |
+ country: "4주", |
|
94 |
+ value: 80 |
|
95 |
+}]; |
|
89 | 96 |
|
90 | 97 |
xAxis.data.setAll(data); |
98 |
+series.data.setAll(data); |
|
91 | 99 |
|
92 |
-let yAxis = chart.yAxes.push( |
|
93 |
- am5xy.ValueAxis.new(root, { |
|
94 |
- min: 0, |
|
95 |
- extraMax: 0.1, |
|
96 |
- renderer: am5xy.AxisRendererY.new(root, { |
|
97 |
- strokeOpacity: 0.1 |
|
98 |
- }) |
|
99 |
- }) |
|
100 |
-); |
|
101 |
- |
|
102 |
- |
|
103 |
-// Add series |
|
104 |
-// https://www.amcharts.com/docs/v5/charts/xy-chart/series/ |
|
105 |
- |
|
106 |
-let series1 = chart.series.push( |
|
107 |
- am5xy.ColumnSeries.new(root, { |
|
108 |
- name: "인원", |
|
109 |
- xAxis: xAxis, |
|
110 |
- yAxis: yAxis, |
|
111 |
- valueYField: "income", |
|
112 |
- categoryXField: "year", |
|
113 |
- tooltip: am5.Tooltip.new(root, { |
|
114 |
- pointerOrientation: "horizontal", |
|
115 |
- labelText: "{valueY} {info} 명" |
|
116 |
- }) |
|
117 |
- }) |
|
118 |
-); |
|
119 |
- |
|
120 |
-series1.columns.template.setAll({ |
|
121 |
- tooltipY: am5.percent(10), |
|
122 |
- templateField: "columnSettings" |
|
123 |
-}); |
|
124 |
- |
|
125 |
-series1.data.setAll(data); |
|
126 |
- |
|
127 |
-let series2 = chart.series.push( |
|
128 |
- am5xy.LineSeries.new(root, { |
|
129 |
- name: "인건비", |
|
130 |
- xAxis: xAxis, |
|
131 |
- yAxis: yAxis, |
|
132 |
- valueYField: "expenses", |
|
133 |
- categoryXField: "year", |
|
134 |
- tooltip: am5.Tooltip.new(root, { |
|
135 |
- pointerOrientation: "horizontal", |
|
136 |
- labelText: "{valueY} {info} (백만원)" |
|
137 |
- }) |
|
138 |
- }) |
|
139 |
-); |
|
140 |
- |
|
141 |
-series2.strokes.template.setAll({ |
|
142 |
- strokeWidth: 3, |
|
143 |
- templateField: "strokeSettings" |
|
144 |
-}); |
|
145 |
- |
|
146 |
- |
|
147 |
-series2.data.setAll(data); |
|
148 |
- |
|
149 |
-series2.bullets.push(function() { |
|
150 |
- return am5.Bullet.new(root, { |
|
151 |
- sprite: am5.Circle.new(root, { |
|
152 |
- strokeWidth: 3, |
|
153 |
- stroke: series2.get("stroke"), |
|
154 |
- radius: 5, |
|
155 |
- fill: root.interfaceColors.get("background") |
|
156 |
- }) |
|
157 |
- }); |
|
158 |
-}); |
|
159 |
- |
|
160 |
-chart.set("cursor", am5xy.XYCursor.new(root, {})); |
|
161 |
- |
|
162 |
-// Add legend |
|
163 |
-// https://www.amcharts.com/docs/v5/charts/xy-chart/legend-xy-series/ |
|
164 |
-let legend = chart.children.push( |
|
165 |
- am5.Legend.new(root, { |
|
166 |
- centerX: am5.p50, |
|
167 |
- x: am5.p50 |
|
168 |
- }) |
|
169 |
-); |
|
170 |
-legend.data.setAll(chart.series.values); |
|
171 | 100 |
|
172 | 101 |
// Make stuff animate on load |
173 | 102 |
// https://www.amcharts.com/docs/v5/concepts/animations/ |
103 |
+series.appear(1000); |
|
174 | 104 |
chart.appear(1000, 100); |
175 |
-series1.appear(); |
|
105 |
+ |
|
176 | 106 |
} |
177 | 107 |
|
178 | 108 |
componentWillUnmount() { |
... | ... | @@ -182,7 +112,7 @@ |
182 | 112 |
} |
183 | 113 |
|
184 | 114 |
render() { |
185 |
- return <div id="chart" style={{ width: "100%", height: "80%" }}></div>; |
|
115 |
+ return <div id="chart" style={{ width: "100%", height: "90%" }}></div>; |
|
186 | 116 |
} |
187 | 117 |
} |
188 | 118 |
|
--- client/views/component/chart/Chart1.jsx
+++ client/views/component/chart/Chart1.jsx
... | ... | @@ -101,10 +101,6 @@ |
101 | 101 |
yAxis: yAxis, |
102 | 102 |
valueYField: fieldName, |
103 | 103 |
categoryXField: "date", |
104 |
- tooltip: am5.Tooltip.new(root1, { |
|
105 |
- pointerOrientation: "horizontal", |
|
106 |
- labelText: "[bold]{name}[/]\n{categoryY}: {valueX}" |
|
107 |
- }) |
|
108 | 104 |
}) |
109 | 105 |
); |
110 | 106 |
|
... | ... | @@ -127,8 +123,6 @@ |
127 | 123 |
}), |
128 | 124 |
}); |
129 | 125 |
}); |
130 |
- |
|
131 |
- |
|
132 | 126 |
|
133 | 127 |
legend.data.push(series); |
134 | 128 |
} |
... | ... | @@ -155,7 +149,7 @@ |
155 | 149 |
|
156 | 150 |
render() { |
157 | 151 |
return ( |
158 |
- <div id="chartdiv1" style={{ width: "100%", height:"17vh"}}></div> |
|
152 |
+ <div id="chartdiv1" style={{ width: "100%", height:"80%"}}></div> |
|
159 | 153 |
); |
160 | 154 |
} |
161 | 155 |
} |
--- client/views/component/chart/Chart2.jsx
+++ client/views/component/chart/Chart2.jsx
... | ... | @@ -8,164 +8,120 @@ |
8 | 8 |
let root = am5.Root.new("Chart2"); |
9 | 9 |
|
10 | 10 |
root._logo.dispose(); |
11 |
- // Set themes |
|
12 |
-// https://www.amcharts.com/docs/v5/concepts/themes/ |
|
13 |
-root.setThemes([ |
|
14 |
- am5themes_Animated.new(root) |
|
15 |
-]); |
|
11 |
+ // Set themes |
|
12 |
+ // https://www.amcharts.com/docs/v5/concepts/themes/ |
|
13 |
+ root.setThemes([am5themes_Animated.new(root)]); |
|
16 | 14 |
|
15 |
+ // Create chart |
|
16 |
+ // https://www.amcharts.com/docs/v5/charts/xy-chart/ |
|
17 |
+ let chart = root.container.children.push( |
|
18 |
+ am5xy.XYChart.new(root, { |
|
19 |
+ panX: true, |
|
20 |
+ panY: true, |
|
21 |
+ wheelX: "panX", |
|
22 |
+ wheelY: "zoomX", |
|
23 |
+ pinchZoomX: true, |
|
24 |
+ }) |
|
25 |
+ ); |
|
17 | 26 |
|
18 |
-// Create chart |
|
19 |
-// https://www.amcharts.com/docs/v5/charts/xy-chart/ |
|
20 |
-let chart = root.container.children.push( |
|
21 |
- am5xy.XYChart.new(root, { |
|
22 |
- panX: false, |
|
23 |
- panY: false, |
|
24 |
- wheelX: "panX", |
|
25 |
- wheelY: "zoomX", |
|
26 |
- layout: root.verticalLayout |
|
27 |
- }) |
|
28 |
-); |
|
27 |
+ chart.get("colors").set("step", 3); |
|
29 | 28 |
|
29 |
+ // Add cursor |
|
30 |
+ // https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/ |
|
31 |
+ let cursor = chart.set("cursor", am5xy.XYCursor.new(root, {})); |
|
32 |
+ cursor.lineY.set("visible", false); |
|
30 | 33 |
|
31 |
-let data = [ |
|
32 |
- { |
|
33 |
- year: "1월", |
|
34 |
- income: 23.5 |
|
35 |
- }, |
|
36 |
- { |
|
37 |
- year: "2월", |
|
38 |
- income: 26.2 |
|
39 |
- }, |
|
40 |
- { |
|
41 |
- year: "3월", |
|
42 |
- income: 30.1 |
|
43 |
- }, |
|
44 |
- { |
|
45 |
- year: "4월", |
|
46 |
- income: 29.5 |
|
47 |
- }, |
|
48 |
- { |
|
49 |
- year: "5월", |
|
50 |
- income: 30.6, |
|
51 |
- strokeSettings: { |
|
52 |
- stroke: chart.get("colors").getIndex(1), |
|
53 |
- strokeWidth: 3, |
|
54 |
- strokeDasharray: [5, 5] |
|
55 |
- } |
|
56 |
- }, |
|
57 |
- { |
|
58 |
- year: "6월", |
|
59 |
- income: 34.1, |
|
60 |
- columnSettings: { |
|
61 |
- strokeWidth: 1, |
|
62 |
- strokeDasharray: [5], |
|
63 |
- fillOpacity: 0.2 |
|
64 |
- }, |
|
65 |
- info: "(projection)" |
|
66 |
- } |
|
67 |
-]; |
|
34 |
+ // Create axes |
|
35 |
+ // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/ |
|
36 |
+ let xAxis = chart.xAxes.push( |
|
37 |
+ am5xy.DateAxis.new(root, { |
|
38 |
+ maxDeviation: 0.3, |
|
39 |
+ baseInterval: { |
|
40 |
+ timeUnit: "day", |
|
41 |
+ count: 1, |
|
42 |
+ }, |
|
43 |
+ renderer: am5xy.AxisRendererX.new(root, {}), |
|
44 |
+ tooltip: am5.Tooltip.new(root, {}), |
|
45 |
+ }) |
|
46 |
+ ); |
|
68 | 47 |
|
69 |
-// Create axes |
|
70 |
-// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/ |
|
71 |
-let xRenderer = am5xy.AxisRendererX.new(root, {}); |
|
72 |
-let xAxis = chart.xAxes.push( |
|
73 |
- am5xy.CategoryAxis.new(root, { |
|
74 |
- categoryField: "year", |
|
75 |
- renderer: xRenderer, |
|
76 |
- tooltip: am5.Tooltip.new(root, {}) |
|
77 |
- }) |
|
78 |
-); |
|
79 |
-xRenderer.grid.template.setAll({ |
|
80 |
- location: 1 |
|
81 |
-}) |
|
48 |
+ let yAxis = chart.yAxes.push( |
|
49 |
+ am5xy.ValueAxis.new(root, { |
|
50 |
+ maxDeviation: 0.3, |
|
51 |
+ renderer: am5xy.AxisRendererY.new(root, {}), |
|
52 |
+ }) |
|
53 |
+ ); |
|
82 | 54 |
|
83 |
-xAxis.data.setAll(data); |
|
55 |
+ // Create series |
|
56 |
+ // https://www.amcharts.com/docs/v5/charts/xy-chart/series/ |
|
57 |
+ let series = chart.series.push( |
|
58 |
+ am5xy.LineSeries.new(root, { |
|
59 |
+ name: "Series 1", |
|
60 |
+ xAxis: xAxis, |
|
61 |
+ yAxis: yAxis, |
|
62 |
+ valueYField: "value", |
|
63 |
+ valueXField: "date", |
|
64 |
+ tooltip: am5.Tooltip.new(root, { |
|
65 |
+ labelText: "{valueY}", |
|
66 |
+ }), |
|
67 |
+ }) |
|
68 |
+ ); |
|
69 |
+ series.strokes.template.setAll({ |
|
70 |
+ strokeWidth: 2, |
|
71 |
+ strokeDasharray: [3, 3], |
|
72 |
+ }); |
|
84 | 73 |
|
85 |
-let yAxis = chart.yAxes.push( |
|
86 |
- am5xy.ValueAxis.new(root, { |
|
87 |
- min: 0, |
|
88 |
- extraMax: 0.1, |
|
89 |
- renderer: am5xy.AxisRendererY.new(root, { |
|
90 |
- strokeOpacity: 0.1 |
|
91 |
- }) |
|
92 |
- }) |
|
93 |
-); |
|
74 |
+ // Set data |
|
75 |
+ let data = [ |
|
76 |
+ { |
|
77 |
+ date: new Date(2022, 8, 1).getTime(), |
|
78 |
+ value: 0, |
|
79 |
+ }, |
|
80 |
+ { |
|
81 |
+ date: new Date(2022, 8, 2).getTime(), |
|
82 |
+ value: 1, |
|
83 |
+ }, |
|
84 |
+ { |
|
85 |
+ date: new Date(2022, 8, 3).getTime(), |
|
86 |
+ value: 1, |
|
87 |
+ }, |
|
88 |
+ { |
|
89 |
+ date: new Date(2022, 8, 4).getTime(), |
|
90 |
+ value: 2, |
|
91 |
+ }, |
|
92 |
+ { |
|
93 |
+ date: new Date(2022, 8, 5).getTime(), |
|
94 |
+ value: 3, |
|
95 |
+ }, |
|
96 |
+ { |
|
97 |
+ date: new Date(2022, 8, 6).getTime(), |
|
98 |
+ value: 3, |
|
99 |
+ }, |
|
100 |
+ { |
|
101 |
+ date: new Date(2022, 8, 7).getTime(), |
|
102 |
+ value: 7, |
|
103 |
+ }, |
|
104 |
+ { |
|
105 |
+ date: new Date(2022, 8, 8).getTime(), |
|
106 |
+ value: 7, |
|
107 |
+ }, |
|
108 |
+ { |
|
109 |
+ date: new Date(2022, 8, 9).getTime(), |
|
110 |
+ value: 8, |
|
111 |
+ }, |
|
112 |
+ { |
|
113 |
+ date: new Date(2022, 8, 10).getTime(), |
|
114 |
+ value: 8, |
|
115 |
+ }, |
|
116 |
+ ]; |
|
94 | 117 |
|
118 |
+ series.data.setAll(data); |
|
95 | 119 |
|
96 |
-// Add series |
|
97 |
-// https://www.amcharts.com/docs/v5/charts/xy-chart/series/ |
|
120 |
+ // Make stuff animate on load |
|
121 |
+ // https://www.amcharts.com/docs/v5/concepts/animations/ |
|
122 |
+ series.appear(1000); |
|
123 |
+ chart.appear(1000, 100); |
|
98 | 124 |
|
99 |
-let series1 = chart.series.push( |
|
100 |
- am5xy.ColumnSeries.new(root, { |
|
101 |
- name: "사용자 수", |
|
102 |
- xAxis: xAxis, |
|
103 |
- yAxis: yAxis, |
|
104 |
- valueYField: "income", |
|
105 |
- categoryXField: "year", |
|
106 |
- tooltip: am5.Tooltip.new(root, { |
|
107 |
- pointerOrientation: "horizontal", |
|
108 |
- labelText: "{valueY} {info} 명" |
|
109 |
- }) |
|
110 |
- }) |
|
111 |
-); |
|
112 |
- |
|
113 |
-series1.columns.template.setAll({ |
|
114 |
- tooltipY: am5.percent(10), |
|
115 |
- templateField: "columnSettings" |
|
116 |
-}); |
|
117 |
- |
|
118 |
-series1.data.setAll(data); |
|
119 |
- |
|
120 |
-// let series2 = chart.series.push( |
|
121 |
-// am5xy.LineSeries.new(root, { |
|
122 |
-// name: "Expenses", |
|
123 |
-// xAxis: xAxis, |
|
124 |
-// yAxis: yAxis, |
|
125 |
-// valueYField: "expenses", |
|
126 |
-// categoryXField: "year", |
|
127 |
-// tooltip: am5.Tooltip.new(root, { |
|
128 |
-// pointerOrientation: "horizontal", |
|
129 |
-// labelText: "{name} in {categoryX}: {valueY} {info}" |
|
130 |
-// }) |
|
131 |
-// }) |
|
132 |
-// ); |
|
133 |
- |
|
134 |
-// series2.strokes.template.setAll({ |
|
135 |
-// strokeWidth: 3, |
|
136 |
-// templateField: "strokeSettings" |
|
137 |
-// }); |
|
138 |
- |
|
139 |
- |
|
140 |
-// series2.data.setAll(data); |
|
141 |
- |
|
142 |
-// series2.bullets.push(function() { |
|
143 |
-// return am5.Bullet.new(root, { |
|
144 |
-// sprite: am5.Circle.new(root, { |
|
145 |
-// strokeWidth: 3, |
|
146 |
-// stroke: series2.get("stroke"), |
|
147 |
-// radius: 5, |
|
148 |
-// fill: root.interfaceColors.get("background") |
|
149 |
-// }) |
|
150 |
-// }); |
|
151 |
-// }); |
|
152 |
- |
|
153 |
-chart.set("cursor", am5xy.XYCursor.new(root, {})); |
|
154 |
- |
|
155 |
-// Add legend |
|
156 |
-// https://www.amcharts.com/docs/v5/charts/xy-chart/legend-xy-series/ |
|
157 |
-let legend = chart.children.push( |
|
158 |
- am5.Legend.new(root, { |
|
159 |
- centerX: am5.p50, |
|
160 |
- x: am5.p50 |
|
161 |
- }) |
|
162 |
-); |
|
163 |
-legend.data.setAll(chart.series.values); |
|
164 |
- |
|
165 |
-// Make stuff animate on load |
|
166 |
-// https://www.amcharts.com/docs/v5/concepts/animations/ |
|
167 |
-chart.appear(1000, 100); |
|
168 |
-series1.appear(); |
|
169 | 125 |
this.root = root; |
170 | 126 |
} |
171 | 127 |
|
... | ... | @@ -176,7 +132,7 @@ |
176 | 132 |
} |
177 | 133 |
|
178 | 134 |
render() { |
179 |
- return <div id="Chart2" style={{ width: "100%", height: "80%" , maxwidth: "100%"}}></div>; |
|
135 |
+ return <div id="Chart2" style={{ width: "100%", height: "15vh" }}></div>; |
|
180 | 136 |
} |
181 | 137 |
} |
182 | 138 |
|
--- client/views/component/chart/Chart3.jsx
+++ client/views/component/chart/Chart3.jsx
... | ... | @@ -81,17 +81,41 @@ |
81 | 81 |
|
82 | 82 |
// Set data |
83 | 83 |
let data = [{ |
84 |
- country: "60대", |
|
85 |
- value: 80 |
|
84 |
+ country: "1월", |
|
85 |
+ value: 5 |
|
86 | 86 |
}, { |
87 |
- country: "70대", |
|
88 |
- value: 80 |
|
87 |
+ country: "2월", |
|
88 |
+ value: 5 |
|
89 | 89 |
}, { |
90 |
- country: "80대", |
|
91 |
- value: 70 |
|
90 |
+ country: "3월", |
|
91 |
+ value: 5 |
|
92 | 92 |
}, { |
93 |
- country: "90대", |
|
94 |
- value: 65 |
|
93 |
+ country: "4월", |
|
94 |
+ value: 5 |
|
95 |
+}, { |
|
96 |
+ country: "5월", |
|
97 |
+ value: 4 |
|
98 |
+}, { |
|
99 |
+ country: "6월", |
|
100 |
+ value: 3 |
|
101 |
+}, { |
|
102 |
+ country: "7월", |
|
103 |
+ value: 3 |
|
104 |
+}, { |
|
105 |
+ country: "8월", |
|
106 |
+ value: 3 |
|
107 |
+}, { |
|
108 |
+ country: "9월", |
|
109 |
+ value: 3 |
|
110 |
+}, { |
|
111 |
+ country: "10월", |
|
112 |
+ value: 2 |
|
113 |
+}, { |
|
114 |
+ country: "11월", |
|
115 |
+ value: 2 |
|
116 |
+},{ |
|
117 |
+ country: "12월", |
|
118 |
+ value: 1 |
|
95 | 119 |
}]; |
96 | 120 |
|
97 | 121 |
xAxis.data.setAll(data); |
--- client/views/component/chart/Donut1.jsx
+++ client/views/component/chart/Donut1.jsx
... | ... | @@ -33,8 +33,11 @@ |
33 | 33 |
// Set data |
34 | 34 |
// https://www.amcharts.com/docs/v5/charts/percent-charts/pie-chart/#Setting_data |
35 | 35 |
series.data.setAll([ |
36 |
- { value: 1, category: "미사용" }, |
|
37 |
- { value: 2, category: "사용" }, |
|
36 |
+ { value: 1, category: "1등급" }, |
|
37 |
+ { value: 2, category: "2등급" }, |
|
38 |
+ { value: 3, category: "3등급" }, |
|
39 |
+ { value: 3, category: "4등급" }, |
|
40 |
+ { value: 1, category: "5등급" }, |
|
38 | 41 |
]); |
39 | 42 |
|
40 | 43 |
// Create legend |
--- client/views/component/chart/Map.jsx
+++ client/views/component/chart/Map.jsx
... | ... | @@ -316,7 +316,7 @@ |
316 | 316 |
<div |
317 | 317 |
className="flex80" |
318 | 318 |
id="Map" |
319 |
- style={{ width: "100%", height: "80%", marginBottom: "1rem", color: "#ffffff"}} |
|
319 |
+ style={{ width: "100%", height: "35vh", marginBottom: "1rem" }} |
|
320 | 320 |
></div> |
321 | 321 |
); |
322 | 322 |
} |
--- client/views/component/chart/RowChart.jsx
+++ client/views/component/chart/RowChart.jsx
... | ... | @@ -82,52 +82,20 @@ |
82 | 82 |
// Set data |
83 | 83 |
let data = [ |
84 | 84 |
{ |
85 |
- network: "1월", |
|
86 |
- value: 20, |
|
85 |
+ network: "60대", |
|
86 |
+ value: 80, |
|
87 | 87 |
}, |
88 | 88 |
{ |
89 |
- network: "2월", |
|
90 |
- value: 18, |
|
89 |
+ network: "70대", |
|
90 |
+ value: 80, |
|
91 | 91 |
}, |
92 | 92 |
{ |
93 |
- network: "3월", |
|
94 |
- value: 10, |
|
93 |
+ network: "80대", |
|
94 |
+ value: 70, |
|
95 | 95 |
}, |
96 | 96 |
{ |
97 |
- network: "4월", |
|
98 |
- value: 7, |
|
99 |
- }, |
|
100 |
- { |
|
101 |
- network: "5월", |
|
102 |
- value: 5, |
|
103 |
- }, |
|
104 |
- { |
|
105 |
- network: "6월", |
|
106 |
- value: 3, |
|
107 |
- }, |
|
108 |
- { |
|
109 |
- network: "7월", |
|
110 |
- value: 6, |
|
111 |
- }, |
|
112 |
- { |
|
113 |
- network: "8월", |
|
114 |
- value: 7, |
|
115 |
- }, |
|
116 |
- { |
|
117 |
- network: "9월", |
|
118 |
- value: 15, |
|
119 |
- }, |
|
120 |
- { |
|
121 |
- network: "10월", |
|
122 |
- value: 30, |
|
123 |
- }, |
|
124 |
- { |
|
125 |
- network: "11월", |
|
126 |
- value: 13, |
|
127 |
- }, |
|
128 |
- { |
|
129 |
- network: "12월", |
|
130 |
- value: 9, |
|
97 |
+ network: "90대", |
|
98 |
+ value: 75, |
|
131 | 99 |
}, |
132 | 100 |
]; |
133 | 101 |
|
... | ... | @@ -236,7 +204,7 @@ |
236 | 204 |
} |
237 | 205 |
|
238 | 206 |
render() { |
239 |
- return <div id="RowChart" style={{ width: "100%", height: "80%" }}></div>; |
|
207 |
+ return <div id="RowChart" style={{ width: "100%", height: "100%" }}></div>; |
|
240 | 208 |
} |
241 | 209 |
} |
242 | 210 |
|
--- client/views/layout/Menu.jsx
+++ client/views/layout/Menu.jsx
... | ... | @@ -16,75 +16,75 @@ |
16 | 16 |
path: "/Main", |
17 | 17 |
icon: <HouseIcon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} />, |
18 | 18 |
}, |
19 |
- { |
|
20 |
- title: "사용자 관리", |
|
21 |
- path: "/UserAuthoriySelect", |
|
22 |
- icon: ( |
|
23 |
- <PersonIcon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
24 |
- ), |
|
25 |
- }, |
|
26 |
- { |
|
27 |
- title: "건강 관리", |
|
28 |
- prefix: "/Medicine", |
|
29 |
- icon: ( |
|
30 |
- <Diversity1Icon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
31 |
- ), |
|
32 |
- childrens: [ |
|
33 |
- { |
|
34 |
- title: "복약 관리", |
|
35 |
- path: "/MedicineCareSelect", |
|
36 |
- }, |
|
37 |
- { |
|
38 |
- title: "댁내 온도 관리", |
|
39 |
- path: "/TemperatureManagementSelect", |
|
40 |
- }, |
|
41 |
- { |
|
42 |
- title: "복약율 통계", |
|
43 |
- path: "/MedicineStatistics", |
|
44 |
- }, |
|
45 |
- ], |
|
46 |
- }, |
|
19 |
+ // { |
|
20 |
+ // title: "사용자 관리", |
|
21 |
+ // path: "/UserAuthoriySelect", |
|
22 |
+ // icon: ( |
|
23 |
+ // <PersonIcon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
24 |
+ // ), |
|
25 |
+ // }, |
|
26 |
+ // { |
|
27 |
+ // title: "건강 관리", |
|
28 |
+ // prefix: "/Medicine", |
|
29 |
+ // icon: ( |
|
30 |
+ // <Diversity1Icon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
31 |
+ // ), |
|
32 |
+ // childrens: [ |
|
33 |
+ // { |
|
34 |
+ // title: "복약 관리", |
|
35 |
+ // path: "/MedicineCareSelect", |
|
36 |
+ // }, |
|
37 |
+ // { |
|
38 |
+ // title: "댁내 온도 관리", |
|
39 |
+ // path: "/TemperatureManagementSelect", |
|
40 |
+ // }, |
|
41 |
+ // { |
|
42 |
+ // title: "복약율 통계", |
|
43 |
+ // path: "/MedicineStatistics", |
|
44 |
+ // }, |
|
45 |
+ // ], |
|
46 |
+ // }, |
|
47 | 47 |
|
48 |
- { |
|
49 |
- title: "방문 관리", |
|
50 |
- prefix: "/Visit", |
|
51 |
- icon: ( |
|
52 |
- <DoorFrontIcon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
53 |
- ), |
|
54 |
- childrens: [ |
|
55 |
- { |
|
56 |
- title: "방문 관리", |
|
57 |
- path: "/VisitSelect", |
|
58 |
- }, |
|
59 |
- ], |
|
60 |
- }, |
|
61 |
- { |
|
62 |
- title: "장비 관리", |
|
63 |
- prefix: "/Equipment", |
|
64 |
- icon: ( |
|
65 |
- <SpeakerPhoneIcon |
|
66 |
- sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} |
|
67 |
- /> |
|
68 |
- ), |
|
69 |
- childrens: [ |
|
70 |
- { |
|
71 |
- title: "장비 관리", |
|
72 |
- path: "/EquipmentManagementSelect", |
|
73 |
- }, |
|
74 |
- ], |
|
75 |
- }, |
|
76 |
- { |
|
77 |
- title: "고객지원센터", |
|
78 |
- icon: ( |
|
79 |
- <CallIcon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
80 |
- ), |
|
81 |
- childrens: [ |
|
82 |
- { |
|
83 |
- title: "장비 반납/교환 요청", |
|
84 |
- path: "/EquipmentManagementSelectReturn", |
|
85 |
- }, |
|
86 |
- ], |
|
87 |
- }, |
|
48 |
+ // { |
|
49 |
+ // title: "방문 관리", |
|
50 |
+ // prefix: "/Visit", |
|
51 |
+ // icon: ( |
|
52 |
+ // <DoorFrontIcon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
53 |
+ // ), |
|
54 |
+ // childrens: [ |
|
55 |
+ // { |
|
56 |
+ // title: "방문 관리", |
|
57 |
+ // path: "/VisitSelect", |
|
58 |
+ // }, |
|
59 |
+ // ], |
|
60 |
+ // }, |
|
61 |
+ // { |
|
62 |
+ // title: "장비 관리", |
|
63 |
+ // prefix: "/Equipment", |
|
64 |
+ // icon: ( |
|
65 |
+ // <SpeakerPhoneIcon |
|
66 |
+ // sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} |
|
67 |
+ // /> |
|
68 |
+ // ), |
|
69 |
+ // childrens: [ |
|
70 |
+ // { |
|
71 |
+ // title: "장비 관리", |
|
72 |
+ // path: "/EquipmentManagementSelect", |
|
73 |
+ // }, |
|
74 |
+ // ], |
|
75 |
+ // }, |
|
76 |
+ // { |
|
77 |
+ // title: "고객지원센터", |
|
78 |
+ // icon: ( |
|
79 |
+ // <CallIcon sx={{ fontSize: 20, color: "#ffffff", marginRight: 1 }} /> |
|
80 |
+ // ), |
|
81 |
+ // childrens: [ |
|
82 |
+ // { |
|
83 |
+ // title: "장비 반납/교환 요청", |
|
84 |
+ // path: "/EquipmentManagementSelectReturn", |
|
85 |
+ // }, |
|
86 |
+ // ], |
|
87 |
+ // }, |
|
88 | 88 |
{ |
89 | 89 |
title: "Q&A", |
90 | 90 |
path: "/QandA", |
--- client/views/pages/App.jsx
+++ client/views/pages/App.jsx
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 |
const navigate = useNavigate(); |
21 | 21 |
const [isLogin, setIsLogin] = React.useState(false); |
22 | 22 |
|
23 |
+ |
|
23 | 24 |
const getLogin = (loginComponentName) => { |
24 | 25 |
setIsLogin(true); |
25 | 26 |
if (loginComponentName == undefined || loginComponentName == null || loginComponentName.length == 0) { |
... | ... | @@ -36,6 +37,7 @@ |
36 | 37 |
item.childrens?.some((child) => location.pathname.startsWith(child.path)) |
37 | 38 |
) ?? { title: '' }; |
38 | 39 |
|
40 |
+ |
|
39 | 41 |
return ( |
40 | 42 |
<div id="App"> |
41 | 43 |
{isLogin ? ( |
--- client/views/pages/AppRoute.jsx
+++ client/views/pages/AppRoute.jsx
... | ... | @@ -6,9 +6,7 @@ |
6 | 6 |
import React from "react"; |
7 | 7 |
//react router 라이브러리 import |
8 | 8 |
import { Routes, Route } from "react-router-dom"; |
9 |
- |
|
10 |
-import Test from "./Test/Test.jsx"; |
|
11 |
-import Main2 from "./main/Main2.jsx"; |
|
9 |
+import Main from "./main/Main.jsx"; |
|
12 | 10 |
import SeniorSelect from "./senior_management/SeniorSelect.jsx"; |
13 | 11 |
import SeniorInsert from "./senior_management/SeniorInsert.jsx"; |
14 | 12 |
import SeniorSelectOne from "./senior_management/SeniorSelectOne.jsx"; |
... | ... | @@ -25,15 +23,13 @@ |
25 | 23 |
import EquipmentManagementSelectOne from "./equipment/EquipmentManagementSelectOne.jsx"; |
26 | 24 |
import UserAuthoriySelect from "./authority/UserAuthoriySelect.jsx"; |
27 | 25 |
import MyInfoUpdate from "./authority/MyInfoUpdate.jsx"; |
28 |
-import EquipmentManagementSelectReturn from "./equipment/EquipmentManagementSelectReturn.jsx"; |
|
29 |
-import Main3 from "./Main/Main3.jsx"; |
|
30 | 26 |
import QandA from "./authority/QandA.jsx"; |
27 |
+import LoginSelect from "./login/LoginSelect.jsx"; |
|
31 | 28 |
|
32 | 29 |
function AppRoute() { |
33 | 30 |
return ( |
34 | 31 |
<Routes> |
35 |
- <Route path="/Test" element={<Test />}></Route> |
|
36 |
- <Route path="/Main" element={<Main2 />}></Route> |
|
32 |
+ <Route path="/Main" element={<Main />}></Route> |
|
37 | 33 |
<Route path="/SeniorSelect" element={<SeniorSelect />}></Route> |
38 | 34 |
<Route path="/SeniorInsert" element={<SeniorInsert />}></Route> |
39 | 35 |
<Route path="/SeniorSelectOne" element={<SeniorSelectOne />}></Route> |
... | ... | @@ -77,9 +73,8 @@ |
77 | 73 |
element={<UserAuthoriySelect />} |
78 | 74 |
></Route> |
79 | 75 |
<Route path="/MyInfoUpdate" element={<MyInfoUpdate />}></Route> |
80 |
- <Route path="/EquipmentManagementSelectReturn" element={<EquipmentManagementSelectReturn />}></Route> |
|
81 |
- <Route path="/Main3" element={<Main3 />}></Route> |
|
82 | 76 |
<Route path="/QandA" element={<QandA />}></Route> |
77 |
+ <Route path="/LoginSelect" element={<LoginSelect />}></Route> |
|
83 | 78 |
</Routes> |
84 | 79 |
); |
85 | 80 |
} |
--- client/views/pages/equipment/EquipmentManagementInsert.jsx
+++ client/views/pages/equipment/EquipmentManagementInsert.jsx
... | ... | @@ -1,14 +1,13 @@ |
1 | 1 |
import React from "react"; |
2 | 2 |
import Button from "../../component/Button.jsx"; |
3 |
-import ContentTitle from "../../component/ContentTitle.jsx"; |
|
4 | 3 |
|
5 | 4 |
export default function EquipmentManagementInsert() { |
6 | 5 |
return ( |
7 | 6 |
<main> |
8 | 7 |
<div className="content-wrap"> |
9 |
- <ContentTitle contentTitle={"장비 등록"} /> |
|
10 |
- <div className="margin-bottom2 insert"> |
|
11 |
- {/* <div className="flex30"> |
|
8 |
+ <div className="page-title margin-bottom">장비 등록</div> |
|
9 |
+ <div className="flex-align-start margin-bottom2 insert"> |
|
10 |
+ <div className="flex30"> |
|
12 | 11 |
<div className="flex margin-bottom"> |
13 | 12 |
<input |
14 | 13 |
type="text" |
... | ... | @@ -22,11 +21,11 @@ |
22 | 21 |
<ul className="user-list"> |
23 | 22 |
<li>검색 내역이 없습니다.</li> |
24 | 23 |
</ul> |
25 |
- </div> */} |
|
24 |
+ </div> |
|
26 | 25 |
<table className="flex70 margin-bottom"> |
27 | 26 |
<tbody className="equipment-insert"> |
28 | 27 |
<tr> |
29 |
- <th>장비 시리얼 넘버</th> |
|
28 |
+ <th>장비넘버</th> |
|
30 | 29 |
<td colSpan={5}> |
31 | 30 |
<input type="text" name="" id="" /> |
32 | 31 |
</td> |
... | ... | @@ -47,21 +46,70 @@ |
47 | 46 |
</label> |
48 | 47 |
</div> |
49 | 48 |
</td> |
50 |
- </tr> |
|
49 |
+ </tr> |
|
51 | 50 |
<tr> |
52 |
- <th>구매일</th> |
|
51 |
+ <th>사용자</th> |
|
52 |
+ <td colSpan={5}> |
|
53 |
+ <div className="flex"> |
|
54 |
+ <input type="text" disabled /> |
|
55 |
+ </div> |
|
56 |
+ </td> |
|
57 |
+ </tr> |
|
58 |
+ <tr> |
|
59 |
+ <th>주소</th> |
|
60 |
+ <td colSpan={5}> |
|
61 |
+ <div className="flex"> |
|
62 |
+ <input type="text" disabled /> |
|
63 |
+ </div> |
|
64 |
+ </td> |
|
65 |
+ </tr> |
|
66 |
+ <tr> |
|
67 |
+ <th>대여일</th> |
|
68 |
+ <td> |
|
69 |
+ <input type="date"/> |
|
70 |
+ </td> |
|
71 |
+ <th>반납일</th> |
|
53 | 72 |
<td> |
54 | 73 |
<input type="date" /> |
55 | 74 |
</td> |
56 |
- <th>기기 상태</th> |
|
75 |
+ <th>작동여부</th> |
|
57 | 76 |
<td> |
58 | 77 |
<select name="" id="" className="select100"> |
59 |
- <option value="">양호</option> |
|
78 |
+ <option value="">작동</option> |
|
60 | 79 |
<option value="">수리중</option> |
61 |
- <option value="">불량</option> |
|
80 |
+ <option value="">고장</option> |
|
62 | 81 |
</select> |
63 | 82 |
</td> |
64 |
- </tr> |
|
83 |
+ </tr> |
|
84 |
+ <tr> |
|
85 |
+ <th>아침</th> |
|
86 |
+ <td> |
|
87 |
+ <select name="" id="" className="select100"> |
|
88 |
+ <option value="">미사용</option> |
|
89 |
+ <option value="">사용</option> |
|
90 |
+ </select> |
|
91 |
+ </td> |
|
92 |
+ <th>점심</th> |
|
93 |
+ <td> |
|
94 |
+ <select name="" id="" className="select100"> |
|
95 |
+ <option value="">미사용</option> |
|
96 |
+ <option value="">사용</option> |
|
97 |
+ </select> |
|
98 |
+ </td> |
|
99 |
+ <th>저녁</th> |
|
100 |
+ <td> |
|
101 |
+ <select name="" id="" className="select100"> |
|
102 |
+ <option value="">미사용</option> |
|
103 |
+ <option value="">사용</option> |
|
104 |
+ </select> |
|
105 |
+ </td> |
|
106 |
+ </tr> |
|
107 |
+ <tr> |
|
108 |
+ <th>비고</th> |
|
109 |
+ <td colSpan={5}> |
|
110 |
+ <textarea name="" id="" cols="30" rows="10"></textarea> |
|
111 |
+ </td> |
|
112 |
+ </tr> |
|
65 | 113 |
</tbody> |
66 | 114 |
</table> |
67 | 115 |
</div> |
--- client/views/pages/equipment/EquipmentManagementSelect.jsx
+++ client/views/pages/equipment/EquipmentManagementSelect.jsx
... | ... | @@ -1,188 +1,144 @@ |
1 | 1 |
import React from "react"; |
2 |
-import Table from "../../component/Table.jsx"; |
|
3 | 2 |
import Button from "../../component/Button.jsx"; |
4 |
-import SubTitle from "../../component/SubTitle.jsx"; |
|
3 |
+import Table from "../../component/Table.jsx"; |
|
5 | 4 |
import Modal from "../../component/Modal.jsx"; |
5 |
+import ContentTitle from "../../component/ContentTitle.jsx"; |
|
6 |
+import SubTitle from '../../component/SubTitle.jsx' |
|
6 | 7 |
import { useNavigate } from "react-router"; |
7 | 8 |
|
8 | 9 |
export default function EquipmentManagementSelect() { |
9 | 10 |
const navigate = useNavigate(); |
10 |
- const thead1 = [ |
|
11 |
+ const [modalOpen, setModalOpen] = React.useState(false); |
|
12 |
+ const openModal = () => { |
|
13 |
+ setModalOpen(true); |
|
14 |
+ }; |
|
15 |
+ const closeModal = () => { |
|
16 |
+ setModalOpen(false); |
|
17 |
+ }; |
|
18 |
+ //게시판 |
|
19 |
+ const thead = [ |
|
20 |
+ <input type="checkbox" />, |
|
11 | 21 |
"No", |
12 | 22 |
"장비명", |
13 | 23 |
"시리얼 넘버", |
14 | 24 |
"기기 상태", |
15 | 25 |
"구매일", |
16 |
- "사용여부", |
|
26 |
+ "배터리 잔량", |
|
27 |
+ "대여가능여부", |
|
17 | 28 |
"관리", |
18 | 29 |
]; |
19 |
- const key1 = [ |
|
30 |
+ const key = [ |
|
31 |
+ "", |
|
20 | 32 |
"No", |
21 | 33 |
"equipment_name", |
22 | 34 |
"serialNumber", |
23 | 35 |
"work", |
24 | 36 |
"name", |
25 |
- "use", |
|
26 |
- "management",]; |
|
27 |
- const content1 = [ |
|
28 |
- { |
|
29 |
- No: 1, |
|
30 |
- equipment_name: "스마트약상자", |
|
31 |
- serialNumber: "ABCD-1", |
|
32 |
- work: "양호", |
|
33 |
- name: "2022.12.02", |
|
34 |
- use: "사용", |
|
35 |
- management: ( |
|
36 |
- <Button |
|
37 |
- className={"btn-small gray-btn"} |
|
38 |
- btnName={"상세보기"} |
|
39 |
- onClick={() => { |
|
40 |
- navigate("/EquipmentManagementSelectOne"); |
|
41 |
- }} |
|
42 |
- /> |
|
43 |
- ), |
|
44 |
- }, |
|
45 |
- { |
|
46 |
- No: 2, |
|
47 |
- equipment_name: "스마트약상자", |
|
48 |
- serialNumber: "ABCD-1", |
|
49 |
- work: "불량", |
|
50 |
- name: "2022.12.02", |
|
51 |
- use: "미사용", |
|
52 |
- management: ( |
|
53 |
- <Button |
|
54 |
- className={"btn-small gray-btn"} |
|
55 |
- btnName={"상세보기"} |
|
56 |
- onClick={() => { |
|
57 |
- navigate("/EquipmentManagementSelectOne"); |
|
58 |
- }} |
|
59 |
- /> |
|
60 |
- ), |
|
61 |
- }, |
|
62 |
- ]; |
|
63 |
- const thead2 = [ |
|
64 |
- "No", |
|
65 |
- "장비명", |
|
66 |
- "시리얼 넘버", |
|
67 |
- "대여일", |
|
68 |
- "배터리 잔량", |
|
69 |
- "사용자", |
|
70 |
- ]; |
|
71 |
- const key2 = [ |
|
72 |
- "No", |
|
73 |
- "equipment_name", |
|
74 |
- "serialNumber", |
|
75 |
- "name", |
|
76 | 37 |
"battery", |
38 |
+ "rental", |
|
77 | 39 |
"management", |
78 | 40 |
]; |
79 |
- const content2 = [ |
|
41 |
+ const content = [ |
|
80 | 42 |
{ |
43 |
+ "": <input type="checkbox" />, |
|
81 | 44 |
No: 1, |
82 | 45 |
equipment_name: "스마트약상자", |
83 | 46 |
serialNumber: "ABCD-1", |
47 |
+ work: "작동", |
|
84 | 48 |
name: "2022.12.02", |
85 | 49 |
battery: "10%", |
86 |
- management: "김복남" |
|
87 |
- }, |
|
88 |
- ]; |
|
89 |
- |
|
90 |
- |
|
91 |
- |
|
92 |
- const data = [ |
|
93 |
- { |
|
94 |
- id: 1, |
|
95 |
- title: "장비 전체", |
|
96 |
- description: ( |
|
97 |
- <div> |
|
98 |
- <div className="btn-wrap flex-end margin-bottom "> |
|
99 |
- <Button |
|
100 |
- className={"btn-small green-btn"} |
|
101 |
- btnName={"등록"} |
|
102 |
- onClick={() => { |
|
103 |
- navigate("/EquipmentManagementInsert"); |
|
104 |
- }} |
|
105 |
- /> |
|
106 |
- <Button className={"btn-small green-btn"} btnName={"삭제"} /> |
|
107 |
- </div> |
|
108 |
- <Table |
|
109 |
- className={"caregiver-user"} |
|
110 |
- head={thead1} |
|
111 |
- contents={content1} |
|
112 |
- contentKey={key1} |
|
113 |
- /> |
|
114 |
- </div> |
|
115 |
- ), |
|
116 |
- }, |
|
117 |
- { |
|
118 |
- id: 2, |
|
119 |
- title: "미사용 장비", |
|
120 |
- description: ( |
|
121 |
- <div> |
|
122 |
- <Table |
|
123 |
- className={"caregiver-user"} |
|
124 |
- head={thead1} |
|
125 |
- contents={content1} |
|
126 |
- contentKey={key1} |
|
127 |
- /> |
|
128 |
- </div> |
|
129 |
- ), |
|
130 |
- }, |
|
131 |
- { |
|
132 |
- id: 3, |
|
133 |
- title: "사용중인 장비", |
|
134 |
- description: ( |
|
135 |
- <Table |
|
136 |
- className={"caregiver-user"} |
|
137 |
- head={thead2} |
|
138 |
- contents={content2} |
|
139 |
- contentKey={key2} |
|
50 |
+ rental: "대여가능", |
|
51 |
+ management: ( |
|
52 |
+ <Button |
|
53 |
+ className={"btn-small gray-btn"} |
|
54 |
+ btnName={"사용자 등록"} |
|
55 |
+ onClick={(event) => ( |
|
56 |
+ event.stopPropagation(), navigate("/EquipmentRentalInsert") |
|
57 |
+ )} |
|
140 | 58 |
/> |
141 | 59 |
), |
142 | 60 |
}, |
61 |
+ { |
|
62 |
+ "": <input type="checkbox" />, |
|
63 |
+ No: 2, |
|
64 |
+ equipment_name: "혈압측정기", |
|
65 |
+ serialNumber: "ABCD-2", |
|
66 |
+ work: "수리중", |
|
67 |
+ name: "2022.12.02", |
|
68 |
+ battery: "0%", |
|
69 |
+ rental: "대여중", |
|
70 |
+ management: ( |
|
71 |
+ <Button className={"btn-small gray-btn"} btnName={"사용자 수정"} /> |
|
72 |
+ ), |
|
73 |
+ }, |
|
143 | 74 |
]; |
144 |
- const [index, setIndex] = React.useState(1); |
|
145 | 75 |
return ( |
146 | 76 |
<main> |
147 |
- |
|
148 |
- <div className="tab-container"> |
|
149 |
- <ul className="tab-menu"> |
|
150 |
- {data.map((item) => ( |
|
151 |
- <li |
|
152 |
- key={item.id} |
|
153 |
- className={index === item.id ? "active" : null} |
|
154 |
- onClick={() => setIndex(item.id)} |
|
155 |
- > |
|
156 |
- {item.title} |
|
157 |
- </li> |
|
158 |
- ))} |
|
159 |
- </ul> |
|
160 |
- <div className="content-wrap"> |
|
161 |
- <div className="search-management flex-end margin-bottom2"> |
|
162 |
- <select name="management-agency"> |
|
163 |
- <option value="기관전체">기관전체</option> |
|
164 |
- <option value="대구보훈병원">복지재단1</option> |
|
165 |
- <option value="군위군청">복지재단2</option> |
|
166 |
- <option value="군위군청">복지재단3</option> |
|
167 |
- </select> |
|
168 |
- <select> |
|
169 |
- <option value="이름">이름</option> |
|
170 |
- <option value="아이디">아이디</option> |
|
171 |
- </select> |
|
172 |
- <input type="text" /> |
|
77 |
+ <Modal open={modalOpen} close={closeModal} header="장비등록"> |
|
78 |
+ <div className="board-wrap"> |
|
79 |
+ <table className="equipment-modal margin-bottom"> |
|
80 |
+ <tbody> |
|
81 |
+ <tr> |
|
82 |
+ <th>장비명</th> |
|
83 |
+ <td> |
|
84 |
+ <input type="text" /> |
|
85 |
+ </td> |
|
86 |
+ </tr> |
|
87 |
+ <tr> |
|
88 |
+ <th>시리얼넘버</th> |
|
89 |
+ <td> |
|
90 |
+ <input type="text" /> |
|
91 |
+ </td> |
|
92 |
+ </tr> |
|
93 |
+ <tr> |
|
94 |
+ <th>기기상태</th> |
|
95 |
+ <td> |
|
96 |
+ <input type="text" /> |
|
97 |
+ </td> |
|
98 |
+ </tr> |
|
99 |
+ <tr> |
|
100 |
+ <th>구매일</th> |
|
101 |
+ <td> |
|
102 |
+ <input type="date" /> |
|
103 |
+ </td> |
|
104 |
+ </tr> |
|
105 |
+ </tbody> |
|
106 |
+ </table> |
|
107 |
+ <div> |
|
173 | 108 |
<Button |
174 |
- className={"btn-small gray-btn"} |
|
175 |
- btnName={"검색"} |
|
176 |
- onClick={() => navigate("")} |
|
109 |
+ className={"btn-100 green-btn"} |
|
110 |
+ btnName={"등록"} |
|
111 |
+ onClick={closeModal} |
|
177 | 112 |
/> |
178 | 113 |
</div> |
179 |
- <ul className="tab-content"> |
|
180 |
- {data |
|
181 |
- .filter((item) => index === item.id) |
|
182 |
- .map((item) => ( |
|
183 |
- <li>{item.description}</li> |
|
184 |
- ))} |
|
185 |
- </ul> |
|
114 |
+ </div> |
|
115 |
+ </Modal> |
|
116 |
+ <div className="content-wrap"> |
|
117 |
+ <ContentTitle contentTitle={"장비 조회"} /> |
|
118 |
+ <div className="board-wrap"> |
|
119 |
+ <SubTitle |
|
120 |
+ className="margin-bottom" |
|
121 |
+ explanation={"장비명 클릭 시 상세페이지로 이동합니다."} |
|
122 |
+ /> |
|
123 |
+ <div className="equipment-table"> |
|
124 |
+ <Table |
|
125 |
+ className={"equipment-table"} |
|
126 |
+ head={thead} |
|
127 |
+ contents={content} |
|
128 |
+ contentKey={key} |
|
129 |
+ onClick={() => { |
|
130 |
+ navigate("/EquipmentManagementSelectOne"); |
|
131 |
+ }} |
|
132 |
+ /> |
|
133 |
+ </div> |
|
134 |
+ <div className="btn-wrap flex-end"> |
|
135 |
+ <Button |
|
136 |
+ className={"btn-small green-btn"} |
|
137 |
+ btnName={"등록"} |
|
138 |
+ onClick={openModal} |
|
139 |
+ /> |
|
140 |
+ <Button className={"btn-small gray-btn"} btnName={"삭제"} /> |
|
141 |
+ </div> |
|
186 | 142 |
</div> |
187 | 143 |
</div> |
188 | 144 |
</main> |
--- client/views/pages/healthcare/medicinecare/MedicineCareSelectOne.jsx
+++ client/views/pages/healthcare/medicinecare/MedicineCareSelectOne.jsx
... | ... | @@ -172,9 +172,9 @@ |
172 | 172 |
</tr> |
173 | 173 |
</tbody> |
174 | 174 |
</table> |
175 |
- <div className="btn-wrap flex-center"> |
|
175 |
+ <div className="btn-wrap flex-end"> |
|
176 | 176 |
<Button |
177 |
- className={"btn-large gray-btn"} |
|
177 |
+ className={"btn-small gray-btn"} |
|
178 | 178 |
btnName={"이전"} |
179 | 179 |
onClick={() => { |
180 | 180 |
navigate("/MedicineCareSelect"); |
--- client/views/pages/healthcare/statistics/MedicineStatistics.jsx
+++ client/views/pages/healthcare/statistics/MedicineStatistics.jsx
... | ... | @@ -2,11 +2,10 @@ |
2 | 2 |
import ContentTitle from "../../../component/ContentTitle.jsx"; |
3 | 3 |
import SubTitle from "../../../component/SubTitle.jsx"; |
4 | 4 |
import Button from "../../../component/Button.jsx"; |
5 |
-import Chart3 from "../../../component/chart/Chart3.jsx"; |
|
6 | 5 |
import LineColor from "./../../../component/chart/LineColor.jsx"; |
7 | 6 |
import Donut2 from "./../../../component/chart/Donut2.jsx"; |
8 | 7 |
import ToggleButton from "../../../component/ToggleButton.jsx"; |
9 |
-import Chart from './../../../component/chart/Chart.jsx'; |
|
8 |
+import Chart from "./../../../component/chart/Chart.jsx"; |
|
10 | 9 |
|
11 | 10 |
export default function MedicineStatistics() { |
12 | 11 |
return ( |
... | ... | @@ -15,7 +14,7 @@ |
15 | 14 |
<ContentTitle contentTitle={"복약율 통계"} /> |
16 | 15 |
<div className="board-wrap" style={{ height: "calc(100% - 60px)" }}> |
17 | 16 |
<div className="statistics-grid" style={{ height: "100%" }}> |
18 |
- <div> |
|
17 |
+ <div className=" combine-top-government"> |
|
19 | 18 |
<SubTitle |
20 | 19 |
className="margin-bottom" |
21 | 20 |
explanation={"토탈 복약율 통계"} |
... | ... | @@ -38,25 +37,6 @@ |
38 | 37 |
</div> |
39 | 38 |
</div> |
40 | 39 |
<Donut2 /> |
41 |
- </div> |
|
42 |
- </div> |
|
43 |
- <div> |
|
44 |
- <div className="flex"> |
|
45 |
- <SubTitle |
|
46 |
- className="margin-bottom" |
|
47 |
- explanation={"나이대별 복약율 통계"} |
|
48 |
- color={"#333333"} |
|
49 |
- /> |
|
50 |
- </div> |
|
51 |
- <div |
|
52 |
- style={{ |
|
53 |
- border: "1px solid #eeeeee", |
|
54 |
- borderRadius: "0.5rem", |
|
55 |
- padding: "1rem", |
|
56 |
- height: "calc(100% - 47px)", |
|
57 |
- }} |
|
58 |
- > |
|
59 |
- <Chart3 /> |
|
60 | 40 |
</div> |
61 | 41 |
</div> |
62 | 42 |
<div> |
--- client/views/pages/healthcare/temperature/TemperatureManagementSelectOne.jsx
+++ client/views/pages/healthcare/temperature/TemperatureManagementSelectOne.jsx
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 |
import ClusteredColumnChart from "../../../component/chart/ClusteredColumnChart.jsx"; |
3 | 3 |
import ContentTitle from "../../../component/ContentTitle.jsx"; |
4 | 4 |
import TableTitle from "../../../component/Tabletitle.jsx"; |
5 |
+import Button from "../../../component/Button.jsx"; |
|
5 | 6 |
|
6 | 7 |
export default function TemperatureManagementSelectOne() { |
7 | 8 |
return ( |
... | ... | @@ -46,6 +47,15 @@ |
46 | 47 |
</tr> |
47 | 48 |
</tbody> |
48 | 49 |
</table> |
50 |
+ <div className="btn-wrap flex-end"> |
|
51 |
+ <Button |
|
52 |
+ className={"btn-small gray-btn"} |
|
53 |
+ btnName={"이전"} |
|
54 |
+ onClick={() => { |
|
55 |
+ navigate("/TemperatureManagementSelect"); |
|
56 |
+ }} |
|
57 |
+ /> |
|
58 |
+ </div> |
|
49 | 59 |
</div> |
50 | 60 |
</div> |
51 | 61 |
</main> |
--- client/views/pages/join/Join.jsx
+++ client/views/pages/join/Join.jsx
... | ... | @@ -4,119 +4,119 @@ |
4 | 4 |
export default function Join() { |
5 | 5 |
const navigate = useNavigate(); |
6 | 6 |
return ( |
7 |
- <div className="container row flex-center join-login"> |
|
8 |
- <div className="join-group"> |
|
9 |
- <h3>회원가입</h3> |
|
10 |
- <div className="join-inner"> |
|
11 |
- <div> |
|
12 |
- <div className="flex-start margin-bottom2"> |
|
13 |
- <label className="flex25">구분</label> |
|
14 |
- <select name="division" id="section"> |
|
15 |
- <option value="manager">관리자</option> |
|
16 |
- <option value="individual">개인</option> |
|
17 |
- <option value="protection_agency">보호기관</option> |
|
18 |
- <option value="hospital">병원</option> |
|
19 |
- <option value="government">지자체</option> |
|
20 |
- </select> |
|
21 |
- </div> |
|
7 |
+ <div className="container row flex-center join-login"> |
|
8 |
+ <div className="join-group"> |
|
9 |
+ <h3>회원가입</h3> |
|
10 |
+ <div className="join-inner"> |
|
11 |
+ <div> |
|
12 |
+ <div className="flex-start margin-bottom2"> |
|
13 |
+ <label className="flex25">구분</label> |
|
14 |
+ <select name="division" id="section"> |
|
15 |
+ <option value="manager">관리자</option> |
|
16 |
+ <option value="individual">개인</option> |
|
17 |
+ <option value="protection_agency">보호기관</option> |
|
18 |
+ <option value="hospital">병원</option> |
|
19 |
+ <option value="government">지자체</option> |
|
20 |
+ </select> |
|
22 | 21 |
</div> |
23 |
- <div> |
|
24 |
- <div className="flex-start margin-bottom2"> |
|
25 |
- <label className="flex25" htmlFor="name"> |
|
26 |
- 기관명 |
|
27 |
- </label> |
|
28 |
- <select name="division" id="section"> |
|
29 |
- <option value="manager">기관명</option> |
|
30 |
- </select> |
|
31 |
- </div> |
|
22 |
+ </div> |
|
23 |
+ <div> |
|
24 |
+ <div className="flex-start margin-bottom2"> |
|
25 |
+ <label className="flex25" htmlFor="name"> |
|
26 |
+ 기관명 |
|
27 |
+ </label> |
|
28 |
+ <select name="division" id="section"> |
|
29 |
+ <option value="manager">기관명</option> |
|
30 |
+ </select> |
|
32 | 31 |
</div> |
33 |
- <div> |
|
34 |
- <div className="flex-start margin-bottom2"> |
|
35 |
- <label className="flex25" htmlFor="name"> |
|
36 |
- 이름 |
|
37 |
- </label> |
|
38 |
- <input |
|
39 |
- type="text" |
|
40 |
- name="name" |
|
41 |
- placeholder="" |
|
42 |
- autocomplete="off" |
|
43 |
- id="name" |
|
44 |
- /> |
|
45 |
- </div> |
|
46 |
- </div> |
|
47 |
- <div className="id"> |
|
48 |
- <div className="flex-start margin-bottom2"> |
|
49 |
- <label className="flex25" htmlFor="id"> |
|
50 |
- 아이디 |
|
51 |
- </label> |
|
52 |
- <input |
|
53 |
- type="text" |
|
54 |
- name="id" |
|
55 |
- placeholder="" |
|
56 |
- autocomplete="off" |
|
57 |
- id="id" |
|
58 |
- /> |
|
59 |
- <Button |
|
60 |
- btnName={"중복확인"} |
|
61 |
- className={"green-btn btn-large"} |
|
62 |
- onclick="openIdChk()" |
|
63 |
- /> |
|
64 |
- </div> |
|
65 |
- </div> |
|
66 |
- <div> |
|
67 |
- <div className="flex-start margin-bottom2"> |
|
68 |
- <label className="flex25" htmlFor="password"> |
|
69 |
- 비밀번호 |
|
70 |
- </label> |
|
71 |
- <input |
|
72 |
- type="text" |
|
73 |
- name="password" |
|
74 |
- placeholder="" |
|
75 |
- autocomplete="off" |
|
76 |
- id="password" |
|
77 |
- /> |
|
78 |
- </div> |
|
79 |
- </div> |
|
80 |
- <div> |
|
81 |
- <div className="flex-start margin-bottom2"> |
|
82 |
- <label className="flex25" htmlFor="password_check"> |
|
83 |
- 비밀번호 확인 |
|
84 |
- </label> |
|
85 |
- <input |
|
86 |
- type="text" |
|
87 |
- name="password_check" |
|
88 |
- placeholder="" |
|
89 |
- autocomplete="off" |
|
90 |
- id="password_check" |
|
91 |
- /> |
|
92 |
- </div> |
|
93 |
- </div> |
|
94 |
- <div> |
|
95 |
- <div className="flex margin-bottom2"> |
|
96 |
- <label className="flex25" htmlFor="phone_number"> |
|
97 |
- 전화번호 |
|
98 |
- </label> |
|
99 |
- <input |
|
100 |
- type="text" |
|
101 |
- name="phone_number" |
|
102 |
- placeholder="" |
|
103 |
- autocomplete="off" |
|
104 |
- id="phone_number" |
|
105 |
- /> |
|
106 |
- </div> |
|
107 |
- </div> |
|
108 |
- <div className="btn-wrap"> |
|
109 |
- <Button className={"gray-btn btn-large"} btnName={"취소"} /> |
|
110 |
- <Button |
|
111 |
- className={"green-btn btn-large"} |
|
112 |
- btnName={"등록"} |
|
113 |
- onClick={() => { |
|
114 |
- navigate("Login"); |
|
115 |
- }} |
|
32 |
+ </div> |
|
33 |
+ <div> |
|
34 |
+ <div className="flex-start margin-bottom2"> |
|
35 |
+ <label className="flex25" htmlFor="name"> |
|
36 |
+ 이름 |
|
37 |
+ </label> |
|
38 |
+ <input |
|
39 |
+ type="text" |
|
40 |
+ name="name" |
|
41 |
+ placeholder="" |
|
42 |
+ autocomplete="off" |
|
43 |
+ id="name" |
|
116 | 44 |
/> |
117 | 45 |
</div> |
118 | 46 |
</div> |
47 |
+ <div className="id"> |
|
48 |
+ <div className="flex-start margin-bottom2"> |
|
49 |
+ <label className="flex25" htmlFor="id"> |
|
50 |
+ 아이디 |
|
51 |
+ </label> |
|
52 |
+ <input |
|
53 |
+ type="text" |
|
54 |
+ name="id" |
|
55 |
+ placeholder="" |
|
56 |
+ autocomplete="off" |
|
57 |
+ id="id" |
|
58 |
+ /> |
|
59 |
+ <Button |
|
60 |
+ btnName={"중복확인"} |
|
61 |
+ className={"green-btn btn-large"} |
|
62 |
+ onclick="openIdChk()" |
|
63 |
+ /> |
|
64 |
+ </div> |
|
65 |
+ </div> |
|
66 |
+ <div> |
|
67 |
+ <div className="flex-start margin-bottom2"> |
|
68 |
+ <label className="flex25" htmlFor="password"> |
|
69 |
+ 비밀번호 |
|
70 |
+ </label> |
|
71 |
+ <input |
|
72 |
+ type="text" |
|
73 |
+ name="password" |
|
74 |
+ placeholder="" |
|
75 |
+ autocomplete="off" |
|
76 |
+ id="password" |
|
77 |
+ /> |
|
78 |
+ </div> |
|
79 |
+ </div> |
|
80 |
+ <div> |
|
81 |
+ <div className="flex-start margin-bottom2"> |
|
82 |
+ <label className="flex25" htmlFor="password_check"> |
|
83 |
+ 비밀번호 확인 |
|
84 |
+ </label> |
|
85 |
+ <input |
|
86 |
+ type="text" |
|
87 |
+ name="password_check" |
|
88 |
+ placeholder="" |
|
89 |
+ autocomplete="off" |
|
90 |
+ id="password_check" |
|
91 |
+ /> |
|
92 |
+ </div> |
|
93 |
+ </div> |
|
94 |
+ <div> |
|
95 |
+ <div className="flex margin-bottom2"> |
|
96 |
+ <label className="flex25" htmlFor="phone_number"> |
|
97 |
+ 전화번호 |
|
98 |
+ </label> |
|
99 |
+ <input |
|
100 |
+ type="text" |
|
101 |
+ name="phone_number" |
|
102 |
+ placeholder="" |
|
103 |
+ autocomplete="off" |
|
104 |
+ id="phone_number" |
|
105 |
+ /> |
|
106 |
+ </div> |
|
107 |
+ </div> |
|
108 |
+ <div className="btn-wrap"> |
|
109 |
+ <Button className={"gray-btn btn-large"} btnName={"취소"} /> |
|
110 |
+ <Button |
|
111 |
+ className={"green-btn btn-large"} |
|
112 |
+ btnName={"등록"} |
|
113 |
+ onClick={() => { |
|
114 |
+ navigate("Login"); |
|
115 |
+ }} |
|
116 |
+ /> |
|
117 |
+ </div> |
|
119 | 118 |
</div> |
120 | 119 |
</div> |
120 |
+ </div> |
|
121 | 121 |
); |
122 | 122 |
} |
--- client/views/pages/login/Login.jsx
+++ client/views/pages/login/Login.jsx
... | ... | @@ -1,6 +1,6 @@ |
1 | 1 |
import React from "react"; |
2 | 2 |
import Button from "../../component/Button.jsx"; |
3 |
-import { useNavigate } from "react-router"; |
|
3 |
+import Join from "./../join/Join.jsx"; |
|
4 | 4 |
|
5 | 5 |
export default function Login({ getLogin }) { |
6 | 6 |
const [isJoin, setIsJoin] = React.useState(false); |
... | ... | @@ -11,132 +11,53 @@ |
11 | 11 |
const onClickLogin = (loginComponentName) => { |
12 | 12 |
getLogin(loginComponentName); |
13 | 13 |
}; |
14 |
- |
|
15 |
- function a () { |
|
16 |
- console.log("a함수 실행!"); |
|
17 |
- } |
|
18 |
- |
|
19 |
- a(); |
|
20 |
- |
|
21 |
- const data = [ |
|
22 |
- { |
|
23 |
- id: 1, |
|
24 |
- title: "복지관(관리자)", |
|
25 |
- description: ( |
|
26 |
- <div className="login-inner"> |
|
27 |
- <div> |
|
28 |
- <div className="content"> |
|
29 |
- <i className="fa-solid fa-user"></i> |
|
30 |
- <input |
|
31 |
- required |
|
32 |
- maxlength="15" |
|
33 |
- type="text" |
|
34 |
- placeholder="아이디를 입력하세요" |
|
35 |
- /> |
|
36 |
- </div> |
|
37 |
- <div className="content"> |
|
38 |
- <i className="fa-solid fa-lock"></i> |
|
39 |
- <input |
|
40 |
- type="password" |
|
41 |
- name="password" |
|
42 |
- placeholder="비밀번호를 입력하세요" |
|
43 |
- /> |
|
44 |
- </div> |
|
45 |
- </div> |
|
46 |
- <div className="btn-wrap"> |
|
47 |
- <Button |
|
48 |
- className={"btn-100 green-btn"} |
|
49 |
- btnName={"로그인"} |
|
50 |
- onClick={() => onClickLogin('/Main')} |
|
51 |
- /> |
|
52 |
- <div className="flex-center btn-bottom"> |
|
53 |
- <Button |
|
54 |
- className={"join-btn"} |
|
55 |
- btnName={"회원가입"} |
|
56 |
- onClick={onClickJoin} |
|
57 |
- /> |
|
58 |
- </div> |
|
59 |
- </div> |
|
60 |
- </div> |
|
61 |
- ), |
|
62 |
- }, |
|
63 |
- { |
|
64 |
- id: 2, |
|
65 |
- title: "보호사", |
|
66 |
- description: ( |
|
67 |
- <div className="login-inner"> |
|
68 |
- <div> |
|
69 |
- <div className="content"> |
|
70 |
- <i className="fa-solid fa-user"></i> |
|
71 |
- <input |
|
72 |
- required |
|
73 |
- maxlength="15" |
|
74 |
- type="text" |
|
75 |
- placeholder="아이디를 입력하세요" |
|
76 |
- /> |
|
77 |
- </div> |
|
78 |
- <div className="content"> |
|
79 |
- <i className="fa-solid fa-lock"></i> |
|
80 |
- <input |
|
81 |
- type="password" |
|
82 |
- name="password" |
|
83 |
- placeholder="비밀번호를 입력하세요" |
|
84 |
- /> |
|
85 |
- </div> |
|
86 |
- </div> |
|
87 |
- <div className="btn-wrap"> |
|
88 |
- <Button |
|
89 |
- className={"btn-100 green-btn"} |
|
90 |
- btnName={"로그인"} |
|
91 |
- onClick={() => onClickLogin('/Main3')} |
|
92 |
- /> |
|
93 |
- <div className="flex-center btn-bottom"> |
|
94 |
- <Button |
|
95 |
- className={"join-btn"} |
|
96 |
- btnName={"회원가입"} |
|
97 |
- onClick={onClickJoin} |
|
98 |
- /> |
|
99 |
- </div> |
|
100 |
- </div> |
|
101 |
- </div> |
|
102 |
- ), |
|
103 |
- }, |
|
104 |
- ]; |
|
105 |
- const [index, setIndex] = React.useState(1); |
|
106 | 14 |
return ( |
107 |
- <main> |
|
108 |
- <div className="row login-wrap"> |
|
109 |
- <h1>시니어 스마트 케어 모니터링 플랫폼</h1> |
|
110 |
- {isJoin ? ( |
|
111 |
- <Join /> |
|
112 |
- ) : ( |
|
113 |
- <div className="tab-container"> |
|
114 |
- <ul className="tab-menu"> |
|
115 |
- {data.map((item) => ( |
|
116 |
- <li |
|
117 |
- key={item.id} |
|
118 |
- className={index === item.id ? "active" : null} |
|
119 |
- onClick={() => setIndex(item.id)} |
|
120 |
- > |
|
121 |
- {item.title} |
|
122 |
- </li> |
|
123 |
- ))} |
|
124 |
- </ul> |
|
125 |
- <div className="content-wrap"> |
|
126 |
- <ul className="tab-content"> |
|
127 |
- {data |
|
128 |
- .filter((item) => index === item.id) |
|
129 |
- .map((item) => ( |
|
130 |
- <li>{item.description}</li> |
|
131 |
- ))} |
|
132 |
- </ul> |
|
15 |
+ <div className="row login-wrap"> |
|
16 |
+ <h1>시니어 스마트 케어 모니터링 플랫폼</h1> |
|
17 |
+ {isJoin ? ( |
|
18 |
+ <Join /> |
|
19 |
+ ) : ( |
|
20 |
+ <div className="container row flex-center join-login"> |
|
21 |
+ <div className="login-form-guardian"> |
|
22 |
+ <div> |
|
23 |
+ <h3>로그인</h3> |
|
24 |
+ <div className="login-inner"> |
|
25 |
+ <div className="content"> |
|
26 |
+ <i className="fa-solid fa-user"></i> |
|
27 |
+ <input |
|
28 |
+ required |
|
29 |
+ maxlength="15" |
|
30 |
+ type="text" |
|
31 |
+ placeholder="아이디를 입력하세요" |
|
32 |
+ /> |
|
33 |
+ </div> |
|
34 |
+ <div className="content"> |
|
35 |
+ <i className="fa-solid fa-lock"></i> |
|
36 |
+ <input |
|
37 |
+ type="password" |
|
38 |
+ name="password" |
|
39 |
+ placeholder="비밀번호를 입력하세요" |
|
40 |
+ /> |
|
41 |
+ </div> |
|
42 |
+ </div> |
|
43 |
+ </div> |
|
44 |
+ <div className="btn-wrap"> |
|
45 |
+ <Button |
|
46 |
+ className={"btn-100 green-btn"} |
|
47 |
+ btnName={"로그인"} |
|
48 |
+ onClick={() => onClickLogin('/LoginSelect')} |
|
49 |
+ /> |
|
50 |
+ <div className="flex-center btn-bottom"> |
|
51 |
+ <Button |
|
52 |
+ className={"join-btn"} |
|
53 |
+ btnName={"회원가입"} |
|
54 |
+ onClick={onClickJoin} |
|
55 |
+ /> |
|
56 |
+ </div> |
|
133 | 57 |
</div> |
134 | 58 |
</div> |
135 |
- )} |
|
136 |
- </div> |
|
137 |
- |
|
138 |
- |
|
139 |
- |
|
140 |
- </main> |
|
59 |
+ </div> |
|
60 |
+ )} |
|
61 |
+ </div> |
|
141 | 62 |
); |
142 | 63 |
} |
+++ client/views/pages/login/LoginSelect.jsx
... | ... | @@ -0,0 +1,36 @@ |
1 | +import React from "react"; | |
2 | +import Button from "../../component/Button.jsx"; | |
3 | +import Join from "./../join/Join.jsx"; | |
4 | +import Person3Icon from '@mui/icons-material/Person3'; | |
5 | +import Person4Icon from '@mui/icons-material/Person4'; | |
6 | +import AddCircleIcon from '@mui/icons-material/AddCircle'; | |
7 | +import { useNavigate } from "react-router"; | |
8 | + | |
9 | +export default function LoginSelect() { | |
10 | + const navigate = useNavigate(); | |
11 | + return ( | |
12 | + <div className="row login-wrap"> | |
13 | + <div className="container row flex-center"> | |
14 | + <div className="login-select" onClick={() => { | |
15 | + navigate("/Main"); | |
16 | + }}> | |
17 | + <Person3Icon sx={{ fontSize: 50, color: "#1976d2" }}/> | |
18 | + <h3>박말자</h3> | |
19 | + </div> | |
20 | + <div className="login-select" onClick={() => { | |
21 | + navigate("/Main"); | |
22 | + }}> | |
23 | + <Person4Icon sx={{ fontSize: 50, color: "#1976d2" }}/> | |
24 | + <h3>김복남</h3> | |
25 | + </div> | |
26 | + <div className="login-select" onClick={() => { | |
27 | + navigate("/Main"); | |
28 | + }}> | |
29 | + <AddCircleIcon sx={{ fontSize: 50, color: "#1976d2" }}/> | |
30 | + </div> | |
31 | + </div> | |
32 | + </div> | |
33 | + | |
34 | + | |
35 | + ); | |
36 | +} |
+++ client/views/pages/main/CalendarComponent.jsx
... | ... | @@ -0,0 +1,23 @@ |
1 | +import React, { useState } from "react"; | |
2 | +import Calendar from "react-calendar"; | |
3 | +import "react-calendar/dist/Calendar.css"; | |
4 | +import moment from "moment"; | |
5 | + | |
6 | +export default function CalendarComponent(props) { | |
7 | + const [value, setValue] = useState(new Date()); | |
8 | + const mark = ["12-12-2022", "21-12-2022", "05-12-2022", "02-12-2022"]; | |
9 | + return ( | |
10 | + <> | |
11 | + <Calendar | |
12 | + onChange={setValue} | |
13 | + value={value} | |
14 | + tileClassName={({ date, view }) => { | |
15 | + if (mark.find((x) => x === moment(date).format("DD-MM-YYYY"))) { | |
16 | + return "highlight"; | |
17 | + } | |
18 | + }} | |
19 | + /> | |
20 | + </> | |
21 | + ); | |
22 | +} | |
23 | + |
--- client/views/pages/main/Main.jsx
+++ client/views/pages/main/Main.jsx
... | ... | @@ -1,110 +1,146 @@ |
1 | 1 |
import React from "react"; |
2 | 2 |
import Title from "../../component/Title.jsx"; |
3 |
-import Table from "./../../component/Table.jsx"; |
|
4 |
-import Map from "./Map.jsx"; |
|
5 |
-import RowChart from "./RowChart.jsx"; |
|
6 |
-import Chart1 from "./Chart1.jsx"; |
|
7 |
-import Chart2 from "./Chart2.jsx"; |
|
8 |
-import Chart3 from "./Chart3.jsx"; |
|
9 |
-import Weather from "./Weather.jsx"; |
|
10 |
-import Donut1 from "./Donut1.jsx"; |
|
11 |
-import Donut2 from "./Donut2.jsx"; |
|
12 |
-import Donut3 from "./Donut3.jsx"; |
|
3 |
+import Table from "../../component/Table.jsx"; |
|
4 |
+import Chart1 from "../../component/chart/Chart1.jsx"; |
|
5 |
+import CalendarComponent from "./CalendarComponent.jsx"; |
|
13 | 6 |
import AddCircleIcon from "@mui/icons-material/AddCircle"; |
7 |
+import CallIcon from '@mui/icons-material/Call'; |
|
8 |
+import ClearIcon from '@mui/icons-material/Clear'; |
|
9 |
+import BatteryCharging20Icon from '@mui/icons-material/BatteryCharging20'; |
|
10 |
+import DeviceThermostatIcon from '@mui/icons-material/DeviceThermostat'; |
|
11 |
+import MedicationIcon from '@mui/icons-material/Medication'; |
|
12 |
+import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn'; |
|
13 |
+import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; |
|
14 | 14 |
|
15 |
-function Main() { |
|
16 |
- const tableHead = ["이름", "시리얼 넘버", "위치"]; |
|
17 |
- const Key = ["name", "serialNumber", "location"]; |
|
18 |
- const content = [ |
|
15 |
+export default function Main() { |
|
16 |
+ const tableHead1 = ["", "", "", "", "", ""]; |
|
17 |
+ const Key1 = ["morning", "morning2", "lunch","lunch2", "dinner","dinner2"]; |
|
18 |
+ const content1 = [ |
|
19 | 19 |
{ |
20 |
- name: "스마트약상자", |
|
21 |
- serialNumber: "ABCD-1", |
|
22 |
- location: "대구광역시 서구 상중이동", |
|
23 |
- }, |
|
20 |
+ morning: "아침", |
|
21 |
+ morning2:( |
|
22 |
+ <CheckCircleOutlineIcon sx={{ width: "3rem", height: "3rem", color: "#067943", borderRadius: "50px" }}/> |
|
23 |
+ ), |
|
24 |
+ lunch: "점심", |
|
25 |
+ lunch2: ( |
|
26 |
+ <CheckCircleOutlineIcon sx={{ width: "3rem", height: "3rem", color: "#067943", borderRadius: "50px" }}/> |
|
27 |
+ ), |
|
28 |
+ dinner: "저녁", |
|
29 |
+ dinner2: ( |
|
30 |
+ <CheckCircleOutlineIcon sx={{ width: "3rem", height: "3rem", color: "#067943", borderRadius: "50px" }}/> |
|
31 |
+ ), |
|
32 |
+ } |
|
33 |
+ ]; |
|
34 |
+ const tableHead2 = ["", "", "", "", "", ""]; |
|
35 |
+ const Key2 = ["morning", "morning2", "lunch","lunch2", "dinner","dinner2"]; |
|
36 |
+ const content2 = [ |
|
24 | 37 |
{ |
25 |
- name: "스마트약상자", |
|
26 |
- serialNumber: "ABCD-2", |
|
27 |
- location: "대구광역시 서구 내당4동", |
|
28 |
- }, |
|
38 |
+ morning: "아침", |
|
39 |
+ morning2:( |
|
40 |
+ <ClearIcon sx={{ width: "3rem", height: "3rem", color: "#bf0629", borderRadius: "50px" }}/> |
|
41 |
+ ), |
|
42 |
+ lunch: "점심", |
|
43 |
+ lunch2: ( |
|
44 |
+ <ClearIcon sx={{ width: "3rem", height: "3rem", color: "#bf0629", borderRadius: "50px" }}/> |
|
45 |
+ ), |
|
46 |
+ dinner: "저녁", |
|
47 |
+ dinner2: ( |
|
48 |
+ <ClearIcon sx={{ width: "3rem", height: "3rem", color: "#bf0629", borderRadius: "50px" }}/> |
|
49 |
+ ), |
|
50 |
+ } |
|
51 |
+ ]; |
|
52 |
+ const tableHead3 = ["월", "화", "수", "목", "금", "토", "일"]; |
|
53 |
+ const Key3 = ["mon", "tue", "wed","thu", "fri","sat","sun"]; |
|
54 |
+ const content3 = [ |
|
29 | 55 |
{ |
30 |
- name: "스마트약상자", |
|
31 |
- serialNumber: "ABCD-3", |
|
32 |
- location: "대구광역시 서구 내당2,3동", |
|
33 |
- }, |
|
34 |
- { |
|
35 |
- name: "스마트약상자", |
|
36 |
- serialNumber: "ABCD-4", |
|
37 |
- location: "대구광역시 서구 평리3동", |
|
38 |
- }, |
|
39 |
- { |
|
40 |
- name: "스마트약상자", |
|
41 |
- serialNumber: "ABCD-5", |
|
42 |
- location: "대구광역시 서구 내당1동", |
|
43 |
- }, |
|
56 |
+ mon: "24°C", |
|
57 |
+ tue: "24°C", |
|
58 |
+ wed: "24°C", |
|
59 |
+ thu: "24°C", |
|
60 |
+ fri: "24°C", |
|
61 |
+ sat: "24°C", |
|
62 |
+ sun: "24°C", |
|
63 |
+ } |
|
44 | 64 |
]; |
45 | 65 |
|
66 |
+ |
|
46 | 67 |
return ( |
47 |
- <main> |
|
48 |
- <div className="main-grid-government"> |
|
49 |
- <div className="content-box combine-left"> |
|
50 |
- <div className="flex margin-bottom"> |
|
51 |
- <Title title={"케어 노인 분포 현황"} /> |
|
52 |
- <AddCircleIcon sx={{ fontSize: 20, color: "#1976d2" }} /> |
|
53 |
- </div> |
|
54 |
- <Map /> |
|
55 |
- </div> |
|
56 |
- <div className="content-box "> |
|
57 |
- <div className="margin-bottom"> |
|
58 |
- <Title title={"노인 분포도"} /> |
|
59 |
- </div> |
|
60 |
- <RowChart /> |
|
61 |
- </div> |
|
62 |
- <div className="content-box"> |
|
63 |
- <div className="margin-bottom"> |
|
64 |
- <Title title={"요양 등급별 노인 현황"} /> |
|
65 |
- </div> |
|
66 |
- <Donut1 /> |
|
67 |
- </div> |
|
68 |
- <div className="content-box"> |
|
69 |
- <div> |
|
70 |
- <div className="flex margin-bottom"> |
|
71 |
- <Title title={"노인 외출 현황"} /> |
|
72 |
- <AddCircleIcon sx={{ fontSize: 20, color: "#1976d2" }} /> |
|
73 |
- </div> |
|
74 |
- <Donut2 /> |
|
68 |
+ <> |
|
69 |
+ <main> |
|
70 |
+ <div className="main-grid-guardian"> |
|
71 |
+ <ul className="content-box statistics"> |
|
72 |
+ <li className="flex-start"> |
|
73 |
+ <p><AssignmentTurnedInIcon sx={{ width: "5rem", height: "5rem", color: "#bf0629", borderRadius: "50px" }} /></p> |
|
74 |
+ <p>방문 체크</p> |
|
75 |
+ <p>이번달 보호사님이 방문한 횟수는 총 4회 입니다.</p> |
|
76 |
+ </li> |
|
77 |
+ <CalendarComponent /> |
|
78 |
+ </ul> |
|
79 |
+ <ul className="content-box statistics"> |
|
80 |
+ <li className="flex-start"> |
|
81 |
+ <p><MedicationIcon sx={{ width: "5rem", height: "5rem", color: "#0dd390", borderRadius: "50px" }} /></p> |
|
82 |
+ <p>복약 체크</p> |
|
83 |
+ <p>약을 잘 복용하고 계신지 체크해주세요</p> |
|
84 |
+ </li> |
|
85 |
+ <li className="flex"> |
|
86 |
+ <p className="guardian-table-text">어제</p> |
|
87 |
+ <p className="guardian-table-inner"><Table |
|
88 |
+ className={"guardian-table"} |
|
89 |
+ head={tableHead1} |
|
90 |
+ contents={content1} |
|
91 |
+ contentKey={Key1} |
|
92 |
+ /></p> |
|
93 |
+ </li> |
|
94 |
+ <li className="flex"> |
|
95 |
+ <p className="guardian-table-text">2일 전</p> |
|
96 |
+ <p className="guardian-table-inner"><Table |
|
97 |
+ className={"guardian-table"} |
|
98 |
+ head={tableHead2} |
|
99 |
+ contents={content2} |
|
100 |
+ contentKey={Key2} |
|
101 |
+ /></p> |
|
102 |
+ </li> |
|
103 |
+ <li className="flex"> |
|
104 |
+ <p className="guardian-table-text">3일 전</p> |
|
105 |
+ <p className="guardian-table-inner"><Table |
|
106 |
+ className={"guardian-table"} |
|
107 |
+ head={tableHead1} |
|
108 |
+ contents={content1} |
|
109 |
+ contentKey={Key1} |
|
110 |
+ /></p> |
|
111 |
+ </li> |
|
112 |
+ </ul> |
|
113 |
+ <ul className="content-box statistics"> |
|
114 |
+ <li className="flex-start"> |
|
115 |
+ <p><DeviceThermostatIcon sx={{ width: "5rem", height: "5rem", color: "#f1de05", borderRadius: "50px" }} /></p> |
|
116 |
+ <p>온도 체크</p> |
|
117 |
+ <p>댁내 온도가 적절한지 체크해보세요.</p> |
|
118 |
+ </li> |
|
119 |
+ <li className="flex"> |
|
120 |
+ <p className="guardian-table-inner"><Table |
|
121 |
+ className={"guardian-table1"} |
|
122 |
+ head={tableHead3} |
|
123 |
+ contents={content3} |
|
124 |
+ contentKey={Key3} |
|
125 |
+ /></p> |
|
126 |
+ </li> |
|
127 |
+ </ul> |
|
128 |
+ <ul className="content-box statistics"> |
|
129 |
+ <li className="flex-start"> |
|
130 |
+ <p><BatteryCharging20Icon sx={{ width: "5rem", height: "5rem", color: "#5f9af3", borderRadius: "50px" }} /></p> |
|
131 |
+ <p>현재 스마트 약상자의 배터리가 40% 입니다.</p> |
|
132 |
+ <p></p> |
|
133 |
+ </li> |
|
134 |
+ <li> |
|
135 |
+ <p className="red">충전이 필요합니다.</p> |
|
136 |
+ </li> |
|
137 |
+ </ul> |
|
138 |
+ <div className="content-box combine-left combine-all-government"> |
|
139 |
+ <Title title={"김복남 어르신"} explanation={"방문, 복약, 온도, 배터리 현황을 확인하세요."} /> |
|
140 |
+ |
|
75 | 141 |
</div> |
76 | 142 |
</div> |
77 |
- <div className="content-box"> |
|
78 |
- <div className="flex margin-bottom"> |
|
79 |
- <Title title={"장기 미복약 현황"} /> |
|
80 |
- <AddCircleIcon sx={{ fontSize: 20, color: "#1976d2" }} /> |
|
81 |
- </div> |
|
82 |
- <Donut3 /> |
|
83 |
- </div> |
|
84 |
- <div className="content-box combine-right-government"> |
|
85 |
- <div className="flex margin-bottom"> |
|
86 |
- <Title title={"약상자 여닫음 횟수 통계"} /> |
|
87 |
- <AddCircleIcon sx={{ fontSize: 20, color: "#1976d2" }} /> |
|
88 |
- </div> |
|
89 |
- <Chart1 /> |
|
90 |
- </div> |
|
91 |
- <div className="content-box combine-left"> |
|
92 |
- <div className="flex margin-bottom"> |
|
93 |
- <Title title={"월별 방문 현황 통계"} /> |
|
94 |
- <AddCircleIcon sx={{ fontSize: 20, color: "#1976d2" }} /> |
|
95 |
- </div> |
|
96 |
- <Chart3 /> |
|
97 |
- </div> |
|
98 |
- <div className="content-box combine-right-government"> |
|
99 |
- <div className="flex margin-bottom"> |
|
100 |
- <Title title={"장비현황"} /> |
|
101 |
- <AddCircleIcon sx={{ fontSize: 20, color: "#1976d2" }} /> |
|
102 |
- </div> |
|
103 |
- <Table head={tableHead} contents={content} contentKey={Key} /> |
|
104 |
- </div> |
|
105 |
- </div> |
|
106 |
- </main> |
|
143 |
+ </main> |
|
144 |
+ </> |
|
107 | 145 |
); |
108 | 146 |
} |
109 |
- |
|
110 |
-export default Main; |
+++ client/views/pages/main/Map.jsx
... | ... | @@ -0,0 +1,316 @@ |
1 | +import React, { Component } from "react"; | |
2 | +import * as am5 from "@amcharts/amcharts5"; | |
3 | +import * as am5map from "@amcharts/amcharts5/map"; | |
4 | +import am5geodata_usaLow from "../../component/map"; | |
5 | +import am5themes_Animated from "@amcharts/amcharts5/themes/Animated"; | |
6 | +// import seniorjson from "../../component/senior.json"; | |
7 | + | |
8 | +class Map extends Component { | |
9 | + componentDidMount() { | |
10 | + let root = am5.Root.new("Map"); | |
11 | + root.setThemes([am5themes_Animated.new(root)]); | |
12 | + | |
13 | + let chart = root.container.children.push( | |
14 | + am5map.MapChart.new(root, { | |
15 | + panX: "rotateX", | |
16 | + // projection: am5map.geoAlbersUsa(), | |
17 | + }) | |
18 | + ); | |
19 | + | |
20 | + // Create polygon series | |
21 | + let polygonSeries = chart.series.push( | |
22 | + am5map.MapPolygonSeries.new(root, { | |
23 | + geoJSON: am5geodata_usaLow, | |
24 | + }) | |
25 | + ); | |
26 | + | |
27 | + polygonSeries.mapPolygons.template.setAll({ | |
28 | + tooltipText: "{name}", | |
29 | + }); | |
30 | + | |
31 | + polygonSeries.mapPolygons.template.states.create("hover", { | |
32 | + fill: am5.color(0x297373), | |
33 | + }); | |
34 | + | |
35 | + let zoomOut = root.tooltipContainer.children.push( | |
36 | + am5.Button.new(root, { | |
37 | + x: am5.p100, | |
38 | + y: 0, | |
39 | + centerX: am5.p100, | |
40 | + centerY: 0, | |
41 | + paddingTop: 18, | |
42 | + paddingBottom: 18, | |
43 | + paddingLeft: 12, | |
44 | + paddingRight: 12, | |
45 | + dx: -20, | |
46 | + dy: 20, | |
47 | + themeTags: ["zoom"], | |
48 | + icon: am5.Graphics.new(root, { | |
49 | + themeTags: ["button", "icon"], | |
50 | + strokeOpacity: 0.7, | |
51 | + draw: function (display) { | |
52 | + display.moveTo(0, 0); | |
53 | + display.lineTo(12, 0); | |
54 | + }, | |
55 | + }), | |
56 | + }) | |
57 | + ); | |
58 | + | |
59 | + zoomOut.get("background").setAll({ | |
60 | + cornerRadiusBL: 40, | |
61 | + cornerRadiusBR: 40, | |
62 | + cornerRadiusTL: 40, | |
63 | + cornerRadiusTR: 40, | |
64 | + }); | |
65 | + zoomOut.events.on("click", function () { | |
66 | + if (currentSeries) { | |
67 | + currentSeries.hide(); | |
68 | + } | |
69 | + chart.goHome(); | |
70 | + zoomOut.hide(); | |
71 | + currentSeries = regionalSeries.US.series; | |
72 | + currentSeries.show(); | |
73 | + }); | |
74 | + zoomOut.hide(); | |
75 | + | |
76 | + // ================================= | |
77 | + // Set up point series | |
78 | + // ================================= | |
79 | + | |
80 | + // Load senior data | |
81 | + am5.net | |
82 | + .load( | |
83 | + "https://gist.githubusercontent.com/dbskfnd/e618b91a622b8efeb55ccc562c47864a/raw/23d9030fe1e6e42d6e43348d86b02f6aafa464e2/seniornumber.json" | |
84 | + ) | |
85 | + .then(function (result) { | |
86 | + let seniors = am5.JSONParser.parse(result.response); | |
87 | + setupseniors(seniors); | |
88 | + }); | |
89 | + | |
90 | + let regionalSeries = {}; | |
91 | + let currentSeries; | |
92 | + | |
93 | + // Parses data and creats map point series for domestic and state-level | |
94 | + function setupseniors(data) { | |
95 | + console.log(data); | |
96 | + | |
97 | + // Init country-level series | |
98 | + regionalSeries.US = { | |
99 | + markerData: [], | |
100 | + series: createSeries("seniors"), | |
101 | + }; | |
102 | + | |
103 | + // Set current series | |
104 | + currentSeries = regionalSeries.US.series; | |
105 | + | |
106 | + // Process data | |
107 | + am5.array.each(data.query_results, function (senior) { | |
108 | + // Get senior data | |
109 | + senior = { | |
110 | + state: senior.MAIL_ST_PROV_C, | |
111 | + long: am5.type.toNumber(senior.LNGTD_I), | |
112 | + lat: am5.type.toNumber(senior.LATTD_I), | |
113 | + location: senior.co_loc_n, | |
114 | + city: senior.mail_city_n, | |
115 | + count: am5.type.toNumber(senior.count), | |
116 | + }; | |
117 | + | |
118 | + // Process state-level data | |
119 | + if (regionalSeries[senior.state] == undefined) { | |
120 | + let statePolygon = getPolygon("KR-" + senior.state); | |
121 | + if (statePolygon) { | |
122 | + let centroid = statePolygon.visualCentroid(); | |
123 | + | |
124 | + // Add state data | |
125 | + regionalSeries[senior.state] = { | |
126 | + target: senior.state, | |
127 | + type: "state", | |
128 | + name: statePolygon.dataItem.dataContext.name, | |
129 | + count: senior.count, | |
130 | + seniors: 1, | |
131 | + state: senior.state, | |
132 | + markerData: [], | |
133 | + geometry: { | |
134 | + type: "Point", | |
135 | + coordinates: [centroid.longitude, centroid.latitude], | |
136 | + }, | |
137 | + }; | |
138 | + regionalSeries.US.markerData.push(regionalSeries[senior.state]); | |
139 | + } else { | |
140 | + // State not found | |
141 | + return; | |
142 | + } | |
143 | + } else { | |
144 | + regionalSeries[senior.state].seniors++; | |
145 | + regionalSeries[senior.state].count += senior.count; | |
146 | + } | |
147 | + | |
148 | + // Process city-level data | |
149 | + if (regionalSeries[senior.city] == undefined) { | |
150 | + regionalSeries[senior.city] = { | |
151 | + target: senior.city, | |
152 | + type: "city", | |
153 | + name: senior.city, | |
154 | + count: senior.count, | |
155 | + seniors: 1, | |
156 | + state: senior.state, | |
157 | + markerData: [], | |
158 | + geometry: { | |
159 | + type: "Point", | |
160 | + coordinates: [senior.long, senior.lat], | |
161 | + }, | |
162 | + }; | |
163 | + regionalSeries[senior.state].markerData.push( | |
164 | + regionalSeries[senior.city] | |
165 | + ); | |
166 | + } else { | |
167 | + regionalSeries[senior.city].seniors++; | |
168 | + regionalSeries[senior.city].count += senior.count; | |
169 | + } | |
170 | + | |
171 | + // Process individual senior | |
172 | + regionalSeries[senior.city].markerData.push({ | |
173 | + name: senior.location, | |
174 | + count: senior.count, | |
175 | + seniors: 1, | |
176 | + state: senior.state, | |
177 | + geometry: { | |
178 | + type: "Point", | |
179 | + coordinates: [senior.long, senior.lat], | |
180 | + }, | |
181 | + }); | |
182 | + }); | |
183 | + console.log(regionalSeries.US.markerData); | |
184 | + regionalSeries.US.series.data.setAll(regionalSeries.US.markerData); | |
185 | + } | |
186 | + | |
187 | + // Finds polygon in series by its id | |
188 | + function getPolygon(id) { | |
189 | + let found; | |
190 | + polygonSeries.mapPolygons.each(function (polygon) { | |
191 | + if (polygon.dataItem.get("id") == id) { | |
192 | + found = polygon; | |
193 | + } | |
194 | + }); | |
195 | + return found; | |
196 | + } | |
197 | + | |
198 | + // Creates series with heat rules | |
199 | + function createSeries(heatfield) { | |
200 | + // Create point series | |
201 | + let pointSeries = chart.series.push( | |
202 | + am5map.MapPointSeries.new(root, { | |
203 | + valueField: heatfield, | |
204 | + calculateAggregates: true, | |
205 | + }) | |
206 | + ); | |
207 | + | |
208 | + // Add senior bullet | |
209 | + let circleTemplate = am5.Template.new(root); | |
210 | + pointSeries.bullets.push(function () { | |
211 | + let container = am5.Container.new(root, {}); | |
212 | + | |
213 | + let circle = container.children.push( | |
214 | + am5.Circle.new( | |
215 | + root, | |
216 | + { | |
217 | + radius: 10, | |
218 | + fill: am5.color(0x000000), | |
219 | + fillOpacity: 0.7, | |
220 | + cursorOverStyle: "pointer", | |
221 | + tooltipText: "{name}:\n[bold]{seniors} seniors[/]", | |
222 | + }, | |
223 | + circleTemplate | |
224 | + ) | |
225 | + ); | |
226 | + | |
227 | + let label = container.children.push( | |
228 | + am5.Label.new(root, { | |
229 | + text: "{seniors}", | |
230 | + fill: am5.color(0xffffff), | |
231 | + populateText: true, | |
232 | + centerX: am5.p50, | |
233 | + centerY: am5.p50, | |
234 | + textAlign: "center", | |
235 | + }) | |
236 | + ); | |
237 | + | |
238 | + // Set up drill-down | |
239 | + circle.events.on("click", function (ev) { | |
240 | + // Determine what we've clicked on | |
241 | + let data = ev.target.dataItem.dataContext; | |
242 | + | |
243 | + // No id? Individual senior - nothing to drill down to further | |
244 | + if (!data.target) { | |
245 | + return; | |
246 | + } | |
247 | + | |
248 | + // Create actual series if it hasn't been yet created | |
249 | + if (!regionalSeries[data.target].series) { | |
250 | + regionalSeries[data.target].series = createSeries("count"); | |
251 | + regionalSeries[data.target].series.data.setAll(data.markerData); | |
252 | + } | |
253 | + | |
254 | + // Hide current series | |
255 | + if (currentSeries) { | |
256 | + currentSeries.hide(); | |
257 | + } | |
258 | + | |
259 | + // Control zoom | |
260 | + if (data.type == "state") { | |
261 | + let statePolygon = getPolygon("KR-" + data.state); | |
262 | + polygonSeries.zoomToDataItem(statePolygon.dataItem); | |
263 | + } else if (data.type == "city") { | |
264 | + chart.zoomToGeoPoint( | |
265 | + { | |
266 | + latitude: data.geometry.coordinates[1], | |
267 | + longitude: data.geometry.coordinates[0], | |
268 | + }, | |
269 | + 64, | |
270 | + true | |
271 | + ); | |
272 | + } | |
273 | + zoomOut.show(); | |
274 | + | |
275 | + // Show new targert series | |
276 | + currentSeries = regionalSeries[data.target].series; | |
277 | + currentSeries.show(); | |
278 | + }); | |
279 | + | |
280 | + return am5.Bullet.new(root, { | |
281 | + sprite: container, | |
282 | + }); | |
283 | + }); | |
284 | + | |
285 | + // Add heat rule for circles | |
286 | + pointSeries.set("heatRules", [ | |
287 | + { | |
288 | + target: circleTemplate, | |
289 | + dataField: "value", | |
290 | + min: 10, | |
291 | + max: 30, | |
292 | + key: "radius", | |
293 | + }, | |
294 | + ]); | |
295 | + | |
296 | + // Set up drill-down | |
297 | + // TODO | |
298 | + | |
299 | + return pointSeries; | |
300 | + } | |
301 | + | |
302 | + this.root = root; | |
303 | + } | |
304 | + | |
305 | + componentWillUnmount() { | |
306 | + if (this.root) { | |
307 | + this.root.dispose(); | |
308 | + } | |
309 | + } | |
310 | + | |
311 | + render() { | |
312 | + return <div id="Map" style={{ width: "100%", height: "250px" }}></div>; | |
313 | + } | |
314 | +} | |
315 | + | |
316 | +export default Map; |
--- client/views/pages/main/Weather.jsx
+++ client/views/pages/main/Weather.jsx
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 |
<ul className="flex-start"> |
48 | 48 |
<li id="fullDate">{date}</li> |
49 | 49 |
<li id="temp">{`${temp}°C`}</li> |
50 |
- <li><img src={weather} alt="" style={{width:"75%"}}/></li> |
|
50 |
+ <li><img src={weather} alt="" /></li> |
|
51 | 51 |
</ul> |
52 | 52 |
</div> |
53 | 53 |
); |
--- client/views/pages/senior_management/SeniorInsert.jsx
+++ client/views/pages/senior_management/SeniorInsert.jsx
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 |
return ( |
9 | 9 |
<main> |
10 | 10 |
<div className="content-wrap row"> |
11 |
- <ContentTitle contentTitle={"대상자 등록"} /> |
|
11 |
+ <ContentTitle contentTitle={"대상자 등록"}/> |
|
12 | 12 |
<table className="margin-bottom2 senior-insert"> |
13 | 13 |
<tr> |
14 | 14 |
<th>이름</th> |
... | ... | @@ -55,6 +55,12 @@ |
55 | 55 |
</td> |
56 | 56 |
</tr> |
57 | 57 |
<tr> |
58 |
+ <th>보호자 비상연락망</th> |
|
59 |
+ <td colSpan={3}> |
|
60 |
+ <input type="text" /> |
|
61 |
+ </td> |
|
62 |
+ </tr> |
|
63 |
+ <tr> |
|
58 | 64 |
<th>연락처</th> |
59 | 65 |
<td colSpan={3}> |
60 | 66 |
<input type="text" /> |
--- client/views/pages/visit/visit/VisitSelectOne.jsx
+++ client/views/pages/visit/visit/VisitSelectOne.jsx
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 |
</tr> |
48 | 48 |
<tr> |
49 | 49 |
<th>방문 상세 사유</th> |
50 |
- <td colSpan={3} style={{ height: "197px", overflow: "auto", textAlign: "left" }}>하루동안 미복약으로 방문.</td> |
|
50 |
+ <td colSpan={3} style={{ height: "180px", overflow: "auto", textAlign: "left" }}>하루동안 미복약으로 방문.</td> |
|
51 | 51 |
</tr> |
52 | 52 |
</table> |
53 | 53 |
<div className="btn-wrap flex-center"> |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?