Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor/FE] 로그인 Redux API를 변경하고 대시보드 페이지를 단일화한다. #43

Merged
merged 11 commits into from
Nov 14, 2023
Merged
12 changes: 4 additions & 8 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Header from "./components/Common/Header.jsx";
import LoginPage from "./pages/LoginPage.jsx";
import SignupPage from "./pages/SignupPage.jsx";
import MyUserPage from "./pages/User/MyUserPage.jsx";
import DevelopPage from "./pages/DevelopPage.jsx";
import ReservationCreatePage from "./pages/Reservation/ReservationCreatePage.jsx";
import DoctorDashBoardPage from "./pages/Doctor/DoctorDashBoardPage.jsx";
import DoctorChartPage from "./pages/Doctor/DoctorChartPage.jsx";
import DoctorDetailPage from "./pages/Doctor/DoctorDetailPage.jsx";
import DoctorPatientListPage from "./pages/Doctor/DoctorPatientListPage.jsx";
import TheraDashBoardPage from "./pages/Therapist/TheraDashBoardPage.jsx";
import TheraPatientListPage from "./pages/Therapist/TheraPatientListPage.jsx";
import TheraDetailPage from "./pages/Therapist/TheraDetailPage.jsx";
import TheraExerciseListPage from "./pages/Therapist/TheraExerciseListPage.jsx";
Expand All @@ -20,6 +17,7 @@ import "./App.scss";
import { ReducerContext } from "./reducer/context.js";
import ReservationListPage from "./pages/Reservation/ReservationListPage.jsx";
import ReservationMeetingPage from "./pages/Reservation/ReservationMeetingPage.jsx";
import DashboardPage from "./pages/DashboardPage.jsx";

const Container = styled.div`
margin-top: 60px;
Expand All @@ -34,19 +32,17 @@ function App() {
<Header />
<Container>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/signup" element={<SignupPage />} />
<Route path="/" element={<DevelopPage />} />
<Route path="/userdash" element={<MyUserPage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<SignupPage />} />
<Route path="/dashboard" element={<DashboardPage />} />
<Route path="/userreserve" element={<ReservationCreatePage />} />
<Route path="/doctordash" element={<DoctorDashBoardPage />} />
<Route path="/doctorchart" element={<DoctorChartPage />} />
<Route path="/doctordetail" element={<DoctorDetailPage />} />
<Route
path="/doctorpatientlist"
element={<DoctorPatientListPage />}
/>
<Route path="/theradashboard" element={<TheraDashBoardPage />} />
<Route
path="/therapatientlist"
element={<TheraPatientListPage />}
Expand Down
21 changes: 13 additions & 8 deletions src/components/Accounts/LoginComponents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import TitleText from "../Common/TitleText";
import BlockContainer from "../Common/BlockContainer";
import InputTextContainer from "../Input/InputTextContainer";
import Button from "../Button/Button";
import { useDispatch } from "react-redux";
import { loginUser, selectName } from "../../redux/userSlice.js";
import { useSelector } from "react-redux";

const InputContainer = styled.div`
margin: 48px 0;
Expand Down Expand Up @@ -34,20 +37,22 @@ const Link = styled.span`
`;

const LoginComponents = ({}) => {
let navigate = useNavigate();
const navigate = useNavigate();
const dispatch = useDispatch();

const [id, setId] = useState("");
const [password, setPassword] = useState("");

const handleLogin = async () => {
const response = await userLogin(id, password);
if (response) {
console.log("로그인 성공:", response);
alert("로그인 완료");
// navigate("/dashboard"); // 이거 아직 페이지 완성 안됨 임시 로그인 되나만 확인용입니다.
} else {
alert("아이디나 비밀번호가 일치하지 않습니다.");
const response = await dispatch(loginUser({ id, password }));

if (response.error) {
alert("아이디나 비밀번호를 다시 한번 확인해주세요.");
return;
}

alert(`${response.payload.name}님, 환영합니다.`);
navigate("/dashboard");
};

return (
Expand Down
21 changes: 16 additions & 5 deletions src/components/Common/Modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const Background = styled.div`

&.hidden {
opacity: 0;

& > div {
transform: translateY(0) scale(0.95);
}
}
`;

Expand All @@ -39,13 +43,16 @@ const Content = styled.div`
box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.2);
overflow: hidden;
z-index: 999;

transition: transform 0.25s;
`;

const Modal = ({ id, className, style, children, onToggle }) => {
const dispatch = useDispatch();
const isVisible = useSelector(selectVisible(id));
const [interactable, setInteractable] = useState(false);
const ref = useRef(null);
const backgroundRef = useRef(null);
const contentRef = useRef(null);

const backgroundClass = {
hidden: !isVisible,
Expand All @@ -54,11 +61,11 @@ const Modal = ({ id, className, style, children, onToggle }) => {

const onClick = useCallback(
(e) => {
if (ref.current && !ref.current.contains(e.target)) {
if (contentRef.current && !contentRef.current.contains(e.target)) {
dispatch(hide(id));
}
},
[ref, dispatch, id],
[contentRef, dispatch, id],
);

useEffect(() => {
Expand All @@ -70,14 +77,18 @@ const Modal = ({ id, className, style, children, onToggle }) => {

useEffect(() => {
onToggle(isVisible);
}, [isVisible]);
if (backgroundRef && isVisible) {
backgroundRef.current.scrollTo(0, 0);
}
}, [backgroundRef, isVisible]);

return (
<Background
ref={backgroundRef}
className={classNames(backgroundClass)}
onTransitionEnd={() => setInteractable(isVisible)}
>
<Content ref={ref} style={style} className={className}>
<Content ref={contentRef} style={style} className={className}>
{children}
</Content>
</Background>
Expand Down
12 changes: 8 additions & 4 deletions src/components/Dashboard/EmployeeHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { userLogin } from "../../librarys/dummy-api";
import IconDoctor from "../../assets/icons/icondoctor.png";
import IconHospital from "../../assets/icons/iconhospital.png";
import { useSelector } from "react-redux";
import { selectName } from "../../redux/userSlice.js";
import {
selectDepartment,
selectLocation,
selectName,
} from "../../redux/userSlice.js";

const Container = styled.div`
width: 800px;
Expand Down Expand Up @@ -70,9 +74,9 @@ const AppointmentInfo = styled.div`
`;

const EmployeeHeader = () => {
const name = useSelector(selectName) || "오민혁";
const dept = useSelector(selectName) || "팔 재활 분야";
const location = useSelector(selectName) || "한림대학교 춘천성심병원";
const name = useSelector(selectName);
const dept = useSelector(selectDepartment);
const location = useSelector(selectLocation);

return (
<Container>
Expand Down
86 changes: 86 additions & 0 deletions src/components/Dashboard/QuickLink.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import styled from "styled-components";
import {
MdAssignment,
MdPersonAddAlt1,
MdVideoChat,
MdDirectionsRun,
} from "react-icons/md";
import { useSelector } from "react-redux";
import { useMemo } from "react";
import { selectRole } from "../../redux/userSlice.js";
import { ROLE_TYPE } from "../../librarys/type.js";
import CardButton from "../Button/CardButton.jsx";

const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
gap: 40px;
`;

const doctorButtons = [
{
icon: <MdAssignment />,
title: "환자 목록",
description: "담당 환자들의 차트를 둘러봅니다.",
link: "/doctorpatientlist",
},
{
icon: <MdVideoChat />,
title: "실시간 비대면 진료",
description: "담당 환자와 실시간 비대면\n진료를 진행합니다.",
link: "/untact/list",
},
{
icon: <MdPersonAddAlt1 />,
title: "환자 등록",
description: "새로운 환자를 등록하고\n차트를 작성합니다.",
link: "/doctorchart",
},
];

const therapistButtons = [
{
icon: <MdDirectionsRun />,
title: "운동 목록",
description: "등록된 운동 목록을 둘러보거나,\n새로운 운동을 등록합니다.",
link: "/theraexerciselist",
},
{
icon: <MdVideoChat />,
title: "실시간 비대면 진료",
description: "담당 환자와 실시간 비대면\n진료를 진행합니다.",
link: "/untact/list",
},
{
icon: <MdAssignment />,
title: "환자 목록",
description:
"담당 환자들의 차트를 둘러보거나\n환자에게 재활 프로그램을 할당합니다.",
link: "/therapatientlist",
},
];

const QuickLink = () => {
const role = useSelector(selectRole);

const list = useMemo(() => {
if (role === ROLE_TYPE.ADMIN_DOCTOR) {
return doctorButtons;
} else if (role === ROLE_TYPE.ADMIN_THERAPIST) {
return therapistButtons;
} else {
return [];
}
}, [role]);

return (
<Container>
{list.map((item, index) => (
<CardButton key={index} {...item} />
))}
</Container>
);
};

export default QuickLink;
2 changes: 1 addition & 1 deletion src/components/Dashboard/UserHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const ItemText = styled.p`
`;

const UserHeader = () => {
const name = useSelector(selectName) || "사용자";
const name = useSelector(selectName);

return (
<Container>
Expand Down
15 changes: 10 additions & 5 deletions src/components/Input/InputImage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ import { useMemo, useState } from "react";
import styled from "styled-components";

const UploadBox = styled.div`
width: 100%;
height: 100%;
width: 154px;
height: 154px;
justify-self: center;
color: #878787;
background-color: #dfdfdf;
border: 1px solid #ababab;
border-radius: 10px;
font-size: 24px;
font-weight: 500;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
white-space: pre-wrap;
cursor: pointer;
`;

Expand All @@ -20,8 +24,9 @@ const HiddenInput = styled.input`
`;

const ImagePreview = styled.img`
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
object-fit: contain;
`;

const InputImage = ({ ...props }) => {
Expand All @@ -46,7 +51,7 @@ const InputImage = ({ ...props }) => {
if (preview) {
return <ImagePreview src={preview} alt="Image preview" />;
} else {
return "이미지 등록하기";
return "이미지\n등록하기";
}
}, [preview]);

Expand Down
4 changes: 2 additions & 2 deletions src/components/Reservation/ReservationList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import BlockContainer from "../Common/BlockContainer.jsx";
import TitleText from "../Common/TitleText.jsx";
import ReservationInfoModal from "./ReservationInfoModal.jsx";
import { useSelector } from "react-redux";
import { selectEmail, selectRole } from "../../redux/userSlice.js";
import { selectId, selectRole } from "../../redux/userSlice.js";
import {
getReservationListAdmin,
getReservationListUser,
Expand All @@ -30,7 +30,7 @@ const ReservationList = () => {
intialReservationListState,
);
const { list, page } = state;
const id = useSelector(selectEmail);
const id = useSelector(selectId);
const role = useSelector(selectRole);

useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Reservation/ReservationMiniList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import BlockContainer from "../Common/BlockContainer.jsx";
import TitleText from "../Common/TitleText.jsx";
import ReservationInfoModal from "./ReservationInfoModal.jsx";
import { useSelector } from "react-redux";
import { selectEmail, selectRole } from "../../redux/userSlice.js";
import { selectId, selectRole } from "../../redux/userSlice.js";
import {
getReservationListAdmin,
getReservationListUser,
Expand All @@ -32,7 +32,7 @@ const ReservationMiniList = () => {
intialReservationListState,
);
const { list, page } = state;
const id = useSelector(selectEmail);
const id = useSelector(selectId);
const role = useSelector(selectRole);

useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/TherapistDashBoard/TheraExerciseList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ const TheraExerciseList = () => {
<ReducerContext.Provider value={[state, dispatch]}>
<BlockContainer>
<TheraExerciseModal />
<TitleText text="운동 등록" />
<TitleText text="운동 목록" />
<SearchAndFilterContainer>
<SearchBar placeholder="환자 이름으로 검색..." />
<SearchBar placeholder="운동 이름으로 검색..." />
<DropdownFilter
items={filters}
defaultText="전체"
Expand Down
Loading