diff --git a/src/App.jsx b/src/App.jsx index ebbd1ad..73c9444 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -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"; @@ -14,6 +15,7 @@ function App() { } /> + } /> diff --git a/src/App.scss b/src/App.scss index a75022f..4c6615d 100644 --- a/src/App.scss +++ b/src/App.scss @@ -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'; } diff --git a/src/assets/icons/dropdownicon.png b/src/assets/icons/dropdownicon.png new file mode 100644 index 0000000..cf8fc48 Binary files /dev/null and b/src/assets/icons/dropdownicon.png differ diff --git a/src/assets/images/user/Odoctor.png b/src/assets/images/user/Odoctor.png new file mode 100644 index 0000000..600c03e Binary files /dev/null and b/src/assets/images/user/Odoctor.png differ diff --git a/src/assets/images/user/Opatient.png b/src/assets/images/user/Opatient.png new file mode 100644 index 0000000..3e77933 Binary files /dev/null and b/src/assets/images/user/Opatient.png differ diff --git a/src/assets/images/user/Otherapist.png b/src/assets/images/user/Otherapist.png new file mode 100644 index 0000000..d6c0322 Binary files /dev/null and b/src/assets/images/user/Otherapist.png differ diff --git a/src/components/Accounts/SignupComponents.jsx b/src/components/Accounts/SignupComponents.jsx new file mode 100644 index 0000000..2c00a6f --- /dev/null +++ b/src/components/Accounts/SignupComponents.jsx @@ -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 ( + + 회원가입 + + + + + + + + + + + + + + + + + + + + + 인증 + + + + + + + + ); +}; + +export default SignupComponents; diff --git a/src/components/Button/RoleButton.jsx b/src/components/Button/RoleButton.jsx new file mode 100644 index 0000000..3d775a5 --- /dev/null +++ b/src/components/Button/RoleButton.jsx @@ -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 ( + + ); +} + +export default RoleButton; + diff --git a/src/components/Dropdown/Dropdown.jsx b/src/components/Dropdown/Dropdown.jsx new file mode 100644 index 0000000..694d9d8 --- /dev/null +++ b/src/components/Dropdown/Dropdown.jsx @@ -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 ( +
+ + + setText(e.target.value)} /> + + {isOpen && ( + + {items.map((item, index) => ( + handleItemClick(item)}> + {item} + + ))} + + )} + +
+ ); +} + +export default Dropdown; diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index a106529..4c4db39 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -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; @@ -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: ["서비스 소개", "회원가입", "로그인"], @@ -65,7 +64,6 @@ export default function Header(props) { {item} ))} - {userType && } ); diff --git a/src/components/Input/InputImage.jsx b/src/components/Input/InputImage.jsx new file mode 100644 index 0000000..0f013ee --- /dev/null +++ b/src/components/Input/InputImage.jsx @@ -0,0 +1,89 @@ +import { useState } from 'react'; +import styled from 'styled-components'; + +const Wrapper = styled.div` + width: 320px; + height: 198px; + display: flex; + flex-direction: row; + align-items: flex-start; + margin-top:50px; + gap: 50px; +`; + + +const Label = styled.label` + width: 90px; + height: 30px; + display: flex; +`; + +const UploadBox = styled.div` + width: 180px; + height: 180px; + background-color: #F3F3F3; + border: 1px solid #BBBBBB; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + position: relative; + border-radius: 10px; +`; + +const UploadText = styled.p` + text-align: center; + line-height: 1.5; +`; + +const HiddenInput = styled.input` + display: none; +`; + +const ImagePreview = styled.img` + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +`; + +const InputImage = () => { + const [preview, setPreview] = useState(null); + + const handleImageChange = (e) => { + const file = e.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onloadend = () => { + setPreview(reader.result); + }; + reader.readAsDataURL(file); + } + }; + + const triggerFileInput = () => { + document.getElementById("imageInput").click(); + }; + + return ( + + + + {preview && } + {!preview && ( + + 이미지
등록하기 +
+ )} + +
+
+ ); +}; + +export default InputImage; diff --git a/src/components/Input/InputText.jsx b/src/components/Input/InputText.jsx new file mode 100644 index 0000000..0ee2a4e --- /dev/null +++ b/src/components/Input/InputText.jsx @@ -0,0 +1,40 @@ +import styled from 'styled-components'; + +const InputContainer = styled.div` + display: flex; + flex-direction: column; + width: 320px; +`; + +const Label = styled.label` + font-family: 'Spoqa Han Sans Neo', 'sans-serif'; + font-size: 16px; + font-weight: 500; + margin-bottom: 5px; +`; + +const Input = styled.input` + width: 320px; + height: 50px; + border-radius: 10px; + background-color: #FAFAFA; + border: 1px solid #BBBBBB; + font-family: 'Spoqa Han Sans Neo', 'sans-serif'; + padding-left: 10px; + + &:focus { + outline: none; + } +`; + +function InputText({ label }) { + return ( + + + + + ); +} + +export { Input }; +export default InputText; diff --git a/src/pages/LoginPage.jsx b/src/pages/LoginPage.jsx index 82e3d89..3e04b40 100644 --- a/src/pages/LoginPage.jsx +++ b/src/pages/LoginPage.jsx @@ -14,6 +14,7 @@ const CenteredContainer = styled.div` justify-content: center; align-items: center; flex: 1; + margin-top: -50px; `; const LoginPage = () => { @@ -26,7 +27,7 @@ const LoginPage = () => { return ( -
{/* userType을 prop으로 전달 */} +
diff --git a/src/pages/SignupPage.jsx b/src/pages/SignupPage.jsx new file mode 100644 index 0000000..b5999fa --- /dev/null +++ b/src/pages/SignupPage.jsx @@ -0,0 +1,32 @@ +import styled from 'styled-components'; +import Header from '../components/Header/Header'; +import SignupComponents from "../components/Accounts/SignupComponents"; + + +const PageContainer = styled.div` + display: flex; + flex-direction: column; + height: 100vh; +`; + +const CenteredContainer = styled.div` + display: flex; + justify-content: center; + align-items: center; + flex: 1; + margin-top: -50px; +`; + +const SignupPage = () => { + + return ( + +
+ + + + + ); +} + +export default SignupPage; \ No newline at end of file