Skip to content

Commit

Permalink
Merge pull request #53 from PortalCube/dev
Browse files Browse the repository at this point in the history
[Refactor/FE] 회원가입 페이지를 리팩토링한다.
  • Loading branch information
PortalCube authored Nov 16, 2023
2 parents 2474cae + b2d5d62 commit fffdd72
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 158 deletions.
183 changes: 101 additions & 82 deletions src/components/Accounts/SignupComponents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,139 +30,150 @@ 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 (
<BlockContainer>
<TitleText text="회원가입" />
<Grid>
<RoleButton
role="doctor"
isSelected={selectedRole === "doctor"}
onSelectRole={() => handleSelectRole("doctor")}
isSelected={role === "ROLE_DOCTOR"}
onSelectRole={() => setData("role")("ROLE_DOCTOR")}
/>
<RoleButton
role="therapist"
isSelected={selectedRole === "therapist"}
onSelectRole={() => handleSelectRole("therapist")}
isSelected={role === "ROLE_THERAPIST"}
onSelectRole={() => setData("role")("ROLE_THERAPIST")}
/>
<DropdownFilter
label="소속 병원명 *"
items={hospitalItems}
onSelect={handleSelectHospital}
items={hospitals}
onSelect={setData("hospital", "value")}
/>
<InputImage
onImageSelect={handleImageSelect}
onUpload={setData("image")}
style={{ gridRowEnd: "span 2" }}
/>
<InputTextContainer
label="전공 분야 *"
name="department"
value={formData.department}
onChange={handleInputChange("department")}
value={department}
onChange={setData("department", "target.value")}
/>
<InputTextContainer
label="성함 *"
name="name"
value={formData.name}
onChange={handleInputChange("name")}
value={name}
onChange={setData("name", "target.value")}
/>
<InputTextContainer
label="연락처 *"
name="phone"
value={formData.phone}
onChange={handleInputChange("phone")}
value={phone}
onChange={setData("phone", "target.value")}
/>
<InputTextContainer
label="이메일 *"
name="email"
value={formData.email}
onChange={handleInputChange("email")}
value={email}
onChange={setData("email", "target.value")}
style={{ gridColumnEnd: "span 2" }}
/>
<InputTextContainer
label="아이디 *"
name="mid"
value={formData.mid}
onChange={handleInputChange("mid")}
value={id}
onChange={setData("id", "target.value")}
/>
<InputTextContainer
label="비밀번호 *"
name="password"
value={formData.password}
onChange={handleInputChange("password")}
value={password}
onChange={setData("password", "target.value")}
/>
<RegisterButton onClick={handleSubmit}>회원가입</RegisterButton>
<RegisterButton onClick={clickRegisterButton}>회원가입</RegisterButton>
</Grid>
</BlockContainer>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/Common/DnDList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Input/InputArea.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function InputArea({ value, onInput, disabled, className }) {
return (
<Item
type="text"
value={value}
defaultValue={value}
onChange={onInput}
disabled={disabled}
className={displayClassName}
Expand Down
47 changes: 31 additions & 16 deletions src/components/Input/InputImage.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useMemo, useState } from "react";
import { useMemo, useRef, useState } from "react";
import styled from "styled-components";
import PropTypes from "prop-types";
import { createImage } from "../../librarys/api/image.js";

const UploadBox = styled.div`
width: 154px;
Expand Down Expand Up @@ -29,25 +31,34 @@ const ImagePreview = styled.img`
object-fit: contain;
`;

const InputImage = ({ onImageSelect, ...props }) => {
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(() => {
Expand All @@ -59,11 +70,15 @@ const InputImage = ({ onImageSelect, ...props }) => {
}, [preview]);

return (
<UploadBox {...props} onClick={triggerFileInput}>
<UploadBox {...props} onClick={handleClick}>
{content}
<HiddenInput type="file" onChange={handleImageChange} id="imageInput" />
<HiddenInput ref={ref} type="file" onChange={handleInputChange} />
</UploadBox>
);
};

InputImage.propTypes = {
onUpload: PropTypes.func,
};

export default InputImage;
9 changes: 7 additions & 2 deletions src/components/Input/InputText.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ const Item = styled.input`

function InputText({ value, onChange, className }) {
return (
<Item type="text" value={value} onChange={onChange} className={className} />
<Item
type="text"
defaultValue={value}
onChange={onChange}
className={className}
/>
);
}

Expand All @@ -27,4 +32,4 @@ InputText.propTypes = {
className: PropTypes.string,
};

export default InputText;
export default InputText;
Loading

0 comments on commit fffdd72

Please sign in to comment.