diff --git a/src/assets/img/btn_main_top_left.svg b/src/assets/img/btn_main_top_left.svg new file mode 100644 index 0000000..2f7a3dd --- /dev/null +++ b/src/assets/img/btn_main_top_left.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/src/assets/img/btn_main_top_right.png b/src/assets/img/btn_main_top_right.png deleted file mode 100644 index d21d608..0000000 Binary files a/src/assets/img/btn_main_top_right.png and /dev/null differ diff --git a/src/assets/img/btn_main_top_right.svg b/src/assets/img/btn_main_top_right.svg new file mode 100644 index 0000000..da2e7a9 --- /dev/null +++ b/src/assets/img/btn_main_top_right.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/src/assets/img/input_dropdown.png b/src/assets/img/input_dropdown.png new file mode 100644 index 0000000..9032549 Binary files /dev/null and b/src/assets/img/input_dropdown.png differ diff --git a/src/assets/img/red_edge.png b/src/assets/img/red_edge.png new file mode 100644 index 0000000..bee4c48 Binary files /dev/null and b/src/assets/img/red_edge.png differ diff --git a/src/assets/img/top_menu_down.png b/src/assets/img/top_menu_down.png new file mode 100644 index 0000000..60432f9 Binary files /dev/null and b/src/assets/img/top_menu_down.png differ diff --git a/src/components/Header.tsx/TImer.tsx b/src/components/Header.tsx/TImer.tsx new file mode 100644 index 0000000..03137fb --- /dev/null +++ b/src/components/Header.tsx/TImer.tsx @@ -0,0 +1,53 @@ +import {useEffect, useState} from 'react'; +import {useNavigate} from 'react-router-dom'; +import styled from 'styled-components'; + +interface TimerProps { + name: string; +} + +function Timer({name}: TimerProps) { + const navigate = useNavigate(); + const [time, setTime] = useState(1800); + + const formatTime = (time: number) => { + return time.toString().padStart(2, '0'); + }; + + const resetTime = () => { + setTime(1800); + }; + + useEffect(() => { + const timer = setInterval(() => { + setTime(prev => prev - 1); + }, 1000); + + if (time === 0) { + navigate('/login'); + } + + return () => clearInterval(timer); + }, [time]); + + return ( + + {name} + + 님 [00:{formatTime(Math.floor(time / 60))}:{formatTime(time % 60)}] + + + ); +} + +const TimerWrap = styled.button` + ${props => props.theme.texts.tableTitle}; + font-size: 1.3rem; + + > span { + color: ${props => props.theme.colors.neutral4}; + font-weight: 400; + } +`; + +export default Timer; diff --git a/src/components/Header.tsx/TopMenu.tsx b/src/components/Header.tsx/TopMenu.tsx new file mode 100644 index 0000000..53f34c9 --- /dev/null +++ b/src/components/Header.tsx/TopMenu.tsx @@ -0,0 +1,107 @@ +import styled from 'styled-components'; +import {useNavigate} from 'react-router-dom'; +import Left from '@assets/img/btn_main_top_left.svg?react'; +import Right from '@assets/img/btn_main_top_right.svg?react'; +import logout from '@assets/img/logout.png'; +import down from '@assets/img/top_menu_down.png'; +import notice from '@assets/img/notice.png'; +import setting from '@assets/img/setitng.png'; +import menu from '@assets/img/menu.png'; +import Timer from './TImer'; + +function TopMenu() { + const navigate = useNavigate(); + const name = '세종대'; + + const handleLogout = () => { + navigate('/login'); + }; + + return ( + + + + + + + + + PC + + + + KOR + + + + + + + + + ); +} + +const TopMenuContainer = styled.div` + display: flex; + align-items: center; + column-gap: 1rem; +`; + +const ArrowWrap = styled.div` + display: flex; + align-items: center; + column-gap: 1.2rem; + margin-right: 1.5rem; +`; + +const StyledLeft = styled(Left)` + fill: ${props => props.theme.colors.neutral4}; + &:hover { + fill: ${props => props.theme.colors.primary}; + } +`; + +const StyledRight = styled(Right)` + fill: ${props => props.theme.colors.neutral4}; + &:hover { + fill: ${props => props.theme.colors.primary}; + } +`; + +const LogoutBtn = styled.button` + background-image: url(${logout}); + width: 1.4rem; + height: 1.4rem; + + &:hover { + filter: brightness(20%); + } +`; + +const DropdownWrap = styled.div` + ${props => props.theme.texts.tableTitle}; + font-size: 1.3rem; + display: flex; + align-items: center; + column-gap: 1.5rem; + + > img { + &:hover { + filter: brightness(20%); + } + } +`; + +const GroupWrap = styled.div` + display: flex; + column-gap: 1rem; + + > img { + &:hover { + filter: brightness(20%); + } + } +`; + +export default TopMenu; diff --git a/src/components/Header.tsx/TopNav.tsx b/src/components/Header.tsx/TopNav.tsx new file mode 100644 index 0000000..66293f8 --- /dev/null +++ b/src/components/Header.tsx/TopNav.tsx @@ -0,0 +1,27 @@ +import styled from 'styled-components'; + +function TopNav() { + return ( + + 학부생학사정보 + 학생서비스 + + ); +} + +const TopNavContatiner = styled.div` + display: flex; + flex-shrink: 0; +`; + +const TopNavWrap = styled.button` + ${props => props.theme.texts.title}; + font-size: 1.6rem; + margin-right: 4rem; + + &:focus { + color: ${props => props.theme.colors.primary}; + } +`; + +export default TopNav; diff --git a/src/components/Header.tsx/index.tsx b/src/components/Header.tsx/index.tsx new file mode 100644 index 0000000..1e99463 --- /dev/null +++ b/src/components/Header.tsx/index.tsx @@ -0,0 +1,37 @@ +import styled from 'styled-components'; +import logo from '@assets/img/main_logo.png'; +import TopNav from './TopNav'; +import TopMenu from './TopMenu'; + +function Header() { + return ( + +
+ +
+ + + + +
+ ); +} + +const HeaderContainer = styled.div` + border-top: 0.5rem solid ${props => props.theme.colors.primary}; + max-width: 100%; + height: 6rem; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 2rem; +`; + +const HeaderBox = styled.div` + display: flex; + flex-grow: 1; + justify-content: space-between; + margin-left: 7.5rem; +`; + +export default Header; diff --git a/src/components/LoginForm/FormInput.tsx b/src/components/LoginForm/FormInput.tsx index 16977d3..a05cdc0 100644 --- a/src/components/LoginForm/FormInput.tsx +++ b/src/components/LoginForm/FormInput.tsx @@ -2,7 +2,7 @@ import styled from 'styled-components'; import {setType} from '.'; interface InputProps { - value: string | number; + value: string | number | undefined; setValue: React.Dispatch>; type: string; } diff --git a/src/components/LoginForm/index.tsx b/src/components/LoginForm/index.tsx index 94e64ca..8ce83f1 100644 --- a/src/components/LoginForm/index.tsx +++ b/src/components/LoginForm/index.tsx @@ -2,10 +2,10 @@ import styled from 'styled-components'; import FormInput from './FormInput'; import {useState} from 'react'; -export type setType = string | number; +export type setType = string | number | undefined; function LoginForm() { - const [id, setId] = useState(0); + const [id, setId] = useState(undefined); const [name, setName] = useState(''); return ( @@ -57,7 +57,7 @@ const CheckboxWrap = styled.div` const FindWrap = styled.div` ${props => props.theme.texts.tableTitle}; - color: #777; + color: ${props => props.theme.colors.neutral4}; float: inline-end; margin-bottom: 2.5rem; `; diff --git a/src/components/Menubar/Menu.tsx b/src/components/Menubar/Menu.tsx index f5cdfdb..93002d0 100644 --- a/src/components/Menubar/Menu.tsx +++ b/src/components/Menubar/Menu.tsx @@ -56,7 +56,7 @@ const MenuTitleBox = styled.div` align-items: center; justify-content: space-between; padding: 0 15px; - border-bottom: 1px solid ${props => props.theme.colors.neutral4}; + border-bottom: 1px solid ${props => props.theme.colors.neutral5}; `; const MenuTitleWrap = styled.div` ${props => props.theme.texts.menuTitle}; @@ -69,7 +69,7 @@ const MenuSubtitleBox = styled(MenuTitleBox)` `; const DetailBox = styled.div` - background-color: ${props => props.theme.colors.neutral5}; + background-color: ${props => props.theme.colors.neutral6}; display: flex; flex-direction: column; align-items: center; diff --git a/src/pages/index/Home.tsx b/src/pages/index/Home.tsx index 6dc66f2..ea7d540 100644 --- a/src/pages/index/Home.tsx +++ b/src/pages/index/Home.tsx @@ -1,17 +1,24 @@ import styled from 'styled-components'; import Menubar from '@components/Menubar'; +import Header from '@components/Header.tsx'; function Home() { return ( - - 강의시간표/수업계획서조회 +
+ + + 강의시간표/수업계획서조회 + ); } const Container = styled.div` ${props => props.theme.texts.title}; +`; + +const Box = styled.div` display: flex; `; diff --git a/src/styles/GlobalStyle.tsx b/src/styles/GlobalStyle.tsx index e37b293..1bef676 100644 --- a/src/styles/GlobalStyle.tsx +++ b/src/styles/GlobalStyle.tsx @@ -26,6 +26,8 @@ const GlobalStyle = createGlobalStyle` } input { border-radius: 2px; + outline: none; + border: none; } button { cursor: pointer; diff --git a/src/styles/theme/Theme.ts b/src/styles/theme/Theme.ts index 062f09e..10a72d4 100644 --- a/src/styles/theme/Theme.ts +++ b/src/styles/theme/Theme.ts @@ -6,8 +6,9 @@ const colors = { neutral1: '#222', neutral2: '#333', neutral3: '#444', - neutral4: '#E8E8E8', - neutral5: '#F7F7F7', + neutral4: '#777', + neutral5: '#E8E8E8', + neutral6: '#F7F7F7', blue: '#A9D0F5', black: '#000', white: '#FFF',