최정임 최정임 2023-03-06
Merge branch 'admin' of http://210.180.118.83/yjryu/senior_care_system into admin
@0f8fe44dcad495800d7fbb305458d9cfff82b72d
client/views/component/QnAModal.jsx
--- client/views/component/QnAModal.jsx
+++ client/views/component/QnAModal.jsx
@@ -4,45 +4,106 @@
 import SubTitle from "./SubTitle.jsx";
 import { useNavigate } from "react-router";
 
-export default function QaAModal({ open, close, }) {
+export default function QnAModal({ open, close }) {
+  const [qnaRegisteringList, setQnaRegisteringList] = React.useState([]);
+
+  const [idx, setIdx] = React.useState();
+  const [title, setTitle] = React.useState("");
+  const [datetime, setDatetime] = React.useState("");
+  const [contents, setContents] = React.useState("");
+
+  //qna등록
+  const getQnaRegisteringList = () => {
+    fetch("/qna/qnaInsert.json", {
+      method: "POST",
+      headers: {
+        "Content-Type": "application/json; charset=UTF-8;",
+      },
+      body: JSON.stringify({
+        qna_idx: idx,
+        qna_title: title,
+        qna_insert_user_id: "gym1004",
+        qna_insert_datetime: datetime,
+      }),
+    })
+      .then((response) => response.json())
+      .then((data) => {
+        if (data > 0) {
+          console.log(data);
+          alert("등록완료");
+          close(true);
+        } else {
+          alert("등록실패, 관리자에게 문의해주세요.");
+        }
+      })
+      .catch((error) => {
+        console.log("qna error : ", error);
+      });
+  };
+
+  //게시판
+  const thead = ["제목", "작성자", "작성일자"];
+  const key = ["qna_title", "qna_insert_user_name", "qna_insert_datetime"];
+
   return (
     <div class={open ? "openModal modal" : "modal"}>
-    {open ? (
-      <div className="modal-inner">
-        <div className="modal-header flex">
-          Q&A등록
-          <Button className={"close"} onClick={close} btnName={"X"} />
-        </div>
-        <div className="modal-main"><div className="board-wrap">        
-        <div>
-        <SubTitle explanation={"작성자 정보"} />
-        <table className="margin-bottom2 qna-insert">
-          <tr>
-            <th>작성자</th>
-            <td>
-              <input type="text" placeholder="자동입력부분" />
-            </td>
-          </tr>
+      {open ? (
+        <div className="modal-inner">
+          <div className="modal-header flex">
+            Q&A등록
+            <Button className={"close"} onClick={close} btnName={"X"} />
+          </div>
+          <div className="modal-main">
+            <div className="board-wrap">
+              <div>
+                <SubTitle explanation={"작성자 정보"} />
+                <table className="margin-bottom2 qna-insert">
+                  <tr>
+                    <th>작성자</th>
+                    <td>
+                      <input type="text" placeholder="자동입력부분" />
+                    </td>
+                  </tr>
 
-          <tr>
-            <th>제목</th>
-            <td colSpan={3}>
-              <input type="text" />
-            </td>
-          </tr>
-          <tr>
-              <th>내용</th>
-              <td colSpan={3}>
-                <textarea className="medicine" cols="30" rows="2"></textarea>
-              </td>
-            </tr>
-        </table>
+                  <tr>
+                    <th>제목</th>
+                    <td colSpan={3}>
+                      <input
+                        type="text"
+                        value={title}
+                        onInput={(e) => {
+                          setTitle(e.target.value);
+                        }}
+                      />
+                    </td>
+                  </tr>
+                  <tr>
+                    <th>내용</th>
+                    <td colSpan={3}>
+                      <textarea
+                        className="medicine"
+                        cols="30"
+                        rows="2"
+                        value={contents}
+                        onInput={(e) => {
+                          setContents(e.target.value);
+                        }}
+                      ></textarea>
+                    </td>
+                  </tr>
+                </table>
+              </div>
+              <div className="flex-center">
+                <Button
+                  className={"btn-small red-btn"}
+                  btnName={"저장"}
+                  onClick={() => getQnaRegisteringList()}
+                />
+              </div>
+            </div>
+          </div>
         </div>
-        <div className="flex-center"><Button className={"btn-small red-btn"} btnName={"저장"} /></div >
-      </div></div>
-      </div>
-    ) : null}
-  </div>
-    
+      ) : null}
+    </div>
   );
 }
client/views/pages/App.jsx
--- client/views/pages/App.jsx
+++ client/views/pages/App.jsx
@@ -26,8 +26,8 @@
   };
 
 
-  const menuItems = GuardianApp.menuItems;  //AdminApp, GovernmentApp, AllApp, AgencyApp, GuardianApp 
-  const AppRoute = GuardianApp.AppRoute;
+  const menuItems = AllApp.menuItems;  //AdminApp, GovernmentApp, AllApp, AgencyApp, GuardianApp 
+  const AppRoute = AllApp.AppRoute;
 
 
   const { title } = menuItems.find(
client/views/pages/callcenter/QuestionConfirm.jsx
--- client/views/pages/callcenter/QuestionConfirm.jsx
+++ client/views/pages/callcenter/QuestionConfirm.jsx
@@ -5,7 +5,10 @@
 import { useNavigate } from "react-router";
 
 export default function QuestionConfirm() {
+
   const navigate = useNavigate();
+
+
   return (
     <main>
       <div className="content-wrap row">
@@ -44,14 +47,14 @@
             className={"btn-large gray-btn"}
             btnName={"이전"}
             onClick={() => {
-              navigate("/QandASelect");
+              navigate("/QuestionSelect");
             }}
           />
           <Button
             className={"btn-large green-btn"}
             btnName={"등록"}
             onClick={() => {
-              navigate("/QandASelect");
+              navigate("/QuestionSelect");
             }}
           />
         </div>
client/views/pages/callcenter/QuestionSelect.jsx
--- client/views/pages/callcenter/QuestionSelect.jsx
+++ client/views/pages/callcenter/QuestionSelect.jsx
@@ -13,16 +13,16 @@
   const openModal = () => {
     setModalOpen(true);
   };
-  const closeModal = () => {
+  const closeModal = (isInsertComplete) => {
     setModalOpen(false);
+    if (isInsertComplete == true) {
+      getQnaList();
+    }
   };
 
-  const [qnaList, setQnaList] = React.useState();
+  const [qnaList, setQnaList] = React.useState([]);
 
-  const [state, setState] = React.useState();
-  const [title, setTitle] = React.useState();
-  const [username, setUsername] = React.useState();
-  const [datetime, setDatetime] = React.useState();
+  const [idx, setIdx] = React.useState();
 
   //-------- 페이징 작업 설정 시작 --------//
   const limit = 15; // 페이지당 보여줄 공지 개수
@@ -39,17 +39,15 @@
       },
       body: JSON.stringify({
 
-        qna_state: state,
-        qna_title: title,
-        qna_insert_user_id: username,
-        qna_insert_datetime: datetime,
+        qna_idx: idx,
+
       }),
     })
       .then((response) => response.json())
       .then((data) => {
         console.log(data);
         setQnaList(data);
-        // setMyQnaTotal(data.length);
+        setMyQnaTotal(data.length);
       })
       .catch((error) => {
         console.log(
@@ -61,25 +59,8 @@
 
   //게시판
   const thead = ["No", "답변상태", "제목", "작성자", "작성일자"];
-  const key = ["idx", "state", "title", "username", "datetime"];
-  const content = [
-    {
-      No: 1,
-      answer: "답변완료",
-      title: (
-        <div
-          className="title"
-          onClick={() => {
-            navigate("/QuestionConfirm");
-          }}
-        >
-          담당자 바꿔주세요
-        </div>
-      ),
-      writer: "홍길동",
-      date: "2023-01-27",
-    },
-  ];
+  const key = ["qna_idx", "qna_state", "qna_title", "qna_insert_user_name", "qna_insert_datetime"];
+  
 
   React.useEffect(() => {
 
@@ -114,7 +95,7 @@
         <Table
           className="equipment-detail"
           head={thead}
-          contents={content}
+          contents={qnaList}
           contentKey={key}
           view={"qna"}
           offset={offset}
client/views/pages/equipment/EquipmentManagementSelect.jsx
--- client/views/pages/equipment/EquipmentManagementSelect.jsx
+++ client/views/pages/equipment/EquipmentManagementSelect.jsx
@@ -149,7 +149,7 @@
 	}
 
 
-	// 관리자 전체 장비 목록
+	// 전체 장비 목록
 	const [equipmentList, setEquipmentList] = React.useState([]);
 	// 장비
 	const [equipment, setEquipment] = React.useState({
@@ -162,20 +162,10 @@
 	});
 	// 장비 등록 모달창
 	const [equipmentInsertModal, setEquipmentInsertModal] = React.useState(false);
+	// 장비 상세 조회 모달창
+	const [equipmentOneModal, setEquipmentOneModal] = React.useState(false);
 
-	// 장비 등록 모달창 열기
-	const equipmentInsertModalOpen = () => {
-		setEquipmentInsertModal(true);
-	};
-	// 장비 등록 모달창 닫기
-	const equipmentInsertModalClose = () => {
-		// 장비 초기화
-		setEquipment(equipment_);
-		setEquipmentInsertModal(false);
-	};
-
-
-	// 관리자 전체 장비 목록 조회
+	// 전체 장비 목록 조회
 	const equipmentSelectList = () => {
 		console.log('equipmentSelectList Function Run');
 		fetch("/equipment/equipmentSelectList.json", {
@@ -192,9 +182,20 @@
 		});
 	}
 
+	// 장비 등록 모달창 열기
+	const equipmentInsertModalOpen = () => {
+		setEquipmentInsertModal(true);
+	};
+	// 장비 등록 모달창 닫기
+	const equipmentInsertModalClose = () => {
+		// 장비 초기화
+		setEquipment(equipment_);
+		setEquipmentInsertModal(false);
+	};
+
 	// 장비 임시 데이터
 	const equipmentChange = (e) => {
-		console.log('equipmentChange: ', e.target.name, e.target.value);
+		// console.log('equipmentChange: ', e.target.name, e.target.value);
 
 		// 원본 데이터 복사 및 수정
 		let data = {};
@@ -227,6 +228,14 @@
 				return;
 			}
 		}
+		
+		// 시리얼 넘버 중복검사
+		for(let i = 0; i < equipmentList.length; i++) {
+			if(equipment["equipment_serial_number"] == equipmentList[i]["equipment_serial_number"]) {
+				alert('이미 등록된 시리얼 넘버입니다.');
+				return;
+			}
+		}
 
 		fetch("/equipment/equipmentInsert.json", {
 			method: "POST",
@@ -249,6 +258,84 @@
 			alert('등록에 실패했습니다.');
 		});
 	}
+
+	// 장비 상세 조회 모달창 열기
+	const equipmentOneModalOpen = (item) => {
+		setEquipment(item);
+		setEquipmentOneModal(true);
+	};
+	// 장비 상세 조회 모달창 닫기
+	const equipmentOneModalClose = () => {
+		// 장비 초기화
+		setEquipment(equipment_);
+		setEquipmentOneModal(false);
+	};
+
+	// 장비 수정
+	const equipmentUpdate = () => {
+		console.log('equipmentUpdate Function Run');
+
+		// 유효성 검사
+		for(let i = 0; i < equipmentInsertHead.length; i++) {
+			if(equipment[equipmentInsertKey[i]] == null) {
+				alert(equipmentInsertHead[i] +'를 선택해 주세요');
+				return;
+			}
+		}
+
+		fetch("/equipment/equipmentUpdate.json", {
+			method: "POST",
+			headers: {
+				'Content-Type': 'application/json; charset=UTF-8'
+			},
+			body: JSON.stringify(equipment),
+		}).then((response) => response.json()).then((data) => {
+			console.log('equipmentUpdate response : ', data);
+			// 장비 목록 조회
+			equipmentSelectList();
+			// 장비 초기화
+			setEquipment(equipment_);
+			// 모달창 닫기
+			setEquipmentOneModal(false);
+
+			alert('수정이 완료됐습니다.');
+		}).catch((error) => {
+			console.log('equipmentUpdate error : ', error);
+			alert('수정에 실패했습니다.');
+		});
+	}
+
+	// 장비 삭제
+	const equipmentDelete = () => {
+		console.log('equipmentDelete Function Run');
+
+		// 삭제 확인 팝업
+		if (confirm('정말 삭제하시겠습니까?') == false) {
+			return;
+		}
+
+		fetch("/equipment/equipmentDelete.json", {
+			method: "POST",
+			headers: {
+				'Content-Type': 'application/json; charset=UTF-8'
+			},
+			body: JSON.stringify(equipment),
+		}).then((response) => response.json()).then((data) => {
+			console.log('equipmentDelete response : ', data);
+			// 장비 목록 조회
+			equipmentSelectList();
+			// 장비 초기화
+			setEquipment(equipment_);
+			// 모달창 닫기
+			setEquipmentOneModal(false);
+
+			alert('삭제가 완료됐습니다.');
+		}).catch((error) => {
+			console.log('equipmentDelete error : ', error);
+			alert('삭제에 실패했습니다.');
+		});
+	}
+
 
 	// 장비 등록 th
 	const equipmentInsertHead = [
@@ -278,7 +365,7 @@
 		"입고 일자",
 		"상태",
 		"보유 기관",
-		"시행기관 관리",
+		"기관 관리",
 	];
 	const key1 = [
 		"equipment_name",
@@ -882,7 +969,7 @@
 							{equipmentList.length > 0
 								? equipmentList.map((item, index) => {
 									return (
-										<tr key={index}>
+										<tr key={index} onClick={() => equipmentOneModalOpen(item)}>
 											<td>{equipmentList.length - index}</td>
 											{key1.map((kes) => {
 												if(kes == "equipment_state") {
@@ -894,7 +981,7 @@
 												}
 												return <td>{item[kes]}</td>
 											})}
-											<td>
+											<td onClick={(e) => e.stopPropagation()}>
 												{
 													item['senior_id'] == null
 														? <Button
@@ -908,6 +995,11 @@
 															onClick={seniorMatchDelete}
 														/>
 												}
+												<Button
+													className={"btn-small gray-btn"}
+													btnName={"삭제"}
+													onClick={() => seniorMatchInsertModalOpen(item)}
+												/>
 											</td>
 										</tr>
 									);
@@ -1176,6 +1268,101 @@
 				</div>
 			</Modal>
 
+			<Modal open={equipmentOneModal} close={equipmentOneModalClose} header="장비 상세 조회">
+				<div className="board-wrap">
+					<div>
+						<table className="flex70 margin-bottom">
+							<tbody className="equipment-insert">
+								<tr>
+									<th>종류</th>
+									<td colSpan={5}>
+										<select value={equipment['equipment_type']} name="equipment_type" onChange={equipmentChange}>
+											<option value="" selected disabled>선택</option>
+											<option value="DIGITAL_MEDIBOX">디지털 약상자</option>
+											<option value="ECG" disabled>심전도계</option>
+											<option value="SPHYGMOMANOMETER" disabled>혈압계</option>
+										</select>
+									</td>
+								</tr>
+								<tr>
+									<th>모델 명</th>
+									<td colSpan={5}>
+										<input type="text" value={equipment['equipment_name']} id="equipmentName" name="equipment_name" placeholder="모델 명을 입력해 주세요" onChange={equipmentChange}></input>
+										{/* {smartMediBoxNameList.map((item) => {
+											return (
+												<span>
+													<input type="radio" id={item} name="equipment_name" value={item}></input>
+													<label for={item}>{item}</label>
+												</span>
+											)
+										})} */}
+									</td>
+								</tr>
+								<tr>
+									<th>시리얼 넘버</th>
+									<td colSpan={5}>
+										<input type="text" value={equipment['equipment_serial_number']} name="equipment_serial_number" placeholder="S/N을 입력해 주세요" disabled onChange={equipmentChange}/>
+									</td>
+								</tr>
+								<tr>
+									<th>생산 일자</th>
+									<td colSpan={5}>
+										<input type="date" value={equipment['equipment_product_date']} name="equipment_product_date" onChange={equipmentChange}/>
+									</td>
+								</tr>
+								<tr>
+									<th>입고 일자</th>
+									<td colSpan={5}>
+										<input type="date" value={equipment['equipment_stock_date']} name="equipment_stock_date" onChange={equipmentChange}/>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+
+						<table className={"caregiver-user"}>
+							<thead>
+								<tr>
+									{thead66.map((i) => {
+										return <th>{i}</th>;
+									})}
+								</tr>
+							</thead>
+							<tbody>
+								{seniorMatchListByEquipment.length > 0
+									? seniorMatchListByEquipment.map((item, index) => {
+										return (
+											<tr>
+												{key66.map((kes) => {
+													return <td>{item[kes]}</td>
+												})}
+											</tr>
+										);
+									})
+									: <td colSpan={4}>조회된 데이터가 없습니다.</td>
+								}
+							</tbody>
+						</table>
+					</div>
+					<div justify-content="center">
+						<Button
+							className={"btn-small gray-btn"}
+							btnName={"수정"}
+							onClick={equipmentUpdate}
+						/>
+						<Button
+							className={"btn-small gray-btn"}
+							btnName={"삭제"}
+							onClick={equipmentDelete}
+						/>
+						<Button
+							className={"btn-small gray-btn"}
+							btnName={"닫기"}
+							onClick={equipmentOneModalClose}
+						/>
+					</div>
+				</div>
+			</Modal>
+
 			<Modal open={modalOpen} close={closeModal} header="납품 기관 선택">
 				<div className="board-wrap">
 					<div>
@@ -1291,7 +1478,7 @@
 				</div>
 			</Modal>
 
-			<Modal open={agencyEquipmentOneModal} close={agencyEquipmentOneModalClose} header="장비 상세 조회">
+			<Modal open={agencyEquipmentOneModal} close={agencyEquipmentOneModalClose} header="대상자 장비 상세 조회">
 				<div className="board-wrap">
 					<div>
 						<table className={"caregiver-user"}>
server/modules/web/Server.js
--- server/modules/web/Server.js
+++ server/modules/web/Server.js
@@ -96,17 +96,19 @@
 webServer.get('*', function (request, response, next) {
     response.sendFile(`${BASE_DIR}/client/views/index.html`);
 })
+
 /**
 + * @author : 방선주
 + * @since : 2023.02.14
 + * @dscription : REST API 서버에 데이터 요청 보내기(Proxy)
 + */
-+webServer.use('*.json', expressProxy(API_SERVER_HOST, {
-        proxyReqPathResolver: function (request) {
-            //console.log('request : ', request.url, request.params[0]);
-            return `${request.params['0']}.json`;
-        }
-    }));
+webServer.use('*.json', expressProxy(API_SERVER_HOST, {
+    proxyReqPathResolver: function (request) {
+        //console.log('request : ', request.url, request.params[0]);
+        return `${request.params['0']}.json`;
+    }
+}));
+    
 /**
  * @author : 최정우
  * @since : 2022.09.21
Add a comment
List