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 (
+
+ );
+};
+
+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 (
+
+ );
+};
+
+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 (
+
+
+
+
+
+
+
+
+ {/* HACK: 모달 제작 후 오류 메세지 표시 예정 */}
+
+ );
+};
+
+export default Login;
+
+const WhiteBackground = styled.div`
+ position: relative;
+
+ width: 100%;
+ height: 100%;
+ min-width: 100vw;
+ min-height: 100vh;
+
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+
+ background-color: #fff;
+`;
+
+const Container = styled.div`
+ max-width: 524px;
+ height: calc(100% - 100px);
+
+ margin: auto;
+`;
+
+const Content = styled.div`
+ width: 100%;
+ height: 100%;
+
+ margin: 50px auto;
+
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 65px;
+`;
diff --git a/src/pages/SignUp/index.tsx b/src/pages/SignUp/index.tsx
new file mode 100644
index 00000000..e668abfe
--- /dev/null
+++ b/src/pages/SignUp/index.tsx
@@ -0,0 +1,81 @@
+import styled from '@emotion/styled';
+
+import logo from '@assets/icons/ic-logo.svg';
+import { Footer } from '@components/common';
+import { SignUpForm, SignUpTitle } from '@components/SignUp';
+
+const SignUp = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default SignUp;
+
+const WhiteBackground = styled.div`
+ position: relative;
+
+ width: 100%;
+ height: 100%;
+ min-height: 100vh;
+
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 50px;
+
+ background-color: #fff;
+`;
+
+const WithoutFooterSection = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ gap: 67px;
+`;
+
+const Logo = styled.div`
+ height: 36px;
+
+ margin-top: 48px;
+ margin-left: 57px;
+`;
+
+const LogoIcon = styled.img`
+ width: 172.8px;
+ height: 100%;
+`;
+
+const Container = styled.div`
+ --logo-height: 36px;
+ --footer-height: 100px;
+
+ max-width: 524px;
+ height: calc(100% - var(--logo-height) - var(--footer-height));
+
+ margin: auto;
+`;
+
+const Content = styled.div`
+ width: 100%;
+ height: 100%;
+
+ display: flex;
+ flex-direction: column;
+`;
diff --git a/src/routes/MainRouter/index.tsx b/src/routes/MainRouter/index.tsx
index 2b62edd0..a5329761 100644
--- a/src/routes/MainRouter/index.tsx
+++ b/src/routes/MainRouter/index.tsx
@@ -1,5 +1,8 @@
import { Route, Routes } from 'react-router-dom';
+
import { Layout } from '@components/common';
+import Login from '@pages/Login';
+import SignUp from '@pages/SignUp';
import Dashboard from '@pages/Dashboard.tsx';
import Report from '@pages/Report.tsx';
@@ -8,15 +11,11 @@ const MainRouter = () => {
🧃 로그인 페이지 입주 예정 🧃
- }
+ element={}
/>
🧃 회원가입 페이지 입주 예정 🧃
- }
+ element={}
/>
}>
;
+export type ButtonText = Pick;
diff --git a/src/types/signUp.ts b/src/types/signUp.ts
new file mode 100644
index 00000000..627413d7
--- /dev/null
+++ b/src/types/signUp.ts
@@ -0,0 +1,7 @@
+export type SignUpFormStyleProps = {
+ $isDisabled: boolean;
+ $isInvalid: boolean;
+};
+
+export type SignUpDisabledButton = Pick;
+export type SignUpInputValidation = Pick;