diff --git a/src/components/Login/LoginForm/index.tsx b/src/components/Login/LoginForm/index.tsx new file mode 100644 index 00000000..3afc88a2 --- /dev/null +++ b/src/components/Login/LoginForm/index.tsx @@ -0,0 +1,114 @@ +import styled from '@emotion/styled'; + +import { ButtonText, InputValidation } from '@/types/login'; + +const LoginForm = () => { + // HACK: 유효성 검사 기능 구현 후 유효성 메세지 노출 여부 결정 + const isInvalid = true; + + return ( +
+ + + + + {isInvalid && ( + + 아이디를 입력해 주세요 + + )} + + + + +
+ ); +}; + +export default LoginForm; + +const Inputs = styled.div` + margin-bottom: ${props => (props.$isInvalid ? '10px' : '65px')}; + + display: flex; + flex-direction: column; + gap: 19px; +`; + +const Input = styled.input` + width: 524px; + height: 79px; + + border-radius: 16px; + border: 2px solid #757676; + padding: 23px 20px; + + display: flex; + align-items: center; + + color: #1a2849; + font-size: 18px; + font-weight: 500; + line-height: 32px; + + &::placeholder { + color: #979c9e; + font-size: 18px; + font-weight: 500; + line-height: 32px; + } + + &:focus { + outline: 2px solid #1a2849; + border-color: #1a2849; + } +`; + +const ValidationText = styled.p` + padding-left: 12px; + + color: #da1e28; + font-size: 15px; + font-weight: 500; + line-height: 32px; +`; + +const ValidationBoldText = styled.span` + font-weight: 700; +`; + +const Buttons = styled.div` + display: flex; + flex-direction: column; + gap: 13px; + + ${props => props.$isInvalid && 'margin-top: 23px'}; +`; + +const Button = styled.button` + min-width: 524px; + + border: none; + border-radius: 16px; + padding: 23px 0; + + color: #fff; + font-size: 22px; + font-weight: 700; + line-height: 32px; + + background: ${props => + props.$text === 'login' + ? '#1A2849' + : 'linear-gradient(91deg, #FF3478 1.39%, #FF83AD 98.63%)'}; + + &:hover { + cursor: pointer; + } +`; diff --git a/src/components/Login/LoginTitle/index.tsx b/src/components/Login/LoginTitle/index.tsx new file mode 100644 index 00000000..521266c0 --- /dev/null +++ b/src/components/Login/LoginTitle/index.tsx @@ -0,0 +1,39 @@ +import styled from '@emotion/styled'; + +import logo from '@assets/icons/ic-logo.svg'; + +const LoginTitle = () => { + return ( + + + 통합 로그인 + + ); +}; + +export default LoginTitle; + +const LogoIcon = styled.img` + width: 288px; + height: 60px; +`; + +const TitleWrapper = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 11px; + + text-align: center; +`; + +const Title = styled.h1` + color: #1a2849; + font-size: 44.374px; + font-weight: 900; + line-height: 51.769px; +`; diff --git a/src/components/Login/index.tsx b/src/components/Login/index.tsx new file mode 100644 index 00000000..58ab3487 --- /dev/null +++ b/src/components/Login/index.tsx @@ -0,0 +1,2 @@ +export { default as LoginTitle } from './LoginTitle'; +export { default as LoginForm } from './LoginForm'; diff --git a/src/components/SignUp/SignUpForm/index.tsx b/src/components/SignUp/SignUpForm/index.tsx new file mode 100644 index 00000000..b43cb0c1 --- /dev/null +++ b/src/components/SignUp/SignUpForm/index.tsx @@ -0,0 +1,178 @@ +import styled from '@emotion/styled'; + +import { SignUpDisabledButton, SignUpInputValidation } from '@/types/signUp'; + +const SignUpForm = () => { + // TODO: react-hook-form 사용해서 유효성 검사 예정 + const isInvalid = false; + const isEmailValidationVisible = false; + + // 2가지 버튼 disabled 처리하기 위한 state + const isEmailValidationDisabled = true; + const isSubmitValidationDisabled = true; + + return ( +
+ + + + {isInvalid && ( + + 이름을 입력해 주세요. + + )} + + + + + + + 중복확인 + + + {isEmailValidationVisible && ( + + 사용 가능한 아이디입니다. + + )} + + + + + {isInvalid && ( + + 비밀번호 형식이 아닙니다. + + )} + + + + + {isInvalid && ( + + 비밀번호가 일치하지 않습니다. + + )} + + + 회원가입 + +
+ ); +}; + +export default SignUpForm; + +const SubmitButton = styled.button` + min-width: 524px; + height: 78px; + + border: none; + border-radius: 16px; + padding: 23px auto; + + color: #fff; + font-size: 22px; + font-weight: 700; + line-height: 32px; + + background: ${props => (props.$isDisabled ? '#C1C1C1' : '#1A2849')}; + + &:hover { + cursor: pointer; + } +`; + +const Form = styled.form` + margin-top: 26px; + + display: flex; + flex-direction: column; + gap: 23px; +`; + +const InputLabelWrapper = styled.div` + display: flex; + flex-direction: column; +`; + +const Label = styled.label` + margin-bottom: 10px; + + color: #757676; + font-size: 18px; + font-weight: 700; + line-height: 32px; +`; + +const Input = styled.input` + width: 524px; + height: 79px; + + border-radius: 16px; + border: 2px solid #757676; + padding: 23px 20px; + + display: flex; + align-items: center; + + color: #1a2849; + font-size: 18px; + font-weight: 500; + line-height: 32px; + + &::placeholder { + color: #979c9e; + font-size: 18px; + font-weight: 500; + line-height: 32px; + } + + &:focus { + outline: 2px solid #1a2849; + border-color: #1a2849; + } +`; + +const EmailInputWrapper = styled.div` + display: flex; + justify-content: space-between; +`; + +const EmailInput = styled(Input)` + width: 358px; +`; + +const EmailValidationButton = styled(SubmitButton)` + min-width: 152px; +`; + +const ValidationText = styled.p` + margin-top: 2px; + margin-left: 12px; + + color: ${props => (props.$isInvalid ? '#DA1E28' : '#1a2849')}; + font-size: 15px; + font-weight: 700; + line-height: 32px; +`; diff --git a/src/components/SignUp/SignUpTitle/index.tsx b/src/components/SignUp/SignUpTitle/index.tsx new file mode 100644 index 00000000..13fc4f2d --- /dev/null +++ b/src/components/SignUp/SignUpTitle/index.tsx @@ -0,0 +1,36 @@ +import styled from '@emotion/styled'; + +const SignUpTitle = () => { + return ( + + 회원가입 + + 야놀자가 준비한 사장님 비서ya만의 혜택을 받아보세요. + + + ); +}; + +export default SignUpTitle; + +const TitleWrapper = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: flex-start; +`; + +const Title = styled.h1` + color: #202325; + font-size: 26px; + font-weight: 700; + line-height: 31px; + letter-spacing: -0.78px; +`; + +const Description = styled.p` + color: #979c9e; + font-size: 18px; + font-weight: 500; + line-height: 32px; +`; diff --git a/src/components/SignUp/index.tsx b/src/components/SignUp/index.tsx new file mode 100644 index 00000000..ec8af5fc --- /dev/null +++ b/src/components/SignUp/index.tsx @@ -0,0 +1,2 @@ +export { default as SignUpForm } from './SignUpForm'; +export { default as SignUpTitle } from './SignUpTitle'; diff --git a/src/components/common/Footer/index.tsx b/src/components/common/Footer/index.tsx new file mode 100644 index 00000000..54a93874 --- /dev/null +++ b/src/components/common/Footer/index.tsx @@ -0,0 +1,62 @@ +import styled from '@emotion/styled'; + +const Footer = () => { + const thisYear = new Date().getFullYear(); + return ( + + + 이용약관 + | + 개인정보 처리방침 + + + (주) 야놀자 Copyright © 2005-{thisYear} Yanolja Co., Ltd. All rights + reserved. + + + ); +}; + +export default Footer; + +const Container = styled.div` + position: relative; + bottom: 0; + + height: 100px; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 7px; +`; + +const Policy = styled.div` + display: flex; + flex-direction: row; + justify-content: center; + gap: 7px; +`; + +const Text = styled.p` + color: #404446; + font-size: 12px; + font-weight: 400; + line-height: 18px; +`; + +const BoldText = styled.p` + color: #404446; + font-size: 12px; + font-weight: 700; + line-height: 18px; +`; + +const Copyright = styled.p` + color: #e3e5e5; + font-size: 10px; + font-weight: 400; + line-height: 15px; + text-align: center; +`; diff --git a/src/components/common/index.tsx b/src/components/common/index.tsx index 51b9f107..d80616f2 100644 --- a/src/components/common/index.tsx +++ b/src/components/common/index.tsx @@ -1,2 +1,3 @@ export { default as Layout } from './Layout'; export { default as DashboardHeader } from './DashboardHeader'; +export { default as Footer } from './Footer'; diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx new file mode 100644 index 00000000..128a460f --- /dev/null +++ b/src/pages/Login/index.tsx @@ -0,0 +1,55 @@ +import styled from '@emotion/styled'; + +import { Footer } from '@components/common'; +import { LoginForm, LoginTitle } from '@components/Login'; + +const Login = () => { + return ( + + + + + + + +