diff --git a/src/components/Accounts/SignupComponents.jsx b/src/components/Accounts/SignupComponents.jsx
index 815eff2..c73b649 100644
--- a/src/components/Accounts/SignupComponents.jsx
+++ b/src/components/Accounts/SignupComponents.jsx
@@ -6,8 +6,16 @@ import InputImage from "../Input/InputImage.jsx";
import InputTextContainer from "../Input/InputTextContainer.jsx";
import Button from "../Button/Button.jsx";
import DropdownFilter from "../Dropdown/DropdownFilter.jsx";
-import { useState } from "react";
-import { userSignup } from "../../librarys/api/signup.js";
+import { useReducer, useState } from "react";
+import {
+ intialUserRegisterState,
+ userRegisterReducer,
+} from "../../reducer/user-register.js";
+import { getByPath } from "../../librarys/util.js";
+import { createAccount } from "../../librarys/api/user.js";
+import { useDispatch } from "react-redux";
+import { getMyInfo, login } from "../../redux/userSlice.js";
+import { useNavigate } from "react-router-dom";
const Grid = styled.div`
margin: 48px 70px;
@@ -22,77 +30,88 @@ const RegisterButton = styled(Button)`
justify-self: center;
`;
-const Signup = () => {
- // 소속 병원 드롭다운 내용
- const hospitalItems = [
- { key: "춘천성심병원", value: "춘천성심병원" },
- { key: "동탄성심병원", value: "동탄성심병원" },
- { key: "강남성심병원", value: "강남성심병원" },
- { key: "한강성심병원", value: "한강성심병원" },
- { key: "강동성심병원", value: "강동성심병원" },
- { key: "한림성심병원", value: "한림성심병원" },
- ];
-
- const handleSelectHospital = (hospital) => {
- console.log("Selected Hospital: ", hospital.key);
- setFormData({ ...formData, hospital: hospital.key });
- };
-
- // 역할 버튼 상태 로직
- const [selectedRole, setSelectedRole] = useState(null);
-
- const handleSelectRole = (role) => {
- setSelectedRole(role);
- const staffRole = role === "doctor" ? "ROLE_DOCTOR" : "ROLE_THERAPIST";
- setFormData({ ...formData, staffRole: staffRole });
- };
+// 소속 병원 드롭다운 내용
+const hospitals = [
+ "춘천성심병원",
+ "동탄성심병원",
+ "강남성심병원",
+ "한강성심병원",
+ "강동성심병원",
+ "한림성심병원",
+].map((item) => ({ key: item, value: item }));
- //이미지 업로드 api 연결
- const handleImageSelect = (file) => {
- const formDataCopy = { ...formData };
- formDataCopy.file = file;
- setFormData(formDataCopy);
- };
+const Signup = () => {
+ const [state, dispatch] = useReducer(
+ userRegisterReducer,
+ intialUserRegisterState,
+ );
+ const reduxDispatch = useDispatch();
+ const navigate = useNavigate();
- const [formData, setFormData] = useState({
- mid: "",
- password: "",
- name: "",
- hospital: "",
- department: "",
- email: "",
- phone: "",
- staffRole: "",
- // fileName: '',
- });
+ const { id, password, name, hospital, department, email, phone, role } =
+ state;
- const handleSubmit = async (e) => {
- e.preventDefault();
+ function setData(key, path) {
+ return (value) => {
+ if (path) {
+ value = getByPath(value, path);
+ }
- // const dataToSubmit = new FormData();
- // Object.keys(formData).forEach(key => {
- // if (key !== 'file') {
- // dataToSubmit.append(key, formData[key]);
- // }
- // });
+ dispatch({
+ type: "field",
+ payload: {
+ key,
+ value,
+ },
+ });
+ };
+ }
- // if (formData.file) {
- // dataToSubmit.append('file', formData.file);
- // }
+ async function clickRegisterButton() {
+ if (id === "" || id.length < 3) {
+ alert("아이디는 4글자 이상으로 입력해주세요.");
+ return;
+ }
+ if (password === "" || password.length < 3) {
+ alert("비밀번호는 4글자 이상으로 입력해주세요.");
+ return;
+ }
+ if (name === "") {
+ alert("이름을 입력하세요.");
+ return;
+ }
+ if (hospital === "") {
+ alert("소속 병원을 입력하세요.");
+ return;
+ }
+ if (department === "") {
+ alert("소속 부서를 입력하세요.");
+ return;
+ }
+ if (email === "") {
+ alert("이메일을 입력하세요.");
+ return;
+ }
+ if (phone === "") {
+ alert("핸드폰 번호를 입력하세요.");
+ return;
+ }
+ console.log(state);
try {
- const response = await userSignup(formData);
- console.log(response);
+ await createAccount(state);
} catch (error) {
console.error(error);
+ alert("회원가입에 실패했습니다.");
+ return;
}
- };
- const handleInputChange = (id) => {
- return (e) => {
- setFormData({ ...formData, [id]: e.target.value });
- };
- };
+ alert(name + "님의 회원가입이 완료되었습니다!");
+ const tokenResponse = await reduxDispatch(login({ id, password }));
+ await reduxDispatch(getMyInfo(tokenResponse.payload));
+
+ navigate("/");
+ }
return (
@@ -100,61 +119,61 @@ const Signup = () => {
handleSelectRole("doctor")}
+ isSelected={role === "ROLE_DOCTOR"}
+ onSelectRole={() => setData("role")("ROLE_DOCTOR")}
/>
handleSelectRole("therapist")}
+ isSelected={role === "ROLE_THERAPIST"}
+ onSelectRole={() => setData("role")("ROLE_THERAPIST")}
/>
- 회원가입
+ 회원가입
);
diff --git a/src/components/Common/DnDList.jsx b/src/components/Common/DnDList.jsx
index 6faf040..53b7424 100644
--- a/src/components/Common/DnDList.jsx
+++ b/src/components/Common/DnDList.jsx
@@ -48,7 +48,7 @@ const DnDList = ({ id, data, dropping, dragging, removable }) => {
DnDList.propTypes = {
id: PropTypes.string.isRequired,
- data: PropTypes.arrayOf(PropTypes.array).isRequired,
+ data: PropTypes.arrayOf(PropTypes.object).isRequired,
dropping: PropTypes.bool,
dragging: PropTypes.bool,
removable: PropTypes.bool,
diff --git a/src/components/Input/InputArea.jsx b/src/components/Input/InputArea.jsx
index 91d6838..ffe8555 100644
--- a/src/components/Input/InputArea.jsx
+++ b/src/components/Input/InputArea.jsx
@@ -30,7 +30,7 @@ function InputArea({ value, onInput, disabled, className }) {
return (
- {
+const InputImage = ({ onUpload, ...props }) => {
const [preview, setPreview] = useState(null);
- const [selectedFile, setSelectedFile] = useState(null);
+ const ref = useRef(null);
- const handleImageChange = (e) => {
+ const handleInputChange = (e) => {
const file = e.target.files[0];
- if (file) {
- const reader = new FileReader();
- reader.onloadend = () => {
- setPreview(reader.result);
- setSelectedFile(file);
- onImageSelect(file);
- };
- reader.readAsDataURL(file);
+
+ if (!file) {
+ return;
}
+
+ const reader = new FileReader();
+ reader.onloadend = () => {
+ handleUpload(reader.result, file);
+ };
+ reader.readAsDataURL(file);
};
- const triggerFileInput = () => {
- document.getElementById("imageInput").click();
+ const handleUpload = async (image, file) => {
+ setPreview(image);
+ const response = await createImage(file);
+ onUpload(response.link);
+ };
+
+ const handleClick = () => {
+ if (ref) {
+ ref.current.click();
+ }
};
const content = useMemo(() => {
@@ -59,11 +70,15 @@ const InputImage = ({ onImageSelect, ...props }) => {
}, [preview]);
return (
-
+
{content}
-
+
);
};
+InputImage.propTypes = {
+ onUpload: PropTypes.func,
+};
+
export default InputImage;
diff --git a/src/components/Input/InputText.jsx b/src/components/Input/InputText.jsx
index d8949bc..e4862a9 100644
--- a/src/components/Input/InputText.jsx
+++ b/src/components/Input/InputText.jsx
@@ -17,7 +17,12 @@ const Item = styled.input`
function InputText({ value, onChange, className }) {
return (
-
+
);
}
@@ -27,4 +32,4 @@ InputText.propTypes = {
className: PropTypes.string,
};
-export default InputText;
\ No newline at end of file
+export default InputText;
diff --git a/src/components/Reservation/ReservationSelect.jsx b/src/components/Reservation/ReservationSelect.jsx
index da69017..669d68d 100644
--- a/src/components/Reservation/ReservationSelect.jsx
+++ b/src/components/Reservation/ReservationSelect.jsx
@@ -1,7 +1,6 @@
import { useState, useEffect } from "react";
import styled from "styled-components";
import { UserSelectCard } from "../UserDashBoard/UserSelectCard";
-import { getDoctorData, userLogin } from "../../librarys/dummy-api";
import BlockContainer from "../Common/BlockContainer.jsx";
import TitleText from "../Common/TitleText.jsx";
import ReservationCreateModal from "./ReservationCreateModal.jsx";
@@ -19,8 +18,6 @@ const Text = styled.p`
font-weight: 400;
`;
-const { doctor, therapist } = getDoctorData();
-
const ReservationSelect = () => {
return (
@@ -28,8 +25,20 @@ const ReservationSelect = () => {
진료를 희망하는 의료진을 선택해주세요.
-
-
+
+
);
diff --git a/src/components/TherapistDashBoard/TheraMakeAssign.jsx b/src/components/TherapistDashBoard/TheraMakeAssign.jsx
index feaf160..a13255e 100644
--- a/src/components/TherapistDashBoard/TheraMakeAssign.jsx
+++ b/src/components/TherapistDashBoard/TheraMakeAssign.jsx
@@ -6,7 +6,7 @@ import { useEffect, useMemo, useReducer, useState } from "react";
import Pagination from "../Pagination/Pagination";
import { ReducerContext } from "../../reducer/context.js";
import BlockContainer from "../Common/BlockContainer.jsx";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useParams } from "react-router-dom";
import {
intialprogramAssignState,
programAssignReducer,
@@ -18,6 +18,9 @@ import { IoClose } from "react-icons/io5";
import Button from "../Button/Button.jsx";
import { getVideoList } from "../../librarys/api/video.js";
import DnDList from "../Common/DnDList.jsx";
+import { modifyProgram } from "../../librarys/api/program.js";
+import { useSelector } from "react-redux";
+import { selectId } from "../../redux/userSlice.js";
const InputArea = styled(InputAreaContainer)`
margin-top: 28px;
@@ -76,6 +79,8 @@ const TheraMakeAssign = () => {
programAssignReducer,
intialprogramAssignState,
);
+ const { id } = useParams();
+ const adminId = useSelector(selectId);
const {
programList,
@@ -101,6 +106,33 @@ const TheraMakeAssign = () => {
});
};
+ const handleSubmit = async () => {
+ if (assignDescription === "" || assignDescription.length < 4) {
+ alert("과제 설명을 4자 이상 적어주세요.");
+ return;
+ }
+
+ if (assignList === null || assignList.length < 1) {
+ alert("환자에게 운동을 할당해주세요!");
+ return;
+ }
+
+ console.log(assignList);
+
+ const response = await modifyProgram({
+ adminId,
+ userId: id,
+ description: assignDescription,
+ list: assignList.map((item) => item.vno),
+ });
+
+ console.log(response);
+
+ alert("과제 할당이 완료되었습니다.");
+
+ navigate("/");
+ };
+
const handleDragEnd = (event) => {
console.log(event);
if (event.destination === null) {
@@ -208,7 +240,9 @@ const TheraMakeAssign = () => {
-
+
diff --git a/src/components/UserDashBoard/UserSelectCard.jsx b/src/components/UserDashBoard/UserSelectCard.jsx
index e3bc95e..86d3327 100644
--- a/src/components/UserDashBoard/UserSelectCard.jsx
+++ b/src/components/UserDashBoard/UserSelectCard.jsx
@@ -1,15 +1,13 @@
import { useState } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
-import Icondoctor from "../../assets/icons/icondoctor.png";
-import Iconmajor from "../../assets/icons/iconmajor.png";
-import Iconhospital from "../../assets/icons/iconhospital.png";
import DoctorImage from "../../assets/images/user/Odoctor.png";
-import TherapistImage from "../../assets/images/user/Otherapist.png";
-import { ReservationCreateModal } from "../Reservation/ReservationCreateModal";
import { useDispatch } from "react-redux";
import { show } from "../../redux/modalSlice.js";
+import { FaUser } from "react-icons/fa";
+import { MdLocalHospital, MdLocationOn } from "react-icons/md";
+
const Card = styled.div`
width: 280px;
border: 1px solid #e1e1e1;
@@ -18,7 +16,6 @@ const Card = styled.div`
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
text-align: center;
margin: 20px;
- font-family: "Spoqa Han Sans Neo", "sans-serif";
background-color: #ffffff;
`;
@@ -52,14 +49,18 @@ const Avatar = styled.img`
const UserName = styled.span`
font-size: 30px;
font-weight: bold;
- font-family: "Spoqa Han Sans Neo", "sans-serif";
`;
const Info = styled.div`
- font-family: "Spoqa Han Sans Neo", "sans-serif";
font-size: 12px;
margin-bottom: 10px;
text-align: left;
+ & > svg {
+ height: 16px;
+ width: 16px;
+ margin-right: 5px;
+ vertical-align: middle;
+ }
`;
const Button = styled.button`
@@ -74,67 +75,62 @@ const Button = styled.button`
font-size: 12px;
`;
-const Icon = styled.img`
- height: 12px;
- width: 12px;
- margin-right: 5px;
- vertical-align: middle;
-`;
-
-const MidSection = styled.div`
- background-color: rgba(0, 100, 255, 0.03);
-`;
-
-export const UserSelectCard = ({ userType, userData }) => {
+export const UserSelectCard = ({
+ id,
+ role,
+ name,
+ image,
+ hospital,
+ department,
+}) => {
const dispatch = useDispatch();
- const [isModalOpen, setIsModalOpen] = useState(false);
- const toggleModal = () => {
- dispatch(show("reservation_create"));
+ const handleClick = () => {
+ dispatch(
+ show({
+ id: "reservation_create",
+ props: id,
+ }),
+ );
};
- if (!userData) return null;
-
- const imageUrl = userType === "admin1" ? DoctorImage : TherapistImage;
- const title =
- userType === "admin1" ? "담당 전문의 프로필" : "담당 재활치료사 프로필";
-
return (
<>
- {title}
+ 담당 {role} 프로필
-
-
-
-
- {userData.name}
-
+
+
+
+ {name}
- {" "}
- {userType === "admin1" ? "전문의" : "재활치료사"}
+ {role}
- {userData.workplace}
+ {hospital}
- {userData.major}
+ {department}
-
+
>
);
};
UserSelectCard.propTypes = {
- userType: PropTypes.string.isRequired,
- userData: PropTypes.shape({
- name: PropTypes.string,
- workplace: PropTypes.string,
- major: PropTypes.string,
- }).isRequired,
+ id: PropTypes.string,
+ role: PropTypes.string,
+ name: PropTypes.string,
+ image: PropTypes.string,
+ hospital: PropTypes.string,
+ department: PropTypes.string,
+};
+
+UserSelectCard.defaultProps = {
+ image: DoctorImage,
};
export default UserSelectCard;
diff --git a/src/librarys/api/image.js b/src/librarys/api/image.js
new file mode 100644
index 0000000..6d0ac48
--- /dev/null
+++ b/src/librarys/api/image.js
@@ -0,0 +1,36 @@
+import { createFormData, getSpringAxios } from "./axios";
+
+// get ~~
+// create ~~
+// modify ~~
+// delete ~~
+
+export async function createImage(files) {
+ const axios = getSpringAxios();
+
+ const body = {
+ files,
+ };
+
+ const response = await axios.post("/upload", createFormData(body));
+
+ const data = {
+ uuid: response.data.uuid,
+ fileName: response.data.fileName,
+ link: response.data.link,
+ };
+
+ return data;
+}
+
+export async function deleteImage(filePath) {
+ const axios = getSpringAxios();
+
+ const response = await axios.delete("/remove/" + filePath);
+
+ const data = {
+ status: true,
+ message: response.data,
+ };
+ return data;
+}
diff --git a/src/librarys/api/user.js b/src/librarys/api/user.js
index 4d01b74..6c0251a 100644
--- a/src/librarys/api/user.js
+++ b/src/librarys/api/user.js
@@ -46,7 +46,7 @@ export async function createAccount(req) {
const axios = getSpringAxios();
const body = {
- mid: req.mid,
+ mid: req.id,
name: req.name,
password: req.password,
hospital: req.hospital,
@@ -54,7 +54,7 @@ export async function createAccount(req) {
email: req.email,
phone: req.phone,
staffRole: req.role,
- fileName: req.image,
+ // fileName: req.image || "",
};
const response = await axios.post("/join", body);
diff --git a/src/librarys/util.js b/src/librarys/util.js
index 47e1c18..a05ea74 100644
--- a/src/librarys/util.js
+++ b/src/librarys/util.js
@@ -21,3 +21,5 @@ export const throttle = (callback, delay) => {
export function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
+
+export const getByPath = (o, p) => p.split(".").reduce((a, v) => a[v], o);
diff --git a/src/reducer/user-register.js b/src/reducer/user-register.js
new file mode 100644
index 0000000..99012dc
--- /dev/null
+++ b/src/reducer/user-register.js
@@ -0,0 +1,24 @@
+export const intialUserRegisterState = {
+ id: "",
+ password: "",
+ name: "",
+ hospital: "",
+ department: "",
+ email: "",
+ phone: "",
+ image: "",
+ role: "",
+};
+
+export function userRegisterReducer(state, action) {
+ switch (action.type) {
+ case "field":
+ return {
+ ...state,
+ [action.payload.key]: action.payload.value,
+ };
+ default:
+ console.error("[UserRegisterReducer] Undefined action: " + action.type);
+ return state;
+ }
+}