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

[Feat/FE] 017 Admin들을 위한 회원가입 기능을 구현합니다. #13

Merged
merged 11 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import LoginPage from "./pages/LoginPage.jsx";
import SignupPage from "./pages/SignupPage.jsx";
import styled from "styled-components";
import "./App.scss";

Expand All @@ -14,6 +15,7 @@ function App() {
<Container>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/signup" element={<SignupPage />} />
</Routes>
</Container>
</Router>
Expand Down
6 changes: 3 additions & 3 deletions src/App.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#root {
width: 100%;
height: 100vh;
height: 200vh;
margin: 0 auto;
background-color: #fff;
font-family: "SUIT Variable", sans-serif;
background-color:#F1F6F9;
font-family: 'Spoqa Han Sans Neo', 'sans-serif';
}
Binary file added src/assets/icons/dropdownicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/user/Odoctor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/user/Opatient.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/user/Otherapist.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
165 changes: 165 additions & 0 deletions src/components/Accounts/SignupComponents.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import styled from 'styled-components';
import RoleButton from '../Button/RoleButton';
import Dropdown from '../Dropdown/Dropdown';
import InputText, { Input } from '../Input/InputText';
import InputImage from '../Input/InputImage';

const SignupContainer = styled.div`
width: 1000px;
height: 1000px;
border-radius: 10px;
background-color: #ffffff;
border: 2px solid #0064FF;
position: relative;
box-shadow: 0px 12px 24px rgba(0, 0, 0, 0.1);
`;

const Divider = styled.div`
width: 900px;
height: 1px;
background-color: #D9D9D9;
margin-top: 10px;
margin-left: 30px;
margin-right: auto;
`;

const Title = styled.h1`
font-size: 35px;
font-family: 'Spoqa Han Sans Neo', 'sans-serif';
font-weight: 700;
margin-left: 30px;
margin-top: 24px;
`;

const ButtonContainer = styled.div`
display: flex;
justify-content: space-between;
width: 700px;
margin-top: 80px;
margin-left: 130px;
`;

const DropdownsContainer = styled.div`
margin-top: 30px;
margin-left: 130px;
`;

const InputFieldsContainer = styled.div`
display: flex;
justify-content: space-between;
margin-top: 30px;
margin-left: 130px;
gap: 20px;
width: 700px;
`;

const FlexContainer = styled.div`
display: flex;
align-items: center;
width: 100%;
margin-left: 0px;
gap: 60px;
`;

const StyledInputImage = styled(InputImage)`
`;

const EmailInputContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
gap: 5px;
width: 700px;
margin-left: 130px;
margin-top: 30px;
`;


const EmailInput = styled(Input)`
width: 200%;
`;

const VerifyButton = styled.button`
width: 130px;
height: 50px;
background-color: #f0f0f0;
border: 1px solid #BBBBBB;
border-radius: 10px;
font-family: 'Spoqa Han Sans Neo', 'sans-serif';
font-size: 16px;
font-weight: 700;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;

&:focus {
outline: none;
}
`;

const Button = styled.button`
width: 280px;
height: 60px;
background-color: #3592FF;
border-radius: 10px;
color: white;
font-size: 22px;
border: none;
cursor: pointer;
position: absolute;
font-family: 'Spoqa Han Sans Neo', 'sans-serif';
margin-top: 40px;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
`;

const SignupComponents = () => {

// 소속병원 선택
const hospitals = [
"한림대학교 춘천성심병원", "한림대학교 강남성심병원",
"한림대학교 동탄성심병원", "한림대학교 성심병원(평촌)",
"한림대학교 한강성심병원", "강동성심병원"
];

// 재활 분야 선택
const fields = ["재활의학과", "신경외과", "정형외과"];

return (
<SignupContainer>
<Title>회원가입</Title>
<Divider />
<ButtonContainer>
<RoleButton role="doctor" />
<RoleButton role="therapist" />
</ButtonContainer>
<FlexContainer>
<DropdownsContainer>
<Dropdown label="소속 병원명 *" items={hospitals} />
<Dropdown label="재활 분야 *" items={fields} />
</DropdownsContainer>
<StyledInputImage />
</FlexContainer>
<InputFieldsContainer>
<InputText label="성함 *" />
<InputText label="연락처 *" />
</InputFieldsContainer>
<EmailInputContainer>
<InputText label="이메일 *">
<EmailInput type="text" />
</InputText>
<VerifyButton>인증</VerifyButton>
</EmailInputContainer>
<InputFieldsContainer>
<InputText label="아이디 *" />
<InputText label="비밀번호 *" />
</InputFieldsContainer>
<Button>가입하기</Button>
</SignupContainer>
);
};

export default SignupComponents;
64 changes: 64 additions & 0 deletions src/components/Button/RoleButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useState } from 'react';
import styled from 'styled-components';
import Patient from "../../assets/images/user/Opatient.png";
import Doctor from "../../assets/images/user/Odoctor.png";
import Therapist from "../../assets/images/user/Otherapist.png";

const Button = styled.button`
width: 320px;
height: 72px;
border-radius: 10px;
background-color: #F3F3F3;
border: ${({ isSelected }) => (isSelected ? '3px solid #AD5DFD' : '1px solid #BBBBBB')};
display: flex;
justify-content: center;
align-items: center;
gap: 12px;
cursor: pointer;

font-family: 'Spoqa Han Sans Neo', 'sans-serif';
font-weight: 700;
font-size: 24px;
color: #333;
`;

const Icon = styled.img`
width: 40px;
height: 40px;
`;

const RoleButton = ({ role }) => {
const [isSelected, setIsSelected] = useState(false);
let iconSrc, buttonText;

switch(role) {
case 'patient':
iconSrc = Patient;
buttonText = "환자";
break;
case 'doctor':
iconSrc = Doctor;
buttonText = "전문의";
break;
case 'therapist':
iconSrc = Therapist;
buttonText = "재활치료사";
break;
default:
throw new Error("Invalid role provided");
}

const handleButtonClick = () => {
setIsSelected(!isSelected);
}

return (
<Button isSelected={isSelected} onClick={handleButtonClick}>
<Icon src={iconSrc} alt={buttonText} />
{buttonText}
</Button>
);
}

export default RoleButton;

94 changes: 94 additions & 0 deletions src/components/Dropdown/Dropdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { useState } from 'react';
import styled from 'styled-components';
import dropdownicon from "../../assets/icons/dropdownicon.png";

const Label = styled.div`
font-family: 'Spoqa Han Sans Neo', 'sans-serif';
font-weight: 500;
font-size: 16px;
margin-bottom: 5px;
padding-top:10px;
`;

const DropdownContainer = styled.div`
width: 320px;
height: 50px;
background-color: #FFFFFF;
border: 1px solid #BBBBBB;
position: relative;
cursor: pointer;
margin-bottom: 10px;
border-radius: 10px;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
`;

const DropdownText = styled.input`
width: calc(100% - 60px);
height: 100%;
border: none;
font-family: 'Spoqa Han Sans Neo', 'sans-serif';
font-weight: 500;
font-size: 16px;
padding-left: 10px;
&:focus {
outline: none;
}
`;

const DropdownIcon = styled.img`
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
`;

const DropdownList = styled.div`
width: 100%;
max-height: ${props => (props.open ? '150px' : '0')};
overflow-y: auto;
position: absolute;
top: 100%;
left: 0;
background-color: #FFFFFF;
border: 1px solid #ccc;
z-index: 1;
`;

const DropdownItem = styled.div`
padding: 10px;
`;

function Dropdown({ label, items }) {
const [isOpen, setIsOpen] = useState(false);
const [text, setText] = useState('');

const toggleDropdown = () => {
setIsOpen(!isOpen);
};

const handleItemClick = (item) => {
setText(item);
setIsOpen(false);
};

return (
<div>
<Label>{label}</Label>
<DropdownContainer onClick={toggleDropdown}>
<DropdownText value={text} onChange={e => setText(e.target.value)} />
<DropdownIcon src={dropdownicon} alt="Dropdown Icon" />
{isOpen && (
<DropdownList open={isOpen}>
{items.map((item, index) => (
<DropdownItem key={index} onClick={() => handleItemClick(item)}>
{item}
</DropdownItem>
))}
</DropdownList>
)}
</DropdownContainer>
</div>
);
}

export default Dropdown;
4 changes: 1 addition & 3 deletions src/components/Header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import styled from 'styled-components';
import { useNavigate } from 'react-router-dom';
import UserComponent from './UserComponents';

const HeaderContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -31,7 +30,7 @@ const NavItem = styled.div`
export default function Header(props) {
let navigate = useNavigate();

const { userType, userName } = props;
const { userType = null } = props;

const menus = {
null: ["서비스 소개", "회원가입", "로그인"],
Expand Down Expand Up @@ -65,7 +64,6 @@ export default function Header(props) {
{item}
</NavItem>
))}
{userType && <UserComponent userType={userType} userName={userName} />}
</NavMenu>
</HeaderContainer>
);
Expand Down
Loading