
--- client/resources/css/main.css
+++ client/resources/css/main.css
... | ... | @@ -650,7 +650,7 @@ |
650 | 650 |
margin-bottom: .5rem; |
651 | 651 |
} |
652 | 652 |
|
653 |
-@media all and (min-width: 479px) { |
|
653 |
+@media all and (min-width: 767px) { |
|
654 | 654 |
.calendar-data { |
655 | 655 |
display: flex; |
656 | 656 |
justify-content: space-between; |
--- client/views/component/Calendar.jsx
+++ client/views/component/Calendar.jsx
... | ... | @@ -49,12 +49,15 @@ |
49 | 49 |
} |
50 | 50 |
}} |
51 | 51 |
onClickDay={(date, event) => { |
52 |
+ let sendData = { date: moment(date).format("YYYY-MM-DD") }; |
|
52 | 53 |
data.visitRecordList.map((item, idx) => { |
53 | 54 |
if (item['visit_date'] === moment(date).format("YYYY-MM-DD")) { |
54 |
- data.onClick(moment(date).format("YYYY-MM-DD"), item); |
|
55 |
- } else { |
|
56 |
- data.onClick(moment(date).format("YYYY-MM-DD")); |
|
55 |
+ sendData = { |
|
56 |
+ date: moment(date).format("YYYY-MM-DD"), |
|
57 |
+ visitData: item |
|
58 |
+ } |
|
57 | 59 |
} |
60 |
+ data.onClick(sendData); |
|
58 | 61 |
}) |
59 | 62 |
}} |
60 | 63 |
tileContent={({ date, view }) => { |
--- client/views/component/chart/Chart5_agencyadmin.jsx
+++ client/views/component/chart/Chart5_agencyadmin.jsx
... | ... | @@ -5,10 +5,14 @@ |
5 | 5 |
import CommonUtil from "../../../resources/js/CommonUtil"; |
6 | 6 |
|
7 | 7 |
|
8 |
-export default function Chart5({ data }) { |
|
8 |
+export default function Chart5() { |
|
9 | 9 |
const createChart = () => { |
10 |
- console.log('createChart data : ', data); |
|
10 |
+ |
|
11 |
+ /* Chart code */ |
|
12 |
+ // Create root element |
|
13 |
+ // https://www.amcharts.com/docs/v5/getting-started/#Root_element |
|
11 | 14 |
let root = am5.Root.new("Chart5"); |
15 |
+ |
|
12 | 16 |
|
13 | 17 |
// Set themes |
14 | 18 |
// https://www.amcharts.com/docs/v5/concepts/themes/ |
... | ... | @@ -29,8 +33,8 @@ |
29 | 33 |
let series = chart.series.push(am5percent.PictorialStackedSeries.new(root, { |
30 | 34 |
alignLabels: true, |
31 | 35 |
orientation: "vertical", |
32 |
- valueField: "count", |
|
33 |
- categoryField: "agency_name", |
|
36 |
+ valueField: "value", |
|
37 |
+ categoryField: "category", |
|
34 | 38 |
svgPath: "M53.5,476c0,14,6.833,21,20.5,21s20.5-7,20.5-21V287h21v189c0,14,6.834,21,20.5,21 c13.667,0,20.5-7,20.5-21V154h10v116c0,7.334,2.5,12.667,7.5,16s10.167,3.333,15.5,0s8-8.667,8-16V145c0-13.334-4.5-23.667-13.5-31 s-21.5-11-37.5-11h-82c-15.333,0-27.833,3.333-37.5,10s-14.5,17-14.5,31v133c0,6,2.667,10.333,8,13s10.5,2.667,15.5,0s7.5-7,7.5-13 V154h10V476 M61.5,42.5c0,11.667,4.167,21.667,12.5,30S92.333,85,104,85s21.667-4.167,30-12.5S146.5,54,146.5,42 c0-11.335-4.167-21.168-12.5-29.5C125.667,4.167,115.667,0,104,0S82.333,4.167,74,12.5S61.5,30.833,61.5,42.5z" |
35 | 39 |
})); |
36 | 40 |
|
... | ... | @@ -40,28 +44,25 @@ |
40 | 44 |
|
41 | 45 |
// Set data |
42 | 46 |
// https://www.amcharts.com/docs/v5/charts/percent-charts/sliced-chart/#Setting_data |
43 |
- /*series.data.setAll([ |
|
44 |
- { value: 10, category: "A복지관" }, |
|
45 |
- { value: 9, category: "B복지관" }, |
|
46 |
- { value: 6, category: "C복지관" }, |
|
47 |
- { value: 5, category: "D복지관" }, |
|
48 |
- { value: 4, category: "E복지관" }, |
|
49 |
- ]);*/ |
|
50 |
- series.data.setAll(data); |
|
47 |
+ series.data.setAll([ |
|
48 |
+ { value: 10, category: "One" }, |
|
49 |
+ { value: 9, category: "Two" }, |
|
50 |
+ { value: 6, category: "Three" }, |
|
51 |
+ { value: 5, category: "Four" }, |
|
52 |
+ { value: 4, category: "Five" }, |
|
53 |
+ { value: 3, category: "Six" }, |
|
54 |
+ { value: 1, category: "Seven" } |
|
55 |
+ ]); |
|
51 | 56 |
|
52 | 57 |
|
53 | 58 |
// Play initial series animation |
54 | 59 |
// https://www.amcharts.com/docs/v5/concepts/animations/#Animation_of_series |
55 | 60 |
chart.appear(1000, 100); |
56 |
- // end am5.ready() |
|
57 | 61 |
} |
58 | 62 |
|
59 | 63 |
React.useEffect(() => { |
60 |
- console.log('React.useEffect data : ', data); |
|
61 |
- if (CommonUtil.isEmpty(data) == false) { |
|
62 |
- createChart(); |
|
63 |
- } |
|
64 |
- }, [data]) |
|
64 |
+ createChart(); |
|
65 |
+ }, []) |
|
65 | 66 |
|
66 | 67 |
return ( |
67 | 68 |
<div id="Chart5" style={{ width: "100%", height: "80%" }}></div> |
+++ client/views/component/chart/Chart7.jsx
... | ... | @@ -0,0 +1,256 @@ |
1 | +import React, { Component } from "react"; | |
2 | +import * as am5 from "@amcharts/amcharts5"; | |
3 | +import * as am5xy from "@amcharts/amcharts5/xy"; | |
4 | +import am5themes_Animated from "@amcharts/amcharts5/themes/Animated"; | |
5 | + | |
6 | +class Chart6 extends Component { | |
7 | + componentDidMount() { | |
8 | + am5.ready(function () { | |
9 | + | |
10 | + // Create root element | |
11 | + // https://www.amcharts.com/docs/v5/getting-started/#Root_element | |
12 | + var root = am5.Root.new("chart7"); | |
13 | + | |
14 | + // Set themes | |
15 | + // https://www.amcharts.com/docs/v5/concepts/themes/ | |
16 | + root.setThemes([ | |
17 | + am5themes_Animated.new(root) | |
18 | + ]); | |
19 | + | |
20 | + // Create chart | |
21 | + // https://www.amcharts.com/docs/v5/charts/xy-chart/ | |
22 | + var chart = root.container.children.push( | |
23 | + am5xy.XYChart.new(root, { | |
24 | + panX: false, | |
25 | + panY: false, | |
26 | + wheelX: "panX", | |
27 | + wheelY: "zoomX", | |
28 | + layout: root.verticalLayout, | |
29 | + arrangeTooltips: false | |
30 | + }) | |
31 | + ); | |
32 | + | |
33 | + // Use only absolute numbers | |
34 | + chart.getNumberFormatter().set("numberFormat", "#.#s"); | |
35 | + | |
36 | + // Add legend | |
37 | + // https://www.amcharts.com/docs/v5/charts/xy-chart/legend-xy-series/ | |
38 | + var legend = chart.children.push( | |
39 | + am5.Legend.new(root, { | |
40 | + centerX: am5.p50, | |
41 | + x: am5.p50 | |
42 | + }) | |
43 | + ); | |
44 | + | |
45 | + // Data | |
46 | + var data = [ | |
47 | + { | |
48 | + age: "85+", | |
49 | + male: -0.1, | |
50 | + female: 0.3 | |
51 | + }, | |
52 | + { | |
53 | + age: "80-54", | |
54 | + male: -0.2, | |
55 | + female: 0.3 | |
56 | + }, | |
57 | + { | |
58 | + age: "75-79", | |
59 | + male: -0.3, | |
60 | + female: 0.6 | |
61 | + }, | |
62 | + { | |
63 | + age: "70-74", | |
64 | + male: -0.5, | |
65 | + female: 0.8 | |
66 | + }, | |
67 | + { | |
68 | + age: "65-69", | |
69 | + male: -0.8, | |
70 | + female: 1.0 | |
71 | + }, | |
72 | + { | |
73 | + age: "60-64", | |
74 | + male: -1.1, | |
75 | + female: 1.3 | |
76 | + }, | |
77 | + { | |
78 | + age: "55-59", | |
79 | + male: -1.7, | |
80 | + female: 1.9 | |
81 | + }, | |
82 | + { | |
83 | + age: "50-54", | |
84 | + male: -2.2, | |
85 | + female: 2.5 | |
86 | + }, | |
87 | + { | |
88 | + age: "45-49", | |
89 | + male: -2.8, | |
90 | + female: 3.0 | |
91 | + }, | |
92 | + { | |
93 | + age: "40-44", | |
94 | + male: -3.4, | |
95 | + female: 3.6 | |
96 | + }, | |
97 | + { | |
98 | + age: "35-39", | |
99 | + male: -4.2, | |
100 | + female: 4.1 | |
101 | + }, | |
102 | + { | |
103 | + age: "30-34", | |
104 | + male: -5.2, | |
105 | + female: 4.8 | |
106 | + }, | |
107 | + { | |
108 | + age: "25-29", | |
109 | + male: -5.6, | |
110 | + female: 5.1 | |
111 | + }, | |
112 | + { | |
113 | + age: "20-24", | |
114 | + male: -5.1, | |
115 | + female: 5.1 | |
116 | + }, | |
117 | + { | |
118 | + age: "15-19", | |
119 | + male: -3.8, | |
120 | + female: 3.8 | |
121 | + }, | |
122 | + { | |
123 | + age: "10-14", | |
124 | + male: -3.2, | |
125 | + female: 3.4 | |
126 | + }, | |
127 | + { | |
128 | + age: "5-9", | |
129 | + male: -4.4, | |
130 | + female: 4.1 | |
131 | + }, | |
132 | + { | |
133 | + age: "0-4", | |
134 | + male: -5.0, | |
135 | + female: 4.8 | |
136 | + } | |
137 | + ]; | |
138 | + | |
139 | + // Create axes | |
140 | + // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/ | |
141 | + var yAxis = chart.yAxes.push( | |
142 | + am5xy.CategoryAxis.new(root, { | |
143 | + categoryField: "age", | |
144 | + renderer: am5xy.AxisRendererY.new(root, { | |
145 | + inversed: true, | |
146 | + cellStartLocation: 0.1, | |
147 | + cellEndLocation: 0.9 | |
148 | + }) | |
149 | + }) | |
150 | + ); | |
151 | + | |
152 | + yAxis.data.setAll(data); | |
153 | + | |
154 | + var xAxis = chart.xAxes.push( | |
155 | + am5xy.ValueAxis.new(root, { | |
156 | + renderer: am5xy.AxisRendererX.new(root, { | |
157 | + strokeOpacity: 0.1 | |
158 | + }) | |
159 | + }) | |
160 | + ); | |
161 | + | |
162 | + // Add series | |
163 | + // https://www.amcharts.com/docs/v5/charts/xy-chart/series/ | |
164 | + function createSeries(field, labelCenterX, pointerOrientation, rangeValue) { | |
165 | + var series = chart.series.push( | |
166 | + am5xy.ColumnSeries.new(root, { | |
167 | + xAxis: xAxis, | |
168 | + yAxis: yAxis, | |
169 | + valueXField: field, | |
170 | + categoryYField: "age", | |
171 | + sequencedInterpolation: true, | |
172 | + clustered: false, | |
173 | + tooltip: am5.Tooltip.new(root, { | |
174 | + pointerOrientation: pointerOrientation, | |
175 | + labelText: "{categoryY}: {valueX}" | |
176 | + }) | |
177 | + }) | |
178 | + ); | |
179 | + | |
180 | + series.columns.template.setAll({ | |
181 | + height: am5.p100, | |
182 | + strokeOpacity: 0, | |
183 | + fillOpacity: 0.8 | |
184 | + }); | |
185 | + | |
186 | + series.bullets.push(function () { | |
187 | + return am5.Bullet.new(root, { | |
188 | + locationX: 1, | |
189 | + locationY: 0.5, | |
190 | + sprite: am5.Label.new(root, { | |
191 | + centerY: am5.p50, | |
192 | + text: "{valueX}", | |
193 | + populateText: true, | |
194 | + centerX: labelCenterX | |
195 | + }) | |
196 | + }); | |
197 | + }); | |
198 | + | |
199 | + series.data.setAll(data); | |
200 | + series.appear(); | |
201 | + | |
202 | + var rangeDataItem = xAxis.makeDataItem({ | |
203 | + value: rangeValue | |
204 | + }); | |
205 | + xAxis.createAxisRange(rangeDataItem); | |
206 | + rangeDataItem.get("grid").setAll({ | |
207 | + strokeOpacity: 1, | |
208 | + stroke: series.get("stroke") | |
209 | + }); | |
210 | + | |
211 | + var label = rangeDataItem.get("label"); | |
212 | + label.setAll({ | |
213 | + text: field.toUpperCase(), | |
214 | + fontSize: "1.1em", | |
215 | + fill: series.get("stroke"), | |
216 | + paddingTop: 10, | |
217 | + isMeasured: false, | |
218 | + centerX: labelCenterX | |
219 | + }); | |
220 | + label.adapters.add("dy", function () { | |
221 | + return -chart.plotContainer.height(); | |
222 | + }); | |
223 | + | |
224 | + return series; | |
225 | + } | |
226 | + | |
227 | + createSeries("male", am5.p100, "right", -3); | |
228 | + createSeries("female", 0, "left", 4); | |
229 | + | |
230 | + // Add cursor | |
231 | + // https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/ | |
232 | + var cursor = chart.set("cursor", am5xy.XYCursor.new(root, { | |
233 | + behavior: "zoomY" | |
234 | + })); | |
235 | + cursor.lineY.set("forceHidden", true); | |
236 | + cursor.lineX.set("forceHidden", true); | |
237 | + | |
238 | + // Make stuff animate on load | |
239 | + // https://www.amcharts.com/docs/v5/concepts/animations/ | |
240 | + chart.appear(1000, 100); | |
241 | + | |
242 | + }); // end am5.ready() | |
243 | + } | |
244 | + | |
245 | + componentWillUnmount() { | |
246 | + if (this.root) { | |
247 | + this.root.dispose(); | |
248 | + } | |
249 | + } | |
250 | + | |
251 | + render() { | |
252 | + return <div id="chart7" style={{ width: "100%", height: "100%" }}></div>; | |
253 | + } | |
254 | +} | |
255 | + | |
256 | +export default Chart6; |
--- client/views/layout/Menu.jsx
+++ client/views/layout/Menu.jsx
... | ... | @@ -50,9 +50,13 @@ |
50 | 50 |
<h1 className="logo"><img src={logo} alt="" /></h1> |
51 | 51 |
<div className="flex-align-column" style={{ marginTop: `3rem` }}> |
52 | 52 |
<ul > |
53 |
- {items.map((item, index) => ( |
|
54 |
- <SidebarItem key={index} item={item} /> |
|
55 |
- ))} |
|
53 |
+ { |
|
54 |
+ items != null ? ( |
|
55 |
+ items.map((item, index) => ( |
|
56 |
+ <SidebarItem key={index} item={item} /> |
|
57 |
+ )) |
|
58 |
+ ) : null |
|
59 |
+ } |
|
56 | 60 |
</ul> |
57 | 61 |
</div> |
58 | 62 |
<div className="bottom-section flex-center" style={{width: '100%'}}> |
--- client/views/pages/App.jsx
+++ client/views/pages/App.jsx
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 |
import Header from "../layout/Header.jsx"; |
18 | 18 |
import Menu from "../layout/Menu.jsx"; |
19 | 19 |
import Login from "./login/Login.jsx"; |
20 |
+import PasswordChange from "./main/PasswordChange.jsx"; |
|
20 | 21 |
import Weather from "./main/Weather.jsx"; |
21 | 22 |
import CommonUtil from "../../resources/js/CommonUtil.js"; |
22 | 23 |
|
... | ... | @@ -140,6 +141,8 @@ |
140 | 141 |
|
141 | 142 |
//로그인 여부 |
142 | 143 |
const [isLogin, setIsLogin] = React.useState(false); |
144 |
+ //기본 비밀번호 사용 여부 확인 (로그인 여부 확인 후, 사용 바람) |
|
145 |
+ const [isDefaultPassword, setIsDefaultPassword] = React.useState(false); |
|
143 | 146 |
|
144 | 147 |
//로그인에 따라 각기 다른 App 주입 대상 변수(AdminApp, GovernmentApp, AgencyApp, GuardianApp) |
145 | 148 |
const [appRoute, setAppRoute] = React.useState(null); |
... | ... | @@ -153,14 +156,35 @@ |
153 | 156 |
'Content-Type': 'application/json; charset=UTF-8' |
154 | 157 |
}, |
155 | 158 |
body: JSON.stringify({}), |
156 |
- }).then((response) => response.json()).then((data) => { |
|
157 |
- console.log("로그인 결과 : ", data); |
|
159 |
+ }).then((response) => response.json()).then((loginUser) => { |
|
160 |
+ console.log("로그인 결과 : ", loginUser); |
|
158 | 161 |
//로그인 사용자 정보 전역 변수에 저장 |
159 |
- dispatch(setLoginUser(data)); |
|
160 |
- //클라이언트 로그인 체크 (콜백) |
|
161 |
- if (CommonUtil.isEmpty(clientLoginCheck) == false) { |
|
162 |
- clientLoginCheck(data); |
|
163 |
- } |
|
162 |
+ dispatch(setLoginUser(loginUser)); |
|
163 |
+ |
|
164 |
+ //로그인 유무(로그인 정보가 있으면 True, 없으면 False) |
|
165 |
+ let isLogin = (loginUser != null && loginUser['user_id'] != null); |
|
166 |
+ setIsLogin(isLogin); |
|
167 |
+ |
|
168 |
+ //기본 비밀번호 사용 여부 확인 |
|
169 |
+ fetch("/user/isDefaultPassword.json", { |
|
170 |
+ method: "POST", |
|
171 |
+ headers: { |
|
172 |
+ 'Content-Type': 'application/json; charset=UTF-8' |
|
173 |
+ }, |
|
174 |
+ body: JSON.stringify({}), |
|
175 |
+ }).then((response) => response.json()).then((isDefaultPassword) => { |
|
176 |
+ console.log("기본 비밀번호 사용 여부 확인 결과 : ", isDefaultPassword); |
|
177 |
+ setIsDefaultPassword(isDefaultPassword); |
|
178 |
+ |
|
179 |
+ //클라이언트 로그인 체크 (콜백) |
|
180 |
+ if (CommonUtil.isEmpty(clientLoginCheck) == false) { |
|
181 |
+ clientLoginCheck(loginUser, isLogin); |
|
182 |
+ } |
|
183 |
+ |
|
184 |
+ }).catch((error) => { |
|
185 |
+ console.log('login() /user/isDefaultPassword.json error : ', error); |
|
186 |
+ }); |
|
187 |
+ |
|
164 | 188 |
}).catch((error) => { |
165 | 189 |
console.log('login() /user/loginUserSelectOne.json error : ', error); |
166 | 190 |
}); |
... | ... | @@ -219,13 +243,9 @@ |
219 | 243 |
|
220 | 244 |
//URL 변경 시, 발생 이벤트(hook) |
221 | 245 |
React.useEffect(() => { |
222 |
- loginUserSelectOne((loginResultData) => { |
|
246 |
+ loginUserSelectOne((loginResultData, isLogin) => { |
|
223 | 247 |
//console.log('loginResultData : ', loginResultData); |
224 | 248 |
//console.log('isLogin : ', isLogin, ', authority : ', loginResultData['authority']); |
225 |
- |
|
226 |
- //로그인 유무(로그인 정보가 있으면 True, 없으면 False) |
|
227 |
- let isLogin = (loginResultData != null && loginResultData['user_id'] != null); |
|
228 |
- setIsLogin(isLogin); |
|
229 | 249 |
|
230 | 250 |
//로그인 -> 권한에 따른 App 주입 |
231 | 251 |
if (isLogin == true) { |
... | ... | @@ -271,15 +291,17 @@ |
271 | 291 |
|
272 | 292 |
return ( |
273 | 293 |
<div id="App"> |
274 |
- {isLogin == true ? ( |
|
275 |
- <div id="layout"> |
|
276 |
- <Header/> |
|
277 |
- <Menu items={menuItems != null ? menuItems : null}/> |
|
278 |
- <div id="pages"> |
|
279 |
- {appRoute != null ? appRoute : null} |
|
294 |
+ {isLogin == true ? |
|
295 |
+ isDefaultPassword == false ? ( |
|
296 |
+ <div id="layout"> |
|
297 |
+ <Header/> |
|
298 |
+ <Menu items={menuItems != null ? menuItems : null}/> |
|
299 |
+ <div id="pages"> |
|
300 |
+ {appRoute != null ? appRoute : null} |
|
301 |
+ </div> |
|
280 | 302 |
</div> |
281 |
- </div> |
|
282 |
- ) : (<Login/>)} |
|
303 |
+ ) : (<PasswordChange/>) |
|
304 |
+ : (<Login/>)} |
|
283 | 305 |
</div> |
284 | 306 |
); |
285 | 307 |
} |
--- client/views/pages/callcenter/QandAInsert.jsx
+++ client/views/pages/callcenter/QandAInsert.jsx
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 |
const location = useLocation(); |
15 | 15 |
|
16 | 16 |
//전역 변수 저장 객체 |
17 |
- const state = useSelector((state) => {return state}); |
|
17 |
+ const state = useSelector((state) => { return state }); |
|
18 | 18 |
const defaultGovernmentId = CommonUtil.isEmpty(state.loginUser) ? null : state.loginUser['government_id']; |
19 | 19 |
const defaultAgencyId = CommonUtil.isEmpty(state.loginUser) ? null : state.loginUser['agency_id']; |
20 | 20 |
let defaultSeniorId = null; |
... | ... | @@ -28,430 +28,456 @@ |
28 | 28 |
defaultSeniorId = null; |
29 | 29 |
} |
30 | 30 |
|
31 |
- console.log('defaultSeniorId : ', defaultSeniorId); |
|
31 |
+ const [seniorSearch, setSeniorSearch] = React.useState(defaultSeniorId); |
|
32 | 32 |
|
33 |
- // 시스템 코드 - 장비 상태 |
|
34 |
- const [equipmentStates, setEquipmentStates] = React.useState({}); |
|
35 |
- // 시스템 코드 - 장비 상태 조회 |
|
36 |
- const equipmentStatesSelect = () => { |
|
37 |
- console.log('equipmentStatesSelect Function Run'); |
|
33 |
+ // 시스템 코드 - 장비 상태 |
|
34 |
+ const [equipmentStates, setEquipmentStates] = React.useState({}); |
|
35 |
+ // 시스템 코드 - 장비 상태 조회 |
|
36 |
+ const equipmentStatesSelect = () => { |
|
37 |
+ console.log('equipmentStatesSelect Function Run'); |
|
38 | 38 |
|
39 |
- //fetch post |
|
40 |
- fetch("/common/systemCode/equipmentStatesSelect.json", { |
|
41 |
- method: "POST", |
|
42 |
- headers: { |
|
43 |
- 'Content-Type': 'application/json; charset=UTF-8' |
|
44 |
- }, |
|
45 |
- body: JSON.stringify({}) |
|
46 |
- }).then((response) => response.json()).then((data) => { |
|
47 |
- console.log('equipmentStatesSelect response : ', data); |
|
48 |
- setEquipmentStates(data); |
|
49 |
- }).catch((error) => { |
|
50 |
- console.log('equipmentStatesSelect error : ', error); |
|
51 |
- }); |
|
52 |
- } |
|
53 |
- |
|
54 |
- |
|
55 |
- //입고 및 미대여 장비 검색 정보 |
|
56 |
- const [equipmentSearch, setEquipmentSearch] = React.useState({ |
|
57 |
- 'government_id': defaultGovernmentId, |
|
58 |
- 'agency_id': defaultAgencyId, |
|
59 |
- 'senior_id': defaultSeniorId, |
|
60 |
- 'currentPage': 1, |
|
61 |
- 'perPage': 10, |
|
62 |
- 'searchType': null, |
|
63 |
- 'searchText': null, |
|
64 |
- |
|
65 |
- 'equipment_state': null, |
|
66 |
- }); |
|
67 |
- //장비 정보 변경 |
|
68 |
- const equipmentSearchChange = (targetKey, value) => { |
|
69 |
- equipmentSearch[targetKey] = value; |
|
70 |
- setEquipmentSearch({...equipmentSearch}); |
|
71 |
- } |
|
72 |
- //장비 검색 |
|
73 |
- const equipmentSearching = () => { |
|
74 |
- equipmentSelectList(1); |
|
75 |
- } |
|
76 |
- const equipmentSearchingEnter = (key) => { |
|
77 |
- if (key == 'Enter') { |
|
78 |
- equipmentSearching(); |
|
79 |
- } else { |
|
80 |
- return; |
|
81 |
- } |
|
82 |
- } |
|
83 |
- //입고 및 미대여 목록 |
|
84 |
- const [equipment, setEquipment] = React.useState({equipmentList: [], equipmentListCount: 0}); |
|
85 |
- //입고 및 미대여 목록 조회 |
|
86 |
- const equipmentSelectList = (currentPage) => { |
|
87 |
- equipmentSearch.currentPage = CommonUtil.isEmpty(currentPage) ? 1 : currentPage; |
|
88 |
- setEquipmentSearch({...equipmentSearch}); |
|
89 |
- |
|
90 |
- fetch("/equipment/equipmentSelectList.json", { |
|
91 |
- method: "POST", |
|
92 |
- headers: { |
|
93 |
- 'Content-Type': 'application/json; charset=UTF-8' |
|
94 |
- }, |
|
95 |
- body: JSON.stringify(equipmentSearch) |
|
96 |
- }).then((response) => response.json()).then((data) => { |
|
97 |
- console.log('equipmentSelectList response : ', data); |
|
98 |
- setEquipment(data); |
|
99 |
- if (CommonUtil.isEmpty(data.equipmentList) == false && equipmentInquiry['equipment_serial_number'] == '') { |
|
100 |
- equipmentInquirySelect(data.equipmentList[0]); |
|
101 |
- } |
|
102 |
- }).catch((error) => { |
|
103 |
- console.log('equipmentSelectList error : ', error); |
|
104 |
- }); |
|
105 |
- } |
|
106 |
- |
|
107 |
- //장비 모달 여부 |
|
108 |
- const [modalEquipmentIsOpen, setModalEquipmentIsOpen] = React.useState(false); |
|
109 |
- //장비 오픈 |
|
110 |
- const modalEquipmentOpen = () => { |
|
111 |
- setModalEquipmentIsOpen(true); |
|
112 |
- }; |
|
113 |
- //장비 닫기 |
|
114 |
- const modalEquipmentClose = () => { |
|
115 |
- setModalEquipmentIsOpen(false); |
|
116 |
- }; |
|
117 |
- |
|
118 |
- const equipmentInit = { |
|
119 |
- 'equipment_serial_number': null, |
|
120 |
- 'equipment_name': null, |
|
121 |
- 'agency_name': null, |
|
122 |
- 'rental_detail_insert_user_name': null, |
|
123 |
- 'rental_detail_insert_user_id': null, |
|
124 |
- 'user_name': null, |
|
125 |
- 'user_id': null, |
|
126 |
- 'user_address': null, |
|
127 |
- 'equipment_state': null, |
|
128 |
- } |
|
129 |
- //등록할 문의 정보 |
|
130 |
- const [equipmentInquiry, setEquipmentInquiry] = React.useState({ |
|
131 |
- 'inquiry_idx': 0, |
|
132 |
- 'inquiry_type': null, |
|
133 |
- 'inquiry_title': null, |
|
134 |
- 'inquiry_content': null, |
|
135 |
- 'inquiry_state': null, |
|
136 |
- 'inquiry_insert_user_id': null, |
|
137 |
- 'inquiry_insert_datetime': null, |
|
138 |
- 'inquiry_answer_content': null, |
|
139 |
- 'inquiry_answer_user_id': null, |
|
140 |
- 'inquiry_update_datetime': null, |
|
141 |
- |
|
142 |
- 'equipment_serial_number': null, |
|
143 |
- //문의할 장비 정보 |
|
144 |
- equipment: {...equipmentInit} |
|
39 |
+ //fetch post |
|
40 |
+ fetch("/common/systemCode/equipmentStatesSelect.json", { |
|
41 |
+ method: "POST", |
|
42 |
+ headers: { |
|
43 |
+ 'Content-Type': 'application/json; charset=UTF-8' |
|
44 |
+ }, |
|
45 |
+ body: JSON.stringify({}) |
|
46 |
+ }).then((response) => response.json()).then((data) => { |
|
47 |
+ console.log('equipmentStatesSelect response : ', data); |
|
48 |
+ setEquipmentStates(data); |
|
49 |
+ }).catch((error) => { |
|
50 |
+ console.log('equipmentStatesSelect error : ', error); |
|
145 | 51 |
}); |
146 |
- const equipmentInquiryRef = React.useRef({...equipmentInquiry}); |
|
147 |
- |
|
148 |
- //문의할 장비 선택 |
|
149 |
- const equipmentInquirySelect = (equipment) => { |
|
150 |
- equipmentInquiry.equipment = equipment; |
|
151 |
- equipmentInquiry['equipment_serial_number'] = equipment['equipment_serial_number']; |
|
152 |
- setEquipmentInquiry({...equipmentInquiry}); |
|
153 |
- } |
|
154 |
- |
|
155 |
- //문의할 장비 선택 취소 |
|
156 |
- const equipmentInquirySelectCancel = () => { |
|
157 |
- equipmentInquiry['equipment_serial_number'] = ''; |
|
158 |
- equipmentInquiry.equipment = {...equipmentInit}; |
|
159 |
- |
|
160 |
- setEquipmentInquiry({...equipmentInquiry}); |
|
161 |
- } |
|
162 |
- |
|
163 |
- //등록할 문의 구분이 '장비문의'로 바꼈을 때만 작동 |
|
164 |
- React.useEffect(() => { |
|
165 |
- if (equipmentInquiry['equipment_serial_number'] == '') { |
|
166 |
- equipmentInquiry['inquiry_type'] = '기타'; |
|
167 |
- setEquipmentInquiry({...equipmentInquiry}); |
|
168 |
- } else if (equipmentInquiry['equipment_serial_number'] == null) { |
|
169 |
- equipmentInquiry.equipment = {...equipmentInit}; |
|
170 |
- equipmentInquiry['inquiry_type'] = null; |
|
171 |
- setEquipmentInquiry({...equipmentInquiry}); |
|
172 |
- } |
|
173 |
- }, [equipmentInquiry['equipment_serial_number']]); |
|
174 |
- |
|
175 |
- //등록할 문의 구분이 '장비문의 구분'이 바꼈을 때만 작동 |
|
176 |
- React.useEffect(() => { |
|
177 |
- if (equipmentInquiry['equipment_serial_number'] == '' |
|
178 |
- && (equipmentInquiry['inquiry_type'] == '교환' |
|
179 |
- || equipmentInquiry['inquiry_type'] == '수리')) { |
|
180 |
- equipmentSelectList(1); |
|
181 |
- } else if (CommonUtil.isEmpty(equipmentInquiry['equipment_serial_number']) == false |
|
182 |
- && equipmentInquiry['inquiry_type'] == '추가') { |
|
183 |
- equipmentInquirySelectCancel(); |
|
184 |
- } |
|
185 |
- }, [equipmentInquiry['inquiry_type']]); |
|
52 |
+ } |
|
186 | 53 |
|
187 | 54 |
|
188 |
- //문의 등록 유효성 검사 |
|
189 |
- const equipmentInquiryValidation = () => { |
|
190 |
- const target = equipmentInquiry; |
|
191 |
- const targetRef = equipmentInquiryRef; |
|
192 |
- if (CommonUtil.isEmpty(target['inquiry_title']) == true) { |
|
193 |
- targetRef.current['inquiry_title'].focus(); |
|
194 |
- alert("문의제목을 입력해 주세요."); |
|
195 |
- return false; |
|
196 |
- } |
|
197 |
- if (CommonUtil.isEmpty(target['inquiry_content']) == true) { |
|
198 |
- targetRef.current['inquiry_content'].focus(); |
|
199 |
- alert("내용을 입력해 주세요."); |
|
200 |
- return false; |
|
201 |
- } |
|
202 |
- if ((equipmentInquiry['inquiry_type'] == '교환' || equipmentInquiry['inquiry_type'] == '수리') |
|
203 |
- && CommonUtil.isEmpty(target['equipment_serial_number'])) { |
|
204 |
- alert(`장비 ${equipmentInquiry['inquiry_type']}은(는) 장비 정보를 필수로 선택하셔야 됩니다.`); |
|
205 |
- return false; |
|
206 |
- } |
|
55 |
+ //입고 및 미대여 장비 검색 정보 |
|
56 |
+ const [equipmentSearch, setEquipmentSearch] = React.useState({ |
|
57 |
+ 'government_id': defaultGovernmentId, |
|
58 |
+ 'agency_id': defaultAgencyId, |
|
59 |
+ 'senior_id': seniorSearch, |
|
60 |
+ 'currentPage': 1, |
|
61 |
+ 'perPage': 10, |
|
62 |
+ 'searchType': null, |
|
63 |
+ 'searchText': null, |
|
207 | 64 |
|
208 |
- return true; |
|
209 |
- } |
|
65 |
+ 'equipment_state': null, |
|
66 |
+ }); |
|
67 |
+ //장비 정보 변경 |
|
68 |
+ const equipmentSearchChange = (targetKey, value) => { |
|
69 |
+ equipmentSearch[targetKey] = value; |
|
70 |
+ setEquipmentSearch({ ...equipmentSearch }); |
|
71 |
+ } |
|
72 |
+ //장비 검색 |
|
73 |
+ const equipmentSearching = () => { |
|
74 |
+ equipmentSelectList(1); |
|
75 |
+ } |
|
76 |
+ const equipmentSearchingEnter = (key) => { |
|
77 |
+ if (key == 'Enter') { |
|
78 |
+ equipmentSearching(); |
|
79 |
+ } else { |
|
80 |
+ return; |
|
81 |
+ } |
|
82 |
+ } |
|
83 |
+ //입고 및 미대여 목록 |
|
84 |
+ const [equipment, setEquipment] = React.useState({ equipmentList: [], equipmentListCount: 0 }); |
|
85 |
+ //입고 및 미대여 목록 조회 |
|
86 |
+ const equipmentSelectList = (currentPage) => { |
|
87 |
+ equipmentSearch.currentPage = CommonUtil.isEmpty(currentPage) ? 1 : currentPage; |
|
88 |
+ setEquipmentSearch({ ...equipmentSearch }); |
|
210 | 89 |
|
211 |
- //문의 등록 |
|
212 |
- const equipmentInquiryInsert = () => { |
|
213 |
- if (equipmentInquiryValidation() == false) { |
|
214 |
- return; |
|
215 |
- } |
|
90 |
+ fetch("/equipment/equipmentSelectList.json", { |
|
91 |
+ method: "POST", |
|
92 |
+ headers: { |
|
93 |
+ 'Content-Type': 'application/json; charset=UTF-8' |
|
94 |
+ }, |
|
95 |
+ body: JSON.stringify(equipmentSearch) |
|
96 |
+ }).then((response) => response.json()).then((data) => { |
|
97 |
+ console.log('equipmentSelectList response : ', data); |
|
98 |
+ setEquipment(data); |
|
99 |
+ if (CommonUtil.isEmpty(data.equipmentList) == false && equipmentInquiry['equipment_serial_number'] == '') { |
|
100 |
+ equipmentInquirySelect(data.equipmentList[0]); |
|
101 |
+ } |
|
102 |
+ }).catch((error) => { |
|
103 |
+ console.log('equipmentSelectList error : ', error); |
|
104 |
+ }); |
|
105 |
+ } |
|
216 | 106 |
|
217 |
- if (equipmentInquiry['equipment_serial_number'] == '') { |
|
218 |
- equipmentInquiry['equipment_serial_number'] = null; |
|
219 |
- } |
|
107 |
+ //장비 모달 여부 |
|
108 |
+ const [modalEquipmentIsOpen, setModalEquipmentIsOpen] = React.useState(false); |
|
109 |
+ //장비 오픈 |
|
110 |
+ const modalEquipmentOpen = () => { |
|
111 |
+ setModalEquipmentIsOpen(true); |
|
112 |
+ }; |
|
113 |
+ //장비 닫기 |
|
114 |
+ const modalEquipmentClose = () => { |
|
115 |
+ setModalEquipmentIsOpen(false); |
|
116 |
+ }; |
|
220 | 117 |
|
221 |
- fetch("/equipment/equipmentInquiryInsert.json", { |
|
222 |
- method: "POST", |
|
223 |
- headers: { |
|
224 |
- 'Content-Type': 'application/json; charset=UTF-8' |
|
225 |
- }, |
|
226 |
- body: JSON.stringify(equipmentInquiry), |
|
227 |
- }).then((response) => response.json()).then((data) => { |
|
228 |
- console.log("문의 등록 결과(건수) : ", data); |
|
229 |
- if (data > 0) { |
|
230 |
- alert("등록완료"); |
|
231 |
- navigate('/QandASelect'); |
|
232 |
- } else { |
|
233 |
- alert("등록에 실패하였습니다. 관리자에게 문의바랍니다."); |
|
234 |
- } |
|
235 |
- }).catch((error) => { |
|
236 |
- console.log('equipmentInquiryInsert() /equipment/equipmentInquiryInsert.json error : ', error); |
|
237 |
- }); |
|
238 |
- } |
|
118 |
+ const equipmentInit = { |
|
119 |
+ 'equipment_serial_number': null, |
|
120 |
+ 'equipment_name': null, |
|
121 |
+ 'agency_name': null, |
|
122 |
+ 'rental_detail_insert_user_name': null, |
|
123 |
+ 'rental_detail_insert_user_id': null, |
|
124 |
+ 'user_name': null, |
|
125 |
+ 'user_id': null, |
|
126 |
+ 'user_address': null, |
|
127 |
+ 'equipment_state': null, |
|
128 |
+ } |
|
129 |
+ //등록할 문의 정보 |
|
130 |
+ const [equipmentInquiry, setEquipmentInquiry] = React.useState({ |
|
131 |
+ 'inquiry_idx': 0, |
|
132 |
+ 'inquiry_type': null, |
|
133 |
+ 'inquiry_title': null, |
|
134 |
+ 'inquiry_content': null, |
|
135 |
+ 'inquiry_state': null, |
|
136 |
+ 'inquiry_insert_user_id': null, |
|
137 |
+ 'inquiry_insert_datetime': null, |
|
138 |
+ 'inquiry_answer_content': null, |
|
139 |
+ 'inquiry_answer_user_id': null, |
|
140 |
+ 'inquiry_update_datetime': null, |
|
141 |
+ |
|
142 |
+ 'equipment_serial_number': null, |
|
143 |
+ //문의할 장비 정보 |
|
144 |
+ equipment: { ...equipmentInit } |
|
145 |
+ }); |
|
146 |
+ const equipmentInquiryRef = React.useRef({ ...equipmentInquiry }); |
|
147 |
+ |
|
148 |
+ //문의할 장비 선택 |
|
149 |
+ const equipmentInquirySelect = (equipment) => { |
|
150 |
+ equipmentInquiry.equipment = equipment; |
|
151 |
+ equipmentInquiry['equipment_serial_number'] = equipment['equipment_serial_number']; |
|
152 |
+ setEquipmentInquiry({ ...equipmentInquiry }); |
|
153 |
+ } |
|
154 |
+ |
|
155 |
+ //문의할 장비 선택 취소 |
|
156 |
+ const equipmentInquirySelectCancel = () => { |
|
157 |
+ equipmentInquiry['equipment_serial_number'] = ''; |
|
158 |
+ equipmentInquiry.equipment = { ...equipmentInit }; |
|
159 |
+ |
|
160 |
+ setEquipmentInquiry({ ...equipmentInquiry }); |
|
161 |
+ } |
|
162 |
+ |
|
163 |
+ //등록할 문의 구분이 '장비문의'로 바꼈을 때만 작동 |
|
164 |
+ React.useEffect(() => { |
|
165 |
+ if (equipmentInquiry['equipment_serial_number'] == '') { |
|
166 |
+ equipmentInquiry['inquiry_type'] = '기타'; |
|
167 |
+ setEquipmentInquiry({ ...equipmentInquiry }); |
|
168 |
+ } else if (equipmentInquiry['equipment_serial_number'] == null) { |
|
169 |
+ equipmentInquiry.equipment = { ...equipmentInit }; |
|
170 |
+ equipmentInquiry['inquiry_type'] = null; |
|
171 |
+ setEquipmentInquiry({ ...equipmentInquiry }); |
|
172 |
+ } |
|
173 |
+ }, [equipmentInquiry['equipment_serial_number']]); |
|
174 |
+ |
|
175 |
+ //등록할 문의 구분이 '장비문의 구분'이 바꼈을 때만 작동 |
|
176 |
+ React.useEffect(() => { |
|
177 |
+ if (equipmentInquiry['equipment_serial_number'] == '' |
|
178 |
+ && (equipmentInquiry['inquiry_type'] == '교환' |
|
179 |
+ || equipmentInquiry['inquiry_type'] == '수리')) { |
|
180 |
+ equipmentSelectList(1); |
|
181 |
+ } else if (CommonUtil.isEmpty(equipmentInquiry['equipment_serial_number']) == false |
|
182 |
+ && equipmentInquiry['inquiry_type'] == '추가') { |
|
183 |
+ equipmentInquirySelectCancel(); |
|
184 |
+ } |
|
185 |
+ }, [equipmentInquiry['inquiry_type']]); |
|
239 | 186 |
|
240 | 187 |
|
188 |
+ //문의 등록 유효성 검사 |
|
189 |
+ const equipmentInquiryValidation = () => { |
|
190 |
+ const target = equipmentInquiry; |
|
191 |
+ const targetRef = equipmentInquiryRef; |
|
192 |
+ if (CommonUtil.isEmpty(target['inquiry_title']) == true) { |
|
193 |
+ targetRef.current['inquiry_title'].focus(); |
|
194 |
+ alert("문의제목을 입력해 주세요."); |
|
195 |
+ return false; |
|
196 |
+ } |
|
197 |
+ if (CommonUtil.isEmpty(target['inquiry_content']) == true) { |
|
198 |
+ targetRef.current['inquiry_content'].focus(); |
|
199 |
+ alert("내용을 입력해 주세요."); |
|
200 |
+ return false; |
|
201 |
+ } |
|
202 |
+ if ((equipmentInquiry['inquiry_type'] == '교환' || equipmentInquiry['inquiry_type'] == '수리') |
|
203 |
+ && CommonUtil.isEmpty(target['equipment_serial_number'])) { |
|
204 |
+ alert(`장비 ${equipmentInquiry['inquiry_type']}은(는) 장비 정보를 필수로 선택하셔야 됩니다.`); |
|
205 |
+ return false; |
|
206 |
+ } |
|
241 | 207 |
|
242 |
- React.useEffect(() => { |
|
243 |
- equipmentStatesSelect(); |
|
244 |
- }, []) |
|
208 |
+ return true; |
|
209 |
+ } |
|
210 |
+ |
|
211 |
+ //문의 등록 |
|
212 |
+ const equipmentInquiryInsert = () => { |
|
213 |
+ if (equipmentInquiryValidation() == false) { |
|
214 |
+ return; |
|
215 |
+ } |
|
216 |
+ |
|
217 |
+ if (equipmentInquiry['equipment_serial_number'] == '') { |
|
218 |
+ equipmentInquiry['equipment_serial_number'] = null; |
|
219 |
+ } |
|
220 |
+ |
|
221 |
+ fetch("/equipment/equipmentInquiryInsert.json", { |
|
222 |
+ method: "POST", |
|
223 |
+ headers: { |
|
224 |
+ 'Content-Type': 'application/json; charset=UTF-8' |
|
225 |
+ }, |
|
226 |
+ body: JSON.stringify(equipmentInquiry), |
|
227 |
+ }).then((response) => response.json()).then((data) => { |
|
228 |
+ console.log("문의 등록 결과(건수) : ", data); |
|
229 |
+ if (data > 0) { |
|
230 |
+ alert("등록완료"); |
|
231 |
+ navigate('/QandASelect'); |
|
232 |
+ } else { |
|
233 |
+ alert("등록에 실패하였습니다. 관리자에게 문의바랍니다."); |
|
234 |
+ } |
|
235 |
+ }).catch((error) => { |
|
236 |
+ console.log('equipmentInquiryInsert() /equipment/equipmentInquiryInsert.json error : ', error); |
|
237 |
+ }); |
|
238 |
+ } |
|
239 |
+ |
|
240 |
+ React.useEffect(() => { |
|
241 |
+ equipmentStatesSelect(); |
|
242 |
+ }, [seniorSearch]) |
|
245 | 243 |
|
246 | 244 |
return ( |
247 | 245 |
<main> |
248 |
- |
|
249 |
- <Modal open={modalEquipmentIsOpen} close={modalEquipmentClose} header="문의대상 장비 선택"> |
|
250 |
- <div className="board-wrap"> |
|
251 |
- <div> |
|
252 |
- |
|
253 |
- <div className="search-management flex-end margin-bottom2 margin-top gap"> |
|
254 |
- <select style={{maxWidth: '150px'}} |
|
255 |
- onChange={(e) => equipmentSearchChange('equipment_state', e.target.value)}> |
|
256 |
- <option value="">상태</option> |
|
257 |
- {Object.keys(equipmentStates).map((key, idx) => { return ( |
|
258 |
- <option key={key} value={key}> |
|
259 |
- {equipmentStates[key]} |
|
260 |
- </option> |
|
261 |
- )})} |
|
262 |
- </select> |
|
263 |
- <select style={{maxWidth: '150px'}} |
|
264 |
- onChange={(e) => equipmentSearchChange('searchType', e.target.value)}> |
|
265 |
- <option value="">전체</option> |
|
266 |
- <option value="equipment_name">모델명</option> |
|
267 |
- <option value="equipment_serial_number">시리얼넘버</option> |
|
268 |
- </select> |
|
269 |
- <input type="text" |
|
270 |
- value={equipmentSearch.searchText} |
|
271 |
- onChange={(e) => equipmentSearchChange('searchText', e.target.value)} |
|
272 |
- onKeyUp={(e) => equipmentSearchingEnter(e.key)} |
|
273 |
- /> |
|
274 |
- <button className={"btn-small gray-btn"} style={{maxWidth: '150px'}} onClick={equipmentSearching}>검색</button> |
|
275 |
- </div> |
|
276 | 246 |
|
277 |
- <table class="caregiver-user protector-user"> |
|
278 |
- <thead> |
|
279 |
- <tr> |
|
280 |
- <th>No</th> |
|
281 |
- <th>장비사용대상자</th> |
|
282 |
- <th>모델명</th> |
|
283 |
- <th>시리얼넘버</th> |
|
284 |
- <th>장비상태</th> |
|
285 |
- <th>기관</th> |
|
286 |
- <th>선택</th> |
|
287 |
- </tr> |
|
288 |
- </thead> |
|
289 |
- <tbody> |
|
290 |
- {equipment.equipmentList.map((item, idx) => { return ( |
|
291 |
- <tr> |
|
292 |
- <td data-label="No">{equipment.equipmentListCount - idx - (equipmentSearch.currentPage - 1) * equipmentSearch.perPage}</td> |
|
293 |
- <td data-label="장비사용대상자"> |
|
294 |
- {item['user_id'] == null ? '미대여' : item['user_name']} |
|
295 |
- </td> |
|
296 |
- <td data-label="모델명">{item['equipment_name']}</td> |
|
297 |
- <td data-label="시리얼넘버">{item['equipment_serial_number']}</td> |
|
298 |
- <td data-label="장비상태">{equipmentStates[item['equipment_state']]}</td> |
|
299 |
- <td> |
|
300 |
- {item['agency_id'] == null ? item['government_name'] : item['agency_name']} |
|
301 |
- </td> |
|
302 |
- <td data-label="대여시행자"> |
|
303 |
- {equipmentInquiry.equipment['equipment_serial_number'] != item['equipment_serial_number'] |
|
304 |
- ? <button className={"btn-small gray-btn"} style={{maxWidth: '150px'}} |
|
305 |
- onClick={() => {equipmentInquirySelect(item); modalEquipmentClose();}}>선택</button> |
|
306 |
- : <button className={"btn-small red-btn"} style={{maxWidth: '150px'}} |
|
307 |
- onClick={() => {equipmentInquirySelectCancel(); modalEquipmentClose();}}>취소</button> |
|
308 |
- } |
|
309 |
- </td> |
|
310 |
- </tr> |
|
311 |
- )})} |
|
312 |
- {CommonUtil.isEmpty(equipment.equipmentList) ? |
|
313 |
- <tr> |
|
314 |
- <td colSpan={7}>조회된 데이터가 없습니다</td> |
|
315 |
- </tr> |
|
316 |
- : null} |
|
317 |
- </tbody> |
|
318 |
- </table> |
|
319 |
- <Pagination |
|
320 |
- currentPage={equipmentSearch.currentPage} |
|
321 |
- perPage={equipmentSearch.perPage} |
|
322 |
- totalCount={equipment.equipmentListCount} |
|
323 |
- maxRange={5} |
|
324 |
- click={equipmentSelectList} |
|
325 |
- /> |
|
326 |
- </div> |
|
327 |
- </div> |
|
328 |
- </Modal> |
|
247 |
+ <Modal open={modalEquipmentIsOpen} close={modalEquipmentClose} header="문의대상 장비 선택"> |
|
248 |
+ <div className="board-wrap"> |
|
249 |
+ <div> |
|
329 | 250 |
|
330 |
- <div className="content-wrap row"> |
|
331 |
- <ContentTitle contentTitle={"문의글 작성"} className={"margin-bottom2"} /> |
|
332 |
- <SubTitle explanation={"문의 정보"} className={"margin-bottom2"}/> |
|
333 |
- <table className="margin-bottom2 qna-insert senior-detail"> |
|
334 |
- <tr> |
|
335 |
- <th><span style={{color : "red"}}>*</span>구분</th> |
|
336 |
- <td colSpan={3}> |
|
337 |
- <div className="gender flex-start gap5"> |
|
338 |
- <div className="flex-start"> |
|
339 |
- <input type="radio" id="normal_question" name="question_type" value="일반문의" style={{width: '25px'}} |
|
340 |
- checked={equipmentInquiry['equipment_serial_number'] == null} |
|
341 |
- onChange={(e) => {equipmentInquiry['equipment_serial_number'] = null; setEquipmentInquiry({...equipmentInquiry});}}/> |
|
342 |
- <label for="normal_question">일반문의</label> |
|
343 |
- </div> |
|
344 |
- <div className="flex-start"> |
|
345 |
- <input type="radio" id="equipment_question" name="question_type" value="장비문의" style={{width: '25px'}} |
|
346 |
- checked={equipmentInquiry['equipment_serial_number'] != null} |
|
347 |
- onChange={(e) => {equipmentInquiry['equipment_serial_number'] = ''; setEquipmentInquiry({...equipmentInquiry});}}/> |
|
348 |
- <label for="equipment_question" >장비문의</label> |
|
349 |
- </div> |
|
350 |
- </div> |
|
351 |
- </td> |
|
352 |
- </tr> |
|
353 |
- {equipmentInquiry['equipment_serial_number'] != null ? |
|
354 |
- <tr> |
|
355 |
- <th><span style={{color : "red"}}>*</span>장비문의 구분</th> |
|
356 |
- <td colSpan={3}> |
|
357 |
- <select onChange={(e) => {equipmentInquiry['inquiry_type'] = e.target.value; setEquipmentInquiry({...equipmentInquiry});}}> |
|
358 |
- <option selected={equipmentInquiry['inquiry_type'] == '수리'}>수리</option> |
|
359 |
- <option selected={equipmentInquiry['inquiry_type'] == '교환'}>교환</option> |
|
360 |
- <option selected={equipmentInquiry['inquiry_type'] == '추가'}>추가</option> |
|
361 |
- <option selected={equipmentInquiry['inquiry_type'] == '기타'}>기타</option> |
|
362 |
- </select> |
|
363 |
- </td> |
|
364 |
- </tr> |
|
365 |
- : null} |
|
366 |
- <tr> |
|
367 |
- <th><span style={{color : "red"}}>*</span>문의제목</th> |
|
368 |
- <td colSpan={3}> |
|
369 |
- <input type="text" placeholder="문의글의 제목을 입력해주세요." |
|
370 |
- onChange={(e) => {equipmentInquiry['inquiry_title'] = e.target.value; setEquipmentInquiry({...equipmentInquiry});}} |
|
371 |
- ref={el => equipmentInquiryRef.current['inquiry_title'] = el} |
|
372 |
- /> |
|
373 |
- </td> |
|
374 |
- </tr> |
|
375 |
- <tr> |
|
376 |
- <th><span style={{color : "red"}}>*</span>내용</th> |
|
377 |
- <td colSpan={3}> |
|
378 |
- <textarea className="medicine" cols="30" rows="2" |
|
379 |
- onChange={(e) => {equipmentInquiry['inquiry_content'] = e.target.value; setEquipmentInquiry({...equipmentInquiry});}} |
|
380 |
- ref={el => equipmentInquiryRef.current['inquiry_content'] = el} |
|
381 |
- ></textarea> |
|
382 |
- </td> |
|
383 |
- </tr> |
|
384 |
- </table> |
|
385 |
- |
|
386 |
- {equipmentInquiry['equipment_serial_number'] != null |
|
387 |
- ?<> |
|
388 |
- <SubTitle explanation={equipmentInquiry['inquiry_type'] == '교환' || equipmentInquiry['inquiry_type'] == '수리' |
|
389 |
- ? <span>장비 정보 <span style={{color : "red"}}>(필수)</span></span> |
|
390 |
- : <span>장비 정보 (선택)</span> |
|
391 |
- } className={"display-inline-block margin-bottom2"}/> |
|
392 |
- <button className={"btn-small gray-btn"} style={{maxWidth: '150px'}} onClick={() => {equipmentSelectList(1); modalEquipmentOpen();}}>검색</button> |
|
393 |
- {CommonUtil.isEmpty(equipmentInquiry.equipment['equipment_serial_number']) == false ? |
|
394 |
- <> |
|
395 |
- <button className={"btn-small red-btn"} style={{maxWidth: '150px'}} onClick={equipmentInquirySelectCancel}>취소</button> |
|
396 |
- <table className="margin-bottom2 qna-insert senior-detail"> |
|
397 |
- <tr> |
|
398 |
- <th>장비 시리얼넘버</th> |
|
399 |
- <td colSpan={3}> |
|
400 |
- {equipmentInquiry.equipment['equipment_serial_number']} |
|
401 |
- </td> |
|
402 |
- </tr> |
|
403 |
- <tr> |
|
404 |
- <th>모델명</th> |
|
405 |
- <td> |
|
406 |
- {equipmentInquiry.equipment['equipment_name']} |
|
407 |
- </td> |
|
408 |
- <th>장비상태</th> |
|
409 |
- <td> |
|
410 |
- {equipmentStates[equipmentInquiry.equipment['equipment_state']]} |
|
411 |
- </td> |
|
412 |
- </tr> |
|
413 |
- <tr> |
|
414 |
- <th>소속기관</th> |
|
415 |
- <td> |
|
416 |
- {equipmentInquiry.equipment['agency_id'] == null ? equipmentInquiry.equipment['government_name'] : equipmentInquiry.equipment['agency_name']} |
|
417 |
- </td> |
|
418 |
- <th>대여시행자</th> |
|
419 |
- <td> |
|
420 |
- {CommonUtil.isEmpty(equipmentInquiry.equipment['equipment_serial_number']) == false |
|
421 |
- && CommonUtil.isEmpty(equipmentInquiry.equipment['rental_detail_insert_user_id']) == false |
|
422 |
- ? <> |
|
423 |
- {equipmentInquiry.equipment['rental_detail_insert_user_name']} |
|
424 |
- ({equipmentInquiry.equipment['rental_detail_insert_user_id']}) |
|
425 |
- </> |
|
426 |
- : '미대여'} |
|
427 |
- </td> |
|
428 |
- </tr> |
|
429 |
- <tr> |
|
430 |
- <th>장비사용대상자</th> |
|
431 |
- <td> |
|
432 |
- {equipmentInquiry.equipment['user_id'] == null ? '미대여' : equipmentInquiry.equipment['user_name']} |
|
433 |
- </td> |
|
434 |
- <th>대상자 ID</th> |
|
435 |
- <td> |
|
436 |
- {equipmentInquiry.equipment['user_id'] == null ? '미대여' : equipmentInquiry.equipment['user_id']} |
|
437 |
- </td> |
|
438 |
- </tr> |
|
439 |
- <tr> |
|
440 |
- <th>대상자 주소</th> |
|
441 |
- <td colSpan={3}> |
|
442 |
- {equipmentInquiry.equipment['user_id'] == null ? '미대여' : equipmentInquiry.equipment['user_address']} |
|
443 |
- </td> |
|
444 |
- </tr> |
|
445 |
- </table> |
|
446 |
- </>: null} |
|
447 |
- </>: null} |
|
448 |
- |
|
449 |
- <div className="btn-wrap flex-center margin-top5"> |
|
450 |
- <button className="btn-large gray-btn" onClick={() => navigate(-1)}>취소</button> |
|
451 |
- <button className="btn-large red-btn" onClick={() => equipmentInquiryInsert()}>등록</button> |
|
452 |
- </div> |
|
251 |
+ <div className="search-management flex-end margin-bottom2 margin-top gap"> |
|
252 |
+ <select style={{ maxWidth: '150px' }} |
|
253 |
+ onChange={(e) => equipmentSearchChange('equipment_state', e.target.value)}> |
|
254 |
+ <option value="">상태</option> |
|
255 |
+ {Object.keys(equipmentStates).map((key, idx) => { |
|
256 |
+ return ( |
|
257 |
+ <option key={key} value={key}> |
|
258 |
+ {equipmentStates[key]} |
|
259 |
+ </option> |
|
260 |
+ ) |
|
261 |
+ })} |
|
262 |
+ </select> |
|
263 |
+ <select style={{ maxWidth: '150px' }} |
|
264 |
+ onChange={(e) => equipmentSearchChange('searchType', e.target.value)}> |
|
265 |
+ <option value="">전체</option> |
|
266 |
+ <option value="equipment_name">모델명</option> |
|
267 |
+ <option value="equipment_serial_number">시리얼넘버</option> |
|
268 |
+ </select> |
|
269 |
+ <input type="text" |
|
270 |
+ value={equipmentSearch.searchText} |
|
271 |
+ onChange={(e) => equipmentSearchChange('searchText', e.target.value)} |
|
272 |
+ onKeyUp={(e) => equipmentSearchingEnter(e.key)} |
|
273 |
+ /> |
|
274 |
+ <button className={"btn-small gray-btn"} style={{ maxWidth: '150px' }} onClick={equipmentSearching}>검색</button> |
|
275 |
+ </div> |
|
453 | 276 |
|
454 |
- </div> |
|
455 |
- </main> |
|
277 |
+ <table class="caregiver-user protector-user"> |
|
278 |
+ <thead> |
|
279 |
+ <tr> |
|
280 |
+ <th>No</th> |
|
281 |
+ <th>장비사용대상자</th> |
|
282 |
+ <th>모델명</th> |
|
283 |
+ <th>시리얼넘버</th> |
|
284 |
+ <th>장비상태</th> |
|
285 |
+ <th>기관</th> |
|
286 |
+ <th>선택</th> |
|
287 |
+ </tr> |
|
288 |
+ </thead> |
|
289 |
+ <tbody> |
|
290 |
+ {equipment.equipmentList.map((item, idx) => { |
|
291 |
+ return ( |
|
292 |
+ <tr> |
|
293 |
+ <td data-label="No">{equipment.equipmentListCount - idx - (equipmentSearch.currentPage - 1) * equipmentSearch.perPage}</td> |
|
294 |
+ <td data-label="장비사용대상자"> |
|
295 |
+ {item['user_id'] == null ? '미대여' : item['user_name']} |
|
296 |
+ </td> |
|
297 |
+ <td data-label="모델명">{item['equipment_name']}</td> |
|
298 |
+ <td data-label="시리얼넘버">{item['equipment_serial_number']}</td> |
|
299 |
+ <td data-label="장비상태">{equipmentStates[item['equipment_state']]}</td> |
|
300 |
+ <td> |
|
301 |
+ {item['agency_id'] == null ? item['government_name'] : item['agency_name']} |
|
302 |
+ </td> |
|
303 |
+ <td data-label="대여시행자"> |
|
304 |
+ {equipmentInquiry.equipment['equipment_serial_number'] != item['equipment_serial_number'] |
|
305 |
+ ? <button className={"btn-small gray-btn"} style={{ maxWidth: '150px' }} |
|
306 |
+ onClick={() => { equipmentInquirySelect(item); modalEquipmentClose(); }}>선택</button> |
|
307 |
+ : <button className={"btn-small red-btn"} style={{ maxWidth: '150px' }} |
|
308 |
+ onClick={() => { equipmentInquirySelectCancel(); modalEquipmentClose(); }}>취소</button> |
|
309 |
+ } |
|
310 |
+ </td> |
|
311 |
+ </tr> |
|
312 |
+ ) |
|
313 |
+ })} |
|
314 |
+ {CommonUtil.isEmpty(equipment.equipmentList) ? |
|
315 |
+ <tr> |
|
316 |
+ <td colSpan={7}>조회된 데이터가 없습니다</td> |
|
317 |
+ </tr> |
|
318 |
+ : null} |
|
319 |
+ </tbody> |
|
320 |
+ </table> |
|
321 |
+ <Pagination |
|
322 |
+ currentPage={equipmentSearch.currentPage} |
|
323 |
+ perPage={equipmentSearch.perPage} |
|
324 |
+ totalCount={equipment.equipmentListCount} |
|
325 |
+ maxRange={5} |
|
326 |
+ click={equipmentSelectList} |
|
327 |
+ /> |
|
328 |
+ </div> |
|
329 |
+ </div> |
|
330 |
+ </Modal> |
|
331 |
+ |
|
332 |
+ <div className="content-wrap row"> |
|
333 |
+ <ContentTitle contentTitle={"문의글 작성"} className={"margin-bottom2"} /> |
|
334 |
+ <SubTitle explanation={"문의 정보"} className={"margin-bottom2"} /> |
|
335 |
+ <table className="margin-bottom2 qna-insert senior-detail"> |
|
336 |
+ <tr> |
|
337 |
+ <th><span style={{ color: "red" }}>*</span>구분</th> |
|
338 |
+ <td colSpan={3}> |
|
339 |
+ <div className="gender flex-start gap5"> |
|
340 |
+ <div className="flex-start"> |
|
341 |
+ <input type="radio" id="normal_question" name="question_type" value="일반문의" style={{ width: '25px' }} |
|
342 |
+ checked={equipmentInquiry['equipment_serial_number'] == null} |
|
343 |
+ onChange={(e) => { equipmentInquiry['equipment_serial_number'] = null; setEquipmentInquiry({ ...equipmentInquiry }); }} /> |
|
344 |
+ <label for="normal_question">일반문의</label> |
|
345 |
+ </div> |
|
346 |
+ <div className="flex-start"> |
|
347 |
+ <input type="radio" id="equipment_question" name="question_type" value="장비문의" style={{ width: '25px' }} |
|
348 |
+ checked={equipmentInquiry['equipment_serial_number'] != null} |
|
349 |
+ onChange={(e) => { equipmentInquiry['equipment_serial_number'] = ''; setEquipmentInquiry({ ...equipmentInquiry }); }} /> |
|
350 |
+ <label for="equipment_question" >장비문의</label> |
|
351 |
+ </div> |
|
352 |
+ </div> |
|
353 |
+ </td> |
|
354 |
+ </tr> |
|
355 |
+ {equipmentInquiry['equipment_serial_number'] != null ? |
|
356 |
+ <> |
|
357 |
+ <tr> |
|
358 |
+ <th><span style={{ color: "red" }}>*</span>시니어 선택</th> |
|
359 |
+ <td> |
|
360 |
+ { |
|
361 |
+ CommonUtil.isEmpty(state.loginUser) == false |
|
362 |
+ && state.loginUser['authority'] == 'ROLE_GUARDIAN' && state['seniorList'].value.length > 1 ? |
|
363 |
+ <select onChange={(e) => { |
|
364 |
+ const index = Number(e.target.value); |
|
365 |
+ setSeniorSearch(state['seniorList'].value[index]['user_id']); |
|
366 |
+ equipmentSearch['senior_id'] = seniorSearch; |
|
367 |
+ console.log("equipmentSearch['senior_id'] : ", equipmentSearch['senior_id']); |
|
368 |
+ }}> |
|
369 |
+ {state['seniorList'].value.map((item, idx) => { |
|
370 |
+ return ( |
|
371 |
+ <option key={idx} value={idx}>{item['user_name']}</option> |
|
372 |
+ ) |
|
373 |
+ })} |
|
374 |
+ </select> |
|
375 |
+ : null |
|
376 |
+ } |
|
377 |
+ </td> |
|
378 |
+ </tr> |
|
379 |
+ <tr> |
|
380 |
+ <th><span style={{ color: "red" }}>*</span>장비문의 구분</th> |
|
381 |
+ <td colSpan={3}> |
|
382 |
+ <select onChange={(e) => { equipmentInquiry['inquiry_type'] = e.target.value; setEquipmentInquiry({ ...equipmentInquiry }); }}> |
|
383 |
+ <option selected={equipmentInquiry['inquiry_type'] == '수리'}>수리</option> |
|
384 |
+ <option selected={equipmentInquiry['inquiry_type'] == '교환'}>교환</option> |
|
385 |
+ <option selected={equipmentInquiry['inquiry_type'] == '추가'}>추가</option> |
|
386 |
+ <option selected={equipmentInquiry['inquiry_type'] == '기타'}>기타</option> |
|
387 |
+ </select> |
|
388 |
+ </td> |
|
389 |
+ </tr> |
|
390 |
+ </> |
|
391 |
+ : null} |
|
392 |
+ <tr> |
|
393 |
+ <th><span style={{ color: "red" }}>*</span>문의제목</th> |
|
394 |
+ <td colSpan={3}> |
|
395 |
+ <input type="text" placeholder="문의글의 제목을 입력해주세요." |
|
396 |
+ onChange={(e) => { equipmentInquiry['inquiry_title'] = e.target.value; setEquipmentInquiry({ ...equipmentInquiry }); }} |
|
397 |
+ ref={el => equipmentInquiryRef.current['inquiry_title'] = el} |
|
398 |
+ /> |
|
399 |
+ </td> |
|
400 |
+ </tr> |
|
401 |
+ <tr> |
|
402 |
+ <th><span style={{ color: "red" }}>*</span>내용</th> |
|
403 |
+ <td colSpan={3}> |
|
404 |
+ <textarea className="medicine" cols="30" rows="2" |
|
405 |
+ onChange={(e) => { equipmentInquiry['inquiry_content'] = e.target.value; setEquipmentInquiry({ ...equipmentInquiry }); }} |
|
406 |
+ ref={el => equipmentInquiryRef.current['inquiry_content'] = el} |
|
407 |
+ ></textarea> |
|
408 |
+ </td> |
|
409 |
+ </tr> |
|
410 |
+ </table> |
|
411 |
+ |
|
412 |
+ {equipmentInquiry['equipment_serial_number'] != null |
|
413 |
+ ? <> |
|
414 |
+ <SubTitle explanation={equipmentInquiry['inquiry_type'] == '교환' || equipmentInquiry['inquiry_type'] == '수리' |
|
415 |
+ ? <span>장비 정보 <span style={{ color: "red" }}>(필수)</span></span> |
|
416 |
+ : <span>장비 정보 (선택)</span> |
|
417 |
+ } className={"display-inline-block margin-bottom2"} /> |
|
418 |
+ <button className={"btn-small gray-btn"} style={{ maxWidth: '150px' }} onClick={() => { equipmentSelectList(1); modalEquipmentOpen(); }}>검색</button> |
|
419 |
+ {CommonUtil.isEmpty(equipmentInquiry.equipment['equipment_serial_number']) == false ? |
|
420 |
+ <> |
|
421 |
+ <button className={"btn-small red-btn"} style={{ maxWidth: '150px' }} onClick={equipmentInquirySelectCancel}>취소</button> |
|
422 |
+ <table className="margin-bottom2 qna-insert senior-detail"> |
|
423 |
+ <tr> |
|
424 |
+ <th>장비 시리얼넘버</th> |
|
425 |
+ <td colSpan={3}> |
|
426 |
+ {equipmentInquiry.equipment['equipment_serial_number']} |
|
427 |
+ </td> |
|
428 |
+ </tr> |
|
429 |
+ <tr> |
|
430 |
+ <th>모델명</th> |
|
431 |
+ <td> |
|
432 |
+ {equipmentInquiry.equipment['equipment_name']} |
|
433 |
+ </td> |
|
434 |
+ <th>장비상태</th> |
|
435 |
+ <td> |
|
436 |
+ {equipmentStates[equipmentInquiry.equipment['equipment_state']]} |
|
437 |
+ </td> |
|
438 |
+ </tr> |
|
439 |
+ <tr> |
|
440 |
+ <th>소속기관</th> |
|
441 |
+ <td> |
|
442 |
+ {equipmentInquiry.equipment['agency_id'] == null ? equipmentInquiry.equipment['government_name'] : equipmentInquiry.equipment['agency_name']} |
|
443 |
+ </td> |
|
444 |
+ <th>대여시행자</th> |
|
445 |
+ <td> |
|
446 |
+ {CommonUtil.isEmpty(equipmentInquiry.equipment['equipment_serial_number']) == false |
|
447 |
+ && CommonUtil.isEmpty(equipmentInquiry.equipment['rental_detail_insert_user_id']) == false |
|
448 |
+ ? <> |
|
449 |
+ {equipmentInquiry.equipment['rental_detail_insert_user_name']} |
|
450 |
+ ({equipmentInquiry.equipment['rental_detail_insert_user_id']}) |
|
451 |
+ </> |
|
452 |
+ : '미대여'} |
|
453 |
+ </td> |
|
454 |
+ </tr> |
|
455 |
+ <tr> |
|
456 |
+ <th>장비사용대상자</th> |
|
457 |
+ <td> |
|
458 |
+ {equipmentInquiry.equipment['user_id'] == null ? '미대여' : equipmentInquiry.equipment['user_name']} |
|
459 |
+ </td> |
|
460 |
+ <th>대상자 ID</th> |
|
461 |
+ <td> |
|
462 |
+ {equipmentInquiry.equipment['user_id'] == null ? '미대여' : equipmentInquiry.equipment['user_id']} |
|
463 |
+ </td> |
|
464 |
+ </tr> |
|
465 |
+ <tr> |
|
466 |
+ <th>대상자 주소</th> |
|
467 |
+ <td colSpan={3}> |
|
468 |
+ {equipmentInquiry.equipment['user_id'] == null ? '미대여' : equipmentInquiry.equipment['user_address']} |
|
469 |
+ </td> |
|
470 |
+ </tr> |
|
471 |
+ </table> |
|
472 |
+ </> : null} |
|
473 |
+ </> : null} |
|
474 |
+ |
|
475 |
+ <div className="btn-wrap flex-center margin-top5"> |
|
476 |
+ <button className="btn-large gray-btn" onClick={() => navigate(-1)}>취소</button> |
|
477 |
+ <button className="btn-large red-btn" onClick={() => equipmentInquiryInsert()}>등록</button> |
|
478 |
+ </div> |
|
479 |
+ |
|
480 |
+ </div> |
|
481 |
+ </main> |
|
456 | 482 |
); |
457 | 483 |
} |
--- client/views/pages/healthcare/HealthcareAdmin.jsx
+++ client/views/pages/healthcare/HealthcareAdmin.jsx
... | ... | @@ -171,9 +171,9 @@ |
171 | 171 |
chartData['time'] = data[i]['temperature_time']; |
172 | 172 |
|
173 | 173 |
if (data[i]['temperature_date'].substr(5, 2) >= 11 || data[i]['temperature_date'].substr(5, 2) <= 2) { |
174 |
- _stackTemperatureData.unshift(chartData); |
|
175 |
- } else { |
|
176 | 174 |
_stackTemperatureData.push(chartData); |
175 |
+ } else { |
|
176 |
+ _stackTemperatureData.unshift(chartData); |
|
177 | 177 |
} |
178 | 178 |
} |
179 | 179 |
|
... | ... | @@ -305,6 +305,7 @@ |
305 | 305 |
return ( |
306 | 306 |
<td data-label="최근온도"> |
307 | 307 |
{data['temperature']} |
308 |
+ {/* <small>({data['time']})</small> */} |
|
308 | 309 |
</td> |
309 | 310 |
) |
310 | 311 |
}) |
... | ... | @@ -344,6 +345,9 @@ |
344 | 345 |
<th>생년월일</th> |
345 | 346 |
<th>성별</th> |
346 | 347 |
<th>연락처</th> |
348 |
+ |
|
349 |
+ {/* <th>최근방문일</th> |
|
350 |
+ <th>방문목적</th> */} |
|
347 | 351 |
</tr> |
348 | 352 |
</thead> |
349 | 353 |
<tbody> |
... | ... | @@ -363,6 +367,9 @@ |
363 | 367 |
<td data-label="생년월일">{item['user_birth']}</td> |
364 | 368 |
<td data-label="성별">{item['user_gender']}</td> |
365 | 369 |
<td data-label="연락처">{item['user_phonenumber']}</td> |
370 |
+ |
|
371 |
+ {/* <td>2023-04-11</td> |
|
372 |
+ <td>정기방문</td> */} |
|
366 | 373 |
</tr> |
367 | 374 |
) |
368 | 375 |
})} |
... | ... | @@ -407,6 +414,21 @@ |
407 | 414 |
<div className="right" style={{ height: "100%", }}> |
408 | 415 |
<div style={{ height: "100%" }}> |
409 | 416 |
<div className="tab-container" style={{ marginTop: "5rem" }}> |
417 |
+ {/* {CommonUtil.isEmpty(state.loginUser) == false && state.loginUser['authority'] == 'ROLE_AGENCY' ? |
|
418 |
+ <div className="flex-end margin-bottom"> |
|
419 |
+ <div className="flex searchselect" style={{width: 'auto'}}> |
|
420 |
+ |
|
421 |
+ <input type="radio" id="my_senior" name="senior" checked={isMySenior} |
|
422 |
+ onChange={(e) => {e.target.checked ? setIsMySenior(true) : null}}/> |
|
423 |
+ <label for="my_senior" style={{marginRight: '3rem'}}>나의 대상자 보기</label> |
|
424 |
+ |
|
425 |
+ <input type="radio" id="all_senior" name="senior" checked={!isMySenior} |
|
426 |
+ onChange={(e) => {e.target.checked ? setIsMySenior(false) : null}}/> |
|
427 |
+ <label for="all_senior" style={{marginRight: '0'}}>전체 대상자 보기</label> |
|
428 |
+ |
|
429 |
+ </div> |
|
430 |
+ </div> |
|
431 |
+ :null} */} |
|
410 | 432 |
<ul className="tab-menu flex-end"> |
411 | 433 |
{tab.map((item, idx) => { |
412 | 434 |
return ( |
--- client/views/pages/healthcare/HealthcareSelectOne.jsx
+++ client/views/pages/healthcare/HealthcareSelectOne.jsx
... | ... | @@ -186,19 +186,18 @@ |
186 | 186 |
|
187 | 187 |
isInsert: true, |
188 | 188 |
}; |
189 |
- |
|
190 |
- |
|
189 |
+ |
|
190 |
+ |
|
191 | 191 |
//방문 기록 목록 조회 |
192 |
- const visitRecordSelectList = (seniorNum) => { |
|
192 |
+ const visitRecordSelectList = () => { |
|
193 | 193 |
fetch("/welfare/visitRecordSelectList.json", { |
194 | 194 |
method: "POST", |
195 | 195 |
headers: { |
196 | 196 |
'Content-Type': 'application/json; charset=UTF-8' |
197 | 197 |
}, |
198 |
- body: JSON.stringify(seniorNum), |
|
198 |
+ body: JSON.stringify(senior), |
|
199 | 199 |
}).then((response) => response.json()).then((data) => { |
200 | 200 |
console.log("방문 기록 목록 조회 결과(건수) : ", data); |
201 |
- data.search = visitRecordList.search; |
|
202 | 201 |
setVisitRecordList(data['visitRecordList']); |
203 | 202 |
}).catch((error) => { |
204 | 203 |
console.log('visitRecordSelectList() /user/visitRecordSelectList.json error : ', error); |
... | ... | @@ -208,6 +207,7 @@ |
208 | 207 |
|
209 | 208 |
/****************** 방문 기록 (시작) ******************/ |
210 | 209 |
//방문 기록 정보 |
210 |
+ const [visitDate, setVisitDate] = React.useState(null); |
|
211 | 211 |
const [visitRecord, setVisitRecord] = React.useState({ ...visitRecordInit }); |
212 | 212 |
const visitRecordRef = React.useRef({ ...visitRecordInit }); |
213 | 213 |
|
... | ... | @@ -332,9 +332,14 @@ |
332 | 332 |
setVisitRecord({ ...visitRecordInit }); |
333 | 333 |
} |
334 | 334 |
|
335 |
- const calerndarClick = (visitRecord) => { |
|
336 |
- console.log("calerndarClick - visitRecord", visitRecord); |
|
337 |
- setVisitRecord(visitRecord); |
|
335 |
+ const calerndarClick = (data) => { |
|
336 |
+ console.log("calerndarClick - date, visitRecord", data); |
|
337 |
+ setVisitDate(data.date); |
|
338 |
+ if (CommonUtil.isEmpty(data.visitData) == false) { |
|
339 |
+ setVisitRecord(data.visitData); |
|
340 |
+ } else { |
|
341 |
+ setVisitRecord(null); |
|
342 |
+ } |
|
338 | 343 |
openModal(); |
339 | 344 |
} |
340 | 345 |
|
... | ... | @@ -353,76 +358,108 @@ |
353 | 358 |
</div> |
354 | 359 |
|
355 | 360 |
<div className="btn-wrap flex-end margin-bottom"> |
356 |
- <button className="btn-small gray-btn" onClick={() => {setVisitRecordInit(); openModal();}}>방문등록</button> |
|
361 |
+ <button className="btn-small gray-btn" onClick={() => { setVisitRecordInit(); openModal(); }}>방문등록</button> |
|
357 | 362 |
</div> |
358 | 363 |
|
359 |
- <Calendar data={{ senior: senior, medication: stackChartData, temperature: stackTemperatureData, visitRecordList: visitRecordList, onClick: calerndarClick}} /> |
|
364 |
+ <Calendar data={{ senior: senior, medication: stackChartData, temperature: stackTemperatureData, visitRecordList: visitRecordList, onClick: calerndarClick }} /> |
|
360 | 365 |
|
361 | 366 |
<div className="btn-wrap flex-center"> |
362 | 367 |
<button className="btn-large gray-btn" onClick={() => { navigate(-1) }}>이전</button> |
363 | 368 |
</div> |
364 | 369 |
|
365 |
- |
|
366 |
- <Modal open={modalOpen} close={closeModal} header="방문 정보 관리"> |
|
367 |
- <div className="board-wrap"> |
|
368 |
- <table className="flex70 margin-bottom">{/* questionnaire-table */} |
|
370 |
+ <Modal open={modalOpen} close={closeModal} header="시니어 정보 관리"> |
|
371 |
+ <div className="modal-visit board-wrap"> |
|
372 |
+ <table className="margin-bottom"> |
|
369 | 373 |
<tbody> |
370 | 374 |
<tr> |
371 |
- <th>방문날짜</th> |
|
372 |
- <td colSpan={3}> |
|
373 |
- <input type="date" value={visitRecord['visit_date']} |
|
374 |
- onChange={(e) => { |
|
375 |
- visitRecord['visit_date'] = e.target.value; |
|
376 |
- setVisitRecord({ ...visitRecord }); |
|
377 |
- }} |
|
378 |
- ref={el => visitRecordRef.current['visit_date'] = el} |
|
379 |
- /> |
|
380 |
- </td> |
|
375 |
+ <th></th> |
|
376 |
+ <th>02:00</th> |
|
377 |
+ <th>10:00</th> |
|
378 |
+ <th>12:00</th> |
|
379 |
+ <th>23:00</th> |
|
381 | 380 |
</tr> |
382 | 381 |
<tr> |
383 |
- <th>방문목적</th> |
|
384 |
- <td> |
|
385 |
- <select onChange={(e) => { |
|
386 |
- visitRecord['visit_reason'] = e.target.value; |
|
387 |
- setVisitRecord({ ...visitRecord }); |
|
388 |
- }} |
|
389 |
- ref={el => visitRecordRef.current['visit_reason'] = el} |
|
390 |
- > |
|
391 |
- <option value="" selected={CommonUtil.isEmpty(visitRecord['visit_reason'])}>방문목적선택</option> |
|
392 |
- <option value="정기방문" selected={visitRecord['visit_reason'] == "정기방문"}>정기방문</option> |
|
393 |
- <option value="어르신케어" selected={visitRecord['visit_reason'] == "어르신케어"}>어르신케어</option> |
|
394 |
- <option value="장비점검" selected={visitRecord['visit_reason'] == "장비점검"}>장비점검</option> |
|
395 |
- <option value="정기방문" selected={visitRecord['visit_reason'] == "기타"}>기타</option> |
|
396 |
- </select> |
|
397 |
- </td> |
|
382 |
+ <th>복약량</th> |
|
383 |
+ <td>1</td> |
|
384 |
+ <td>1</td> |
|
385 |
+ <td>1</td> |
|
386 |
+ <td>1</td> |
|
398 | 387 |
</tr> |
399 | 388 |
<tr> |
400 |
- <th>방문 상세 사유</th> |
|
401 |
- <td colSpan={3}> |
|
402 |
- <textarea className="medicine" style={{ height: "225px" }} name="" id="" cols="30" rows="10" |
|
403 |
- value={visitRecord['visit_content']} |
|
404 |
- onChange={(e) => { |
|
405 |
- visitRecord['visit_content'] = e.target.value; |
|
406 |
- setVisitRecord({ ...visitRecord }); |
|
407 |
- }} |
|
408 |
- ref={el => visitRecordRef.current['visit_content'] = el} |
|
409 |
- ></textarea> |
|
410 |
- </td> |
|
389 |
+ <th>온도</th> |
|
390 |
+ <td>30</td> |
|
391 |
+ <td>29</td> |
|
392 |
+ <td>28</td> |
|
393 |
+ <td>27</td> |
|
394 |
+ </tr> |
|
395 |
+ <tr> |
|
396 |
+ <th>배터리</th> |
|
397 |
+ <td colSpan={4}>30%</td> |
|
411 | 398 |
</tr> |
412 | 399 |
</tbody> |
413 | 400 |
</table> |
414 |
- <div className="flex-center"> |
|
415 |
- {CommonUtil.isEmpty(visitRecord.isInsert) == false && visitRecord.isInsert |
|
416 |
- ? <button className="btn-small red-btn" onClick={visitRecordInsert}>등록</button> |
|
417 |
- : <> |
|
418 |
- <button className="btn-small red-btn" onClick={visitRecordUpdate}>수정</button> |
|
419 |
- <button className="btn-small red-btn" onClick={visitRecordDelete}>삭제</button> |
|
420 |
- </> |
|
421 |
- } |
|
422 |
- </div> |
|
401 |
+ |
|
402 |
+ {CommonUtil.isEmpty(visitRecord) == false ? ( |
|
403 |
+ <> |
|
404 |
+ <table className="flex70 margin-bottom">{/* questionnaire-table */} |
|
405 |
+ <tbody> |
|
406 |
+ <tr> |
|
407 |
+ <th>방문날짜</th> |
|
408 |
+ <td colSpan={3}> |
|
409 |
+ <input type="date" value={visitRecord['visit_date']} |
|
410 |
+ onChange={(e) => { |
|
411 |
+ visitRecord['visit_date'] = e.target.value; |
|
412 |
+ setVisitRecord({ ...visitRecord }); |
|
413 |
+ }} |
|
414 |
+ ref={el => visitRecordRef.current['visit_date'] = el} |
|
415 |
+ /> |
|
416 |
+ </td> |
|
417 |
+ </tr> |
|
418 |
+ <tr> |
|
419 |
+ <th>방문목적</th> |
|
420 |
+ <td colSpan={3}> |
|
421 |
+ <select onChange={(e) => { |
|
422 |
+ visitRecord['visit_reason'] = e.target.value; |
|
423 |
+ setVisitRecord({ ...visitRecord }); |
|
424 |
+ }} |
|
425 |
+ ref={el => visitRecordRef.current['visit_reason'] = el} |
|
426 |
+ > |
|
427 |
+ <option value="" selected={CommonUtil.isEmpty(visitRecord['visit_reason'])}>방문목적선택</option> |
|
428 |
+ <option value="정기방문" selected={visitRecord['visit_reason'] == "정기방문"}>정기방문</option> |
|
429 |
+ <option value="어르신케어" selected={visitRecord['visit_reason'] == "어르신케어"}>어르신케어</option> |
|
430 |
+ <option value="장비점검" selected={visitRecord['visit_reason'] == "장비점검"}>장비점검</option> |
|
431 |
+ <option value="정기방문" selected={visitRecord['visit_reason'] == "기타"}>기타</option> |
|
432 |
+ </select> |
|
433 |
+ </td> |
|
434 |
+ </tr> |
|
435 |
+ <tr> |
|
436 |
+ <th>방문 상세 사유</th> |
|
437 |
+ <td colSpan={3}> |
|
438 |
+ <textarea className="medicine" style={{ height: "225px" }} name="" id="" cols="30" rows="10" |
|
439 |
+ value={visitRecord['visit_content']} |
|
440 |
+ onChange={(e) => { |
|
441 |
+ visitRecord['visit_content'] = e.target.value; |
|
442 |
+ setVisitRecord({ ...visitRecord }); |
|
443 |
+ }} |
|
444 |
+ ref={el => visitRecordRef.current['visit_content'] = el} |
|
445 |
+ ></textarea> |
|
446 |
+ </td> |
|
447 |
+ </tr> |
|
448 |
+ </tbody> |
|
449 |
+ </table> |
|
450 |
+ |
|
451 |
+ <div className="flex-center"> |
|
452 |
+ {CommonUtil.isEmpty(visitRecord.isInsert) == false && visitRecord.isInsert |
|
453 |
+ ? <button className="btn-small red-btn" onClick={visitRecordInsert}>등록</button> |
|
454 |
+ : <> |
|
455 |
+ <button className="btn-small red-btn" onClick={visitRecordUpdate}>수정</button> |
|
456 |
+ <button className="btn-small red-btn" onClick={visitRecordDelete}>삭제</button> |
|
457 |
+ </>} |
|
458 |
+ </div> |
|
459 |
+ </> |
|
460 |
+ ) : null} |
|
423 | 461 |
</div> |
424 | 462 |
</Modal> |
425 |
- |
|
426 | 463 |
</main> |
427 | 464 |
</> |
428 | 465 |
); |
--- client/views/pages/login/Login.jsx
+++ client/views/pages/login/Login.jsx
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 |
|
4 | 4 |
|
5 | 5 |
import Join from "./../join/Join.jsx"; |
6 |
+import passwordChange from "./../main/PasswordChange.jsx"; |
|
6 | 7 |
import Button from "../../component/Button.jsx"; |
7 | 8 |
|
8 | 9 |
|
... | ... | @@ -11,7 +12,7 @@ |
11 | 12 |
const location = useLocation(); |
12 | 13 |
|
13 | 14 |
//로그인 정보 |
14 |
- const [loginInfo, setLoginInfo] = React.useState({'user_id': '', 'user_password': ''}); |
|
15 |
+ const [loginInfo, setLoginInfo] = React.useState({ 'user_id': '', 'user_password': '' }); |
|
15 | 16 |
//사용자의 입력으로 인한 로그인 정보 변경 |
16 | 17 |
const loginInfoChange = (key, value) => { |
17 | 18 |
let newLoginInfo = JSON.parse(JSON.stringify(loginInfo)); |
... | ... | @@ -38,12 +39,8 @@ |
38 | 39 |
body: JSON.stringify(loginInfo), |
39 | 40 |
}).then((response) => response.json()).then((data) => { |
40 | 41 |
console.log("로그인 결과 : ", data); |
41 |
- if (data.isSuccess == true) { |
|
42 |
- if(data.message == "비밀번호를 변경해주세요.") { |
|
43 |
- |
|
44 |
- } else { |
|
45 |
- navigate('/'); |
|
46 |
- } |
|
42 |
+ if (data.isSuccess == true) { |
|
43 |
+ navigate('/'); |
|
47 | 44 |
} else { |
48 | 45 |
alert(data.message); |
49 | 46 |
} |
... | ... | @@ -55,7 +52,7 @@ |
55 | 52 |
return ( |
56 | 53 |
<div className="row login-wrap"> |
57 | 54 |
<h1>시니어 스마트 케어 모니터링 플랫폼</h1> |
58 |
- {location.pathname == '/Join' ? (<Join/>) : ( |
|
55 |
+ {location.pathname == '/Join' ? (<Join />) : ( |
|
59 | 56 |
<div className="container row flex-center join-login"> |
60 | 57 |
<div className="login-form"> |
61 | 58 |
<div> |
... | ... | @@ -65,16 +62,16 @@ |
65 | 62 |
<i className="fa-solid fa-user"></i> |
66 | 63 |
<input type="text" placeholder="아이디를 입력하세요" |
67 | 64 |
value={loginInfo['user_id']} |
68 |
- onChange={(e) => {loginInfoChange('user_id', e.target.value)}} |
|
69 |
- onKeyUp={(e) => {loginEnter(e.key)}} |
|
65 |
+ onChange={(e) => { loginInfoChange('user_id', e.target.value) }} |
|
66 |
+ onKeyUp={(e) => { loginEnter(e.key) }} |
|
70 | 67 |
/> |
71 | 68 |
</div> |
72 | 69 |
<div className="content"> |
73 | 70 |
<i className="fa-solid fa-lock"></i> |
74 | 71 |
<input type="password" placeholder="비밀번호를 입력하세요" |
75 | 72 |
value={loginInfo['user_password']} |
76 |
- onChange={(e) => {loginInfoChange('user_password', e.target.value)}} |
|
77 |
- onKeyUp={(e) => {loginEnter(e.key)}} |
|
73 |
+ onChange={(e) => { loginInfoChange('user_password', e.target.value) }} |
|
74 |
+ onKeyUp={(e) => { loginEnter(e.key) }} |
|
78 | 75 |
/> |
79 | 76 |
</div> |
80 | 77 |
</div> |
... | ... | @@ -89,7 +86,7 @@ |
89 | 86 |
<Button |
90 | 87 |
className={"join-btn"} |
91 | 88 |
btnName={"회원가입"} |
92 |
- onClick={() => {navigate('/Join')}} |
|
89 |
+ onClick={() => { navigate('/Join') }} |
|
93 | 90 |
/> |
94 | 91 |
</div> |
95 | 92 |
</div> |
--- client/views/pages/main/Main_agency.jsx
+++ client/views/pages/main/Main_agency.jsx
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 |
import Chart2_agency from "../../component/chart/Chart2_agency.jsx"; |
8 | 8 |
import AddCircleIcon from "@mui/icons-material/AddCircle"; |
9 | 9 |
import Calendar_agency from "../../component/Calendar_agency.jsx"; |
10 |
+import Cart7 from "../../component/chart/Chart7.jsx"; |
|
10 | 11 |
import tool from "../../../resources/files/images/tool.png"; |
11 | 12 |
import medicinebox from "../../../resources/files/images/medicinebox.png"; |
12 | 13 |
import box from "../../../resources/files/images/box.png"; |
... | ... | @@ -82,19 +83,25 @@ |
82 | 83 |
</li> |
83 | 84 |
</ul> |
84 | 85 |
</div> |
85 |
- <div className="flex-start margin-bottom2"><img src={medicinebox} alt="" /><TitleSmall title={"방문/전화 관리 리스트"} /></div> |
|
86 |
- <div className="main-grid-agency"> |
|
87 |
- <div className="content-box combine-left-government3 visitlist"> |
|
88 |
- <div className="margin-bottom2"> |
|
89 |
- <Calendar_agency /> |
|
90 |
- </div> |
|
91 |
- <div> |
|
86 |
+ <div className="flex-start margin-bottom2"><img src={medicinebox} alt="" /><TitleSmall title={"방문/전화 관리 리스트"} /></div> |
|
87 |
+ <div className="main-grid-agency margin-bottom2"> |
|
88 |
+ <div className="content-box combine-left-government3 visitlist"> |
|
89 |
+ <div className="margin-bottom2"> |
|
90 |
+ <Calendar_agency /> |
|
91 |
+ </div> |
|
92 |
+ <div className="margin-bottom2"> |
|
92 | 93 |
<Table className="agency-visitlist" head={thead} contents={content} contentKey={key} /> |
93 |
- </div> |
|
94 |
+ </div> |
|
95 |
+ </div> |
|
96 |
+ </div> |
|
97 |
+ <div className="flex-start margin-bottom2"><img src={medicinebox} alt="" /><TitleSmall title={"연령대별 통계"} /></div> |
|
98 |
+ <div className="main-grid-agency"> |
|
99 |
+ <div className="content-box combine-left-government3 visitlist margin-bottom2"> |
|
100 |
+ <Cart7 /> |
|
94 | 101 |
</div> |
95 | 102 |
</div> |
96 | 103 |
<div> |
97 |
- |
|
104 |
+ |
|
98 | 105 |
</div> |
99 | 106 |
</main> |
100 | 107 |
); |
--- client/views/pages/main/Main_agencyAdmin.jsx
+++ client/views/pages/main/Main_agencyAdmin.jsx
... | ... | @@ -287,7 +287,7 @@ |
287 | 287 |
<div className="flex"> |
288 | 288 |
<Title title={`보호사별 대상자 등록 현황`} explanation={"약상자 사용자의 데이터 차트가 보여집니다."} /> |
289 | 289 |
</div> |
290 |
- <Chart5_agencyadmin data={seniorEnroll} /> |
|
290 |
+ <Chart5_agencyadmin /> |
|
291 | 291 |
</div> |
292 | 292 |
</div> |
293 | 293 |
</main> |
--- client/views/pages/main/Main_guardian.jsx
+++ client/views/pages/main/Main_guardian.jsx
... | ... | @@ -238,10 +238,14 @@ |
238 | 238 |
// searching(); |
239 | 239 |
// }, []); |
240 | 240 |
|
241 |
- const calerndarClick = (date, visitRecord) => { |
|
242 |
- console.log("calerndarClick - date, visitRecord", date, visitRecord); |
|
243 |
- setVisitDate(date); |
|
244 |
- setVisitRecord(visitRecord); |
|
241 |
+ const calerndarClick = (data) => { |
|
242 |
+ console.log("calerndarClick - date, visitRecord", data); |
|
243 |
+ setVisitDate(data.date); |
|
244 |
+ if (CommonUtil.isEmpty(data.visitData) == false) { |
|
245 |
+ setVisitRecord(data.visitData); |
|
246 |
+ } else { |
|
247 |
+ setVisitRecord(null); |
|
248 |
+ } |
|
245 | 249 |
openModal(); |
246 | 250 |
} |
247 | 251 |
|
... | ... | @@ -317,7 +321,8 @@ |
317 | 321 |
</tr> |
318 | 322 |
</tbody> |
319 | 323 |
</table> |
320 |
- {visitRecord != null ? ( |
|
324 |
+ |
|
325 |
+ {CommonUtil.isEmpty(visitRecord) == false ? ( |
|
321 | 326 |
<table className="flex70 margin-bottom">{/* questionnaire-table */} |
322 | 327 |
<tbody> |
323 | 328 |
<tr> |
+++ client/views/pages/main/PasswordChange.jsx
... | ... | @@ -0,0 +1,158 @@ |
1 | +import React from "react"; | |
2 | +import Button from "../../component/Button.jsx"; | |
3 | +import { useNavigate, useLocation } from "react-router"; | |
4 | +import { useSelector } from "react-redux"; | |
5 | + | |
6 | +import CommonUtil from "../../../resources/js/CommonUtil.js"; | |
7 | + | |
8 | +export default function PasswordChange() { | |
9 | + const navigate = useNavigate(); | |
10 | + const location = useLocation(); | |
11 | + const state = useSelector((state) => { return state }); | |
12 | + | |
13 | + //아이디 중복 확인 | |
14 | + const [isIdCheck, setIsIdCheck] = React.useState(false); | |
15 | + | |
16 | + //등록할 사용자 정보 | |
17 | + const [user, setUser] = React.useState({ | |
18 | + 'user_id': null, | |
19 | + 'user_name': null, | |
20 | + 'user_password': null, | |
21 | + 'user_password_check': null, | |
22 | + 'user_phonenumber': null, | |
23 | + 'user_birth': null, | |
24 | + 'user_gender': null, | |
25 | + 'user_address': null, | |
26 | + 'user_email': null, | |
27 | + //'authority': CommonUtil.isEmpty(defaultAuthority) ? state.loginUser['authority'] : defaultAuthority, | |
28 | + //'agency_id': CommonUtil.isEmpty(defaultAgencyId) ? state.loginUser['agency_id'] : defaultAgencyId, | |
29 | + //'government_id': CommonUtil.isEmpty(defaultGovernmentId) ? state.loginUser['government_id'] : defaultGovernmentId, | |
30 | + }); | |
31 | + //각 데이터별로 Dom 정보 담을 Ref 생성 | |
32 | + const userRefInit = JSON.parse(JSON.stringify(user)); | |
33 | + userRefInit['user_gender'] = {}; | |
34 | + userRefInit['user_id_check_button'] = null; | |
35 | + const userRef = React.useRef(userRefInit); | |
36 | + //등록할 사용자 정보 변경 | |
37 | + const userValueChange = (targetKey, value) => { | |
38 | + let newUser = JSON.parse(JSON.stringify(user)); | |
39 | + newUser[targetKey] = value; | |
40 | + setUser(newUser); | |
41 | + } | |
42 | + //사용자 등록 유효성 검사 | |
43 | + const userInsertValidation = () => { | |
44 | + if (CommonUtil.isEmpty(user['user_password']) == true) { | |
45 | + userRef.current['user_password'].focus(); | |
46 | + alert("비밀번호를 입력해 주세요."); | |
47 | + return false; | |
48 | + } | |
49 | + if (user['user_password'] != user['user_password_check']) { | |
50 | + userRef.current['user_password_check'].focus(); | |
51 | + alert("비밀번호가 일치하지 않습니다."); | |
52 | + return false; | |
53 | + } | |
54 | + | |
55 | + return true; | |
56 | + } | |
57 | + | |
58 | + //사용자 등록 | |
59 | + const userUpdate = () => { | |
60 | + if (userInsertValidation() == false) { | |
61 | + return; | |
62 | + } | |
63 | + | |
64 | + fetch("/user/userUpdate.json", { | |
65 | + method: "POST", | |
66 | + headers: { | |
67 | + 'Content-Type': 'application/json; charset=UTF-8' | |
68 | + }, | |
69 | + body: JSON.stringify(user), | |
70 | + }).then((response) => response.json()).then((data) => { | |
71 | + console.log("사용자 등록 결과(건수) : ", data); | |
72 | + if (data > 0) { | |
73 | + alert("계정생성완료"); | |
74 | + navigate(-1); | |
75 | + } else { | |
76 | + alert("계정생성에 실패하였습니다. 관리자에게 문의바랍니다."); | |
77 | + } | |
78 | + }).catch((error) => { | |
79 | + console.log('userUpdate() /user/userInsert.json error : ', error); | |
80 | + }); | |
81 | + } | |
82 | + | |
83 | + //로그아웃 | |
84 | + const logout = () => { | |
85 | + fetch("/user/logout.json", { | |
86 | + method: "POST", | |
87 | + headers: { | |
88 | + 'Content-Type': 'application/json; charset=UTF-8' | |
89 | + }, | |
90 | + /* body: JSON.stringify({}), */ | |
91 | + }).then((response) => response.json()).then((data) => { | |
92 | + console.log("로그아웃 결과 : ", data); | |
93 | + if (data == true) { | |
94 | + navigate('/'); | |
95 | + } else { | |
96 | + alert('로그아웃 실패, 관리자에게 문의바랍니다.'); | |
97 | + } | |
98 | + }).catch((error) => { | |
99 | + console.log('logout() /user/logout.json error : ', error); | |
100 | + }); | |
101 | + }; | |
102 | + | |
103 | + //Mounted | |
104 | + React.useEffect(() => { | |
105 | + //authoritiesSelect(); | |
106 | + //orgSelectListOfHierarchy(); | |
107 | + }, []); | |
108 | + | |
109 | + | |
110 | + return ( | |
111 | + <div className="row login-wrap"> | |
112 | + <h1>시니어 스마트 케어 모니터링 플랫폼</h1> | |
113 | + <div className="container row flex-center join-login"> | |
114 | + <div className="join-group"> | |
115 | + <h3>최초 로그인</h3> | |
116 | + <div className="join-inner"> | |
117 | + <div> | |
118 | + <div className="margin-bottom2"> | |
119 | + <p className="margin-bottom"> | |
120 | + 시니어 스마트 케어 모니터링 플랫폼에 최초로 로그인 하셨습니다. | |
121 | + </p> | |
122 | + <p> | |
123 | + 최초 로그인 시, 임시 비밀번호 변경 후 이용하실 수 있습니다. | |
124 | + </p> | |
125 | + </div> | |
126 | + </div> | |
127 | + <div> | |
128 | + <div className="flex-start margin-bottom2"> | |
129 | + <label className="flex25" htmlFor="password"><span style={{ color: "red" }}>*</span>비밀번호</label> | |
130 | + <input type="password" | |
131 | + value={user['user_password']} | |
132 | + onChange={(e) => { userValueChange('user_password', e.target.value) }} | |
133 | + ref={el => userRef.current['user_password'] = el} | |
134 | + /> | |
135 | + </div> | |
136 | + </div> | |
137 | + <div> | |
138 | + <div className="flex-start margin-bottom2"> | |
139 | + <label className="flex25" htmlFor="password_check"><span style={{ color: "red" }}>*</span>비밀번호 확인</label> | |
140 | + <input type="password" | |
141 | + value={user['user_password_check']} | |
142 | + onChange={(e) => { userValueChange('user_password_check', e.target.value) }} | |
143 | + ref={el => userRef.current['user_password_check'] = el} | |
144 | + /> | |
145 | + </div> | |
146 | + </div> | |
147 | + | |
148 | + <div className="btn-wrap"> | |
149 | + <button className={"gray-btn btn-large"} onClick={logout}>취소</button> | |
150 | + <button className={"red-btn btn-large"} onClick={userUpdate}>수정</button> | |
151 | + </div> | |
152 | + | |
153 | + </div> | |
154 | + </div> | |
155 | + </div> | |
156 | + </div > | |
157 | + ); | |
158 | +} |
--- client/views/pages/user_management/AgencyAdminSeniorSelect.jsx
+++ client/views/pages/user_management/AgencyAdminSeniorSelect.jsx
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 |
import House from "../../../resources/files/icon/house.png"; |
8 | 8 |
import Arrow from "../../../resources/files/icon/arrow.png"; |
9 | 9 |
|
10 |
+import Modal from "../../component/Modal.jsx"; |
|
10 | 11 |
import Modal_SeniorInsert from "../../component/Modal_SeniorInsert.jsx"; |
11 | 12 |
|
12 | 13 |
import CommonUtil from "../../../resources/js/CommonUtil.js"; |
... | ... | @@ -14,6 +15,14 @@ |
14 | 15 |
export default function AgencyAdminSeniorSelect() { |
15 | 16 |
const navigate = useNavigate(); |
16 | 17 |
const location = useLocation(); |
18 |
+ |
|
19 |
+ const [modalOpen, setModalOpen] = React.useState(false); |
|
20 |
+ const openModal = () => { |
|
21 |
+ setModalOpen(true); |
|
22 |
+ }; |
|
23 |
+ const closeModal = () => { |
|
24 |
+ setModalOpen(false); |
|
25 |
+ }; |
|
17 | 26 |
|
18 | 27 |
//대상자(시니어) 등록 모달 오픈 여부 |
19 | 28 |
const [modalSeniorInsertIsOpen, setModalSeniorInsertIsOpen] = React.useState(false); |
... | ... | @@ -178,6 +187,28 @@ |
178 | 187 |
}); |
179 | 188 |
} |
180 | 189 |
|
190 |
+ const [CheckList, setCheckList] = React.useState([]); |
|
191 |
+ const [IdList, setIdList] = React.useState([]); |
|
192 |
+ |
|
193 |
+ React.useEffect(() => { |
|
194 |
+ let ids = [] |
|
195 |
+ agencySenior.seniorList.map((item, i) => { |
|
196 |
+ ids[i] = item['user_id'] |
|
197 |
+ }) |
|
198 |
+ setIdList(ids) |
|
199 |
+ }, [agencySenior.seniorList]) |
|
200 |
+ |
|
201 |
+ const onChangeAll = (e) => { |
|
202 |
+ setCheckList(e.target.checked ? IdList : []) |
|
203 |
+ } |
|
204 |
+ |
|
205 |
+ const onChangeEach = (e, id) => { |
|
206 |
+ if (e.target.checked) { |
|
207 |
+ setCheckList([...CheckList, id]); |
|
208 |
+ } else { |
|
209 |
+ setCheckList(CheckList.filter((checkedId) => checkedId !== id)); |
|
210 |
+ } |
|
211 |
+ } |
|
181 | 212 |
|
182 | 213 |
React.useEffect(() => { |
183 | 214 |
agentSelectList(); |
... | ... | @@ -243,12 +274,16 @@ |
243 | 274 |
) |
244 | 275 |
} /> |
245 | 276 |
<div className="btn-wrap flex-end margin-bottom "> |
246 |
- {/* <button className={"btn-small gray-btn"} onClick={() => {modalEquipmentOpen()}}>등록</button> */} |
|
277 |
+ <button className={"btn-small gray-btn"} onClick={modalSeniorInsertOpen}>신규등록</button> |
|
278 |
+ <button className={"btn-small gray-btn"} onClick={() => { openModal() }}>보호사 배정하기</button> |
|
247 | 279 |
</div> |
248 | 280 |
</div> |
249 | 281 |
<table className={"protector-user"}> |
250 | 282 |
<thead> |
251 | 283 |
<tr> |
284 |
+ <th> |
|
285 |
+ <input type="checkbox" name="checkAll" id="checkAll" onChange={onChangeAll} checked={CheckList.length === IdList.length} /> |
|
286 |
+ </th> |
|
252 | 287 |
<th>No</th> |
253 | 288 |
<th>소속기관명</th> |
254 | 289 |
<th>이름</th> |
... | ... | @@ -264,6 +299,9 @@ |
264 | 299 |
{agencySenior.seniorList.map((item, idx) => { |
265 | 300 |
return ( |
266 | 301 |
<tr key={idx}> |
302 |
+ <td data-label="checkbox"> |
|
303 |
+ <input type="checkbox" name="checkSenior" id={"check" + idx} onChange={(e) => onChangeEach(e, item['user_id'])} checked={CheckList.includes(item['user_id'])} /> |
|
304 |
+ </td> |
|
267 | 305 |
<td data-label="No">{agencySenior.seniorListCount - idx - (agencySenior.search.currentPage - 1) * agencySenior.search.perPage}</td> |
268 | 306 |
<td data-label="소속기관명">{item['agency_name']}</td> |
269 | 307 |
<td data-label="이름">{item['user_name']}</td> |
... | ... | @@ -277,10 +315,7 @@ |
277 | 315 |
} |
278 | 316 |
</td> |
279 | 317 |
<td data-label="보호사"> |
280 |
- {CommonUtil.isEmpty(item['agent_user_names']) |
|
281 |
- ? <button className="btn-small gray-btn" onClick={() => agentSeniorInsert(item)}>내 돌봄 대상자로 추가</button> |
|
282 |
- : item['agent_user_names'] |
|
283 |
- } |
|
318 |
+ {item['agent_user_names']} |
|
284 | 319 |
</td> |
285 | 320 |
<td data-label="대상자관리"> |
286 | 321 |
<button className="btn-small gray-btn" onClick={() => { |
... | ... | @@ -367,6 +402,45 @@ |
367 | 402 |
</ul> |
368 | 403 |
</div> |
369 | 404 |
</div> |
405 |
+ <Modal open={modalOpen} close={closeModal} header="보호사 배정하기"> |
|
406 |
+ <div className="modal-visit board-wrap"> |
|
407 |
+ <table className="margin-bottom"> |
|
408 |
+ <tbody> |
|
409 |
+ <tr> |
|
410 |
+ <th>담당 보호사</th> |
|
411 |
+ <td> |
|
412 |
+ <select name="" id=""> |
|
413 |
+ <option value="">담당 보호사를 선택해주세요.</option> |
|
414 |
+ {agent.userList.map((user, idx) => { |
|
415 |
+ return ( |
|
416 |
+ <option key={idx} value={user['user_id']}>{user['user_name']}</option> |
|
417 |
+ ) |
|
418 |
+ })} |
|
419 |
+ </select> |
|
420 |
+ </td> |
|
421 |
+ </tr> |
|
422 |
+ </tbody> |
|
423 |
+ </table> |
|
424 |
+ <div className="flex-center"> |
|
425 |
+ <button className="btn-small gray-btn">등록</button> |
|
426 |
+ <button className="btn-small red-btn">삭제</button> |
|
427 |
+ </div> |
|
428 |
+ </div> |
|
429 |
+ </Modal> |
|
430 |
+ |
|
431 |
+ <Modal_SeniorInsert |
|
432 |
+ open={modalSeniorInsertIsOpen} |
|
433 |
+ close={modalSeniorInsertClose} |
|
434 |
+ seniorInsertCallback={() => { |
|
435 |
+ search.searchText = ''; |
|
436 |
+ search.searchType = ''; |
|
437 |
+ searching(); |
|
438 |
+ modalSeniorInsertClose(); |
|
439 |
+ }} |
|
440 |
+ defaultAgentId={state.loginUser['user_id']} |
|
441 |
+ defaultAgencyId={state.loginUser['agency_id']} |
|
442 |
+ defaultGovernmentId={state.loginUser['government_id']} |
|
443 |
+ /> |
|
370 | 444 |
</main> |
371 | 445 |
); |
372 | 446 |
} |
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?