diff --git a/frontend/public/img/connectIcon.webp b/frontend/public/img/connectIcon.webp new file mode 100644 index 0000000..7f9669d Binary files /dev/null and b/frontend/public/img/connectIcon.webp differ diff --git a/frontend/public/img/favoriteIcon.webp b/frontend/public/img/favoriteIcon.webp new file mode 100644 index 0000000..4ab6b5c Binary files /dev/null and b/frontend/public/img/favoriteIcon.webp differ diff --git a/frontend/public/img/home.webp b/frontend/public/img/home.webp new file mode 100644 index 0000000..bcbb504 Binary files /dev/null and b/frontend/public/img/home.webp differ diff --git a/frontend/public/img/logout.webp b/frontend/public/img/logout.webp new file mode 100644 index 0000000..9f0a385 Binary files /dev/null and b/frontend/public/img/logout.webp differ diff --git a/frontend/public/img/profile.webp b/frontend/public/img/profile.webp new file mode 100644 index 0000000..71628bf Binary files /dev/null and b/frontend/public/img/profile.webp differ diff --git a/frontend/public/img/reportIcon.webp b/frontend/public/img/reportIcon.webp new file mode 100644 index 0000000..ffebd7e Binary files /dev/null and b/frontend/public/img/reportIcon.webp differ diff --git a/frontend/public/img/skill.webp b/frontend/public/img/skill.webp new file mode 100644 index 0000000..2f9466f Binary files /dev/null and b/frontend/public/img/skill.webp differ diff --git a/frontend/public/img/wrongIcon.webp b/frontend/public/img/wrongIcon.webp new file mode 100644 index 0000000..887e5c7 Binary files /dev/null and b/frontend/public/img/wrongIcon.webp differ diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6da2622..1efee6d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4,6 +4,7 @@ import Home from './pages/Home'; import { Route, Routes } from 'react-router-dom'; import Register from './pages/Register'; import Login from './pages/Login'; +import Main from './pages/Main'; function App() { return ( @@ -12,6 +13,7 @@ function App() { } /> } /> } /> + } /> ); diff --git a/frontend/src/components/Main/ProfileToggle.tsx b/frontend/src/components/Main/ProfileToggle.tsx new file mode 100644 index 0000000..76b784a --- /dev/null +++ b/frontend/src/components/Main/ProfileToggle.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import styled from 'styled-components'; +import { media } from '../../style/mediaQuery'; + +const Wrapper = styled.div` + ${media.smallMobile` + top: 36px; + padding: 10px; + `} + ${media.largeMobile` + top: 41px; + padding: 10px; + `} + position: absolute; + top: 53px; + right: 4px; + padding: 15px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 15px; + border-radius: 5px; + border: 0.5px solid #d3d3d3; + background: #fff; + p { + display: flex; + } +`; + +const ModalBox = styled.div` + ${media.largeMobile` + gap: 8px; + p { + font-size: 12px; + } + `} + display: flex; + flex-direction: row; + align-items: center; + gap: 10px; +`; + +const ModalIconBox = styled.div<{ color: string }>` + ${media.smallMobile` + width: 18px; + height: 18px; + `} + ${media.largeMobile` + width: 20px; + height: 20px; + `} + display: flex; + align-items: center; + justify-content: center; + width: 25px; + height: 25px; + border-radius: 50%; + background-color: ${(props) => props.color}; +`; + +const ModalImg = styled.img<{ size: string }>` + ${media.smallMobile` + width: 10px; + height: 10px; + `} + ${media.largeMobile` + width: 12px; + height: 12px; + `} + width: ${(props) => props.size}; + height: ${(props) => props.size}; +`; + +function ProfileToggle() { + return ( + + + + + +

로그아웃

+
+ + + + +

회원정보

+
+
+ ); +} + +export default ProfileToggle; diff --git a/frontend/src/components/common/ClickNavigationBox.tsx b/frontend/src/components/common/ClickNavigationBox.tsx new file mode 100644 index 0000000..e7fdadf --- /dev/null +++ b/frontend/src/components/common/ClickNavigationBox.tsx @@ -0,0 +1,134 @@ +import React from 'react'; +import styled from 'styled-components'; +import { media } from '../../style/mediaQuery'; +import { NavigationBarProps } from '../../types/NavigationBarProps'; + +const Wrapper = styled.div` + ${media.smallMobile` + width: 200px; + height: 50px; + border-radius: 8px; + `} + ${media.largeMobile` + width: 300px; + height: 50px; + border-radius: 10px; + margin-bottom: 0px; + `} + display:flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + padding: 15px; + width: 400px; + height: 64px; + border-radius: 20px; + background: #fff; + box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25); +`; + +const Box = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; +`; + +const IconBox = styled.div<{ color: string }>` + ${media.smallMobile` + width: 25px; + height: 25px; + `} + ${media.largeMobile` + width: 30px; + height: 30px; + `} + display:flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: 50%; + background-color: ${(props) => props.color}; +`; + +const Img = styled.img<{ size: string }>` + ${media.smallMobile` + width: 15px; + height: 15px; + `} + ${media.largeMobile` + width: 19px; + height: 19px; + `} + width: ${(props) => props.size}; + height: ${(props) => props.size}; +`; + +const DescBox = styled.div` + display: flex; + flex-direction: column; +`; + +const SubTitle = styled.p` + display: flex; + color: #838383; + font-size: 10px; + font-weight: 400; + margin-left: 2px; +`; + +const Title = styled.p` + ${media.largeMobile` + font-size: 16px; + `} + display: flex; + color: #000; + font-size: 19px; + font-weight: 400; +`; + +const Arrow = styled.p` + ${media.largeMobile` + font-size: 20px; + font-weight: 400; + `} + color: #000; + font-size: 25px; + font-weight: 500; +`; + +function ClickNavigationBox({ + color, + size, + path, + sub, + title, +}: NavigationBarProps) { + return ( + + {/* 아이콘 + 제목 박스 */} + + {/* 아이콘 박스의 색깔을 string으로 받습니다 */} + + + {/* desktop 사이즈의 img size와 path를 string으로 받습니다 */} + connect + + {/* subTitle이 있으면 넣고 없으면 빼주세요 */} + + {sub} + {title} + + + {/* 화살표 */} + {'>'} + + ); +} + +export default ClickNavigationBox; diff --git a/frontend/src/pages/Loading.tsx b/frontend/src/pages/Loading.tsx index 16a4be7..2746256 100644 --- a/frontend/src/pages/Loading.tsx +++ b/frontend/src/pages/Loading.tsx @@ -1,9 +1,9 @@ import styled from 'styled-components'; import MoonLoader from 'react-spinners/MoonLoader'; -const Wapper = styled.div` +const Wrapper = styled.div` width: 100%; - height: 100%; + height: 100vh; display: flex; flex-direction: column; align-items: center; @@ -18,13 +18,13 @@ const LoadImg = styled.img` function Loading() { return ( <> - + - + ); } diff --git a/frontend/src/pages/Main.tsx b/frontend/src/pages/Main.tsx new file mode 100644 index 0000000..4f3e9cf --- /dev/null +++ b/frontend/src/pages/Main.tsx @@ -0,0 +1,288 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; +import { media } from '../style/mediaQuery'; +import { useNavigate } from 'react-router-dom'; +import ProfileToggle from '../components/Main/ProfileToggle'; +import ClickNavigationBox from '../components/common/ClickNavigationBox'; + +const Wrapper = styled.div` + ${media.smallMobile` + p { + font-size: 13px; + } + `} + position: relative; + width: 100%; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: linear-gradient(180deg, #2e66dd 0%, #639fc8 72.5%, #7ac3ce 100%); +`; + +const Header = styled.div` + ${media.smallMobile` + height: 35px; + padding: 8px; + `} + ${media.largeMobile` + height: 40px; + padding: 10px; + `} + position: fixed; + top: 0; + width: 100%; + height: 52px; + display: flex; + justify-content: flex-end; + align-items: center; + padding: 18px; + background-color: #fff; +`; + +const Btn = styled.button` + background: none; +`; + +const HomeBtn = styled.div` + ${media.smallMobile` + width: 50px; + height: 50px; + `} + ${media.largeMobile` + width: 60px; + height: 60px; + `} + position: absolute; + top: 0; + left: 0; + width: 77px; + height: 77px; + display: flex; + justify-content: center; + align-items: center; + background-color: #fff; + border-radius: 50%; +`; + +const HomeImg = styled.img` + ${media.smallMobile` + width: 25px; + height: 25px; + `} + ${media.largeMobile` + width: 30px; + height: 30px; + `} + width: 40px; + height: 40px; +`; + +const SkillImg = styled.img` + ${media.smallMobile` + width: 15px; + height: 15px; + `} + ${media.largeMobile` + width: 20px; + height: 20px; + `} + width: 25px; + height: 25px; +`; + +const LetText = styled.h2` + ${media.smallMobile` + font-size: 40px; + `} + ${media.largeMobile` + font-size: 50px; + `} + font-size: 70px; + color: rgba(19, 18, 62, 0.1); + font-size: 70px; + font-weight: 700; +`; + +const ProblemBox = styled.div` + ${media.smallMobile` + width: 200px; + height: 120px; + border-radius: 8px; + margin-bottom:12px; + padding: 10px; + + `} + ${media.largeMobile` + width: 300px; + height: 150px; + margin-bottom:15px; + border-radius: 10px; + padding: 15px; + `} + display:flex; + flex-direction: column; + width: 400px; + height: 186px; + padding: 20px; + margin-bottom: 29px; + border-radius: 20px; + background: #fff; + box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25); +`; + +const Title = styled.p` + ${media.largeMobile` + font-size: 16px; + font-weight: 800; + `} + display:flex; + color: #609098; + font-size: 20px; + font-weight: 600; +`; + +const ContBox = styled.div` + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + flex: 1; +`; + +const DescBox = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; +`; + +const IconBox = styled.div<{ color: string }>` + ${media.smallMobile` + width: 25px; + height: 25px; + `} + ${media.largeMobile` + width: 30px; + height: 30px; + `} + display:flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: 50%; + background-color: ${(props) => props.color}; +`; + +const Img = styled.img<{ size: string }>` + ${media.smallMobile` + width: 15px; + height: 15px; + `} + ${media.largeMobile` + width: 19px; + height: 19px; + `} + width: ${(props) => props.size}; + height: ${(props) => props.size}; +`; + +const SubTitle = styled.p` + ${media.largeMobile` + font-size: 16px; + `} + color: #000; + font-size: 19px; + font-weight: 400; +`; + +const Arrow = styled.p` + ${media.largeMobile` + font-size: 20px; + font-weight: 400; + `} + color: #000; + font-size: 25px; + font-weight: 500; +`; + +function Main() { + const navigate = useNavigate(); + const [isShowing, setShowing] = useState(false); + return ( + +
+ { + navigate('/'); + }} + > + + + setShowing((pre) => !pre)}> + + + {isShowing && } +
+ Let’s Go + + 문제풀기 + + + + connect + + 실전 기출문제 풀러가기 + + {'>'} + + + + 복습 + + + + connect + + 내가 틀린 문제 + + {'>'} + + + + + connect + + 즐겨찾기한 문제 + + {'>'} + + + +
+ ); +} + +export default Main; diff --git a/frontend/src/types/NavigationBarProps.ts b/frontend/src/types/NavigationBarProps.ts new file mode 100644 index 0000000..4439adb --- /dev/null +++ b/frontend/src/types/NavigationBarProps.ts @@ -0,0 +1,7 @@ +export type NavigationBarProps = { + color: string; + size: string; + path: string; + sub?: string; + title: string; +};