Skip to content

Commit

Permalink
Merge pull request #13 from osohyun0224/master
Browse files Browse the repository at this point in the history
[Feat/FE] Admin들을 위한 회원가입 기능을 구현합니다.
  • Loading branch information
PortalCube authored Sep 25, 2023
2 parents 4aff890 + f39fbda commit 5ad8bc5
Show file tree
Hide file tree
Showing 14 changed files with 492 additions and 7 deletions.
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

0 comments on commit 5ad8bc5

Please sign in to comment.