-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from hduoc2003/feature/create-header-and-footer
#2 done
- Loading branch information
Showing
27 changed files
with
1,502 additions
and
8 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
'use client'; | ||
|
||
export default function Loading() { | ||
return ( | ||
<div> | ||
<h1>Loading</h1> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react' | ||
|
||
export default function SignIn() { | ||
return ( | ||
<div>SignIn</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react' | ||
|
||
export default function SignUp() { | ||
return ( | ||
<div>SignUp</div> | ||
) | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Input } from 'antd' | ||
import React from 'react' | ||
import { BiSearchAlt } from "react-icons/bi"; | ||
|
||
export default function SearchBar({ | ||
onSearch | ||
}: { | ||
onSearch: (value: string) => void | ||
}): React.JSX.Element { | ||
return ( | ||
<Input.Search | ||
placeholder='Tìm kiếm môn học' | ||
allowClear | ||
onSearch={onSearch} | ||
size='large' | ||
style={{ width: 400 }} | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import Image from 'next/image' | ||
import React from 'react' | ||
import UETLogo from '../../public/images/uet-logo.svg'; | ||
import { THEME } from '@/styles/theme'; | ||
|
||
export default function Footer() { | ||
return ( | ||
<div> | ||
<div className='h-0.5 mb-5' style={{ backgroundColor: THEME.PRIMARY_COLOR }}></div> | ||
<div className="flex-row"> | ||
<div className="flex items-center ml-4 mb-4"> | ||
<Image src={UETLogo} alt='uet-logo' /> | ||
<div className="flex-col ml-2"> | ||
<div className='font-semibold' style={{ color: THEME.PRIMARY_COLOR }}> | ||
Trường Đại học Công nghệ, Đại học Quốc gia Hà Nội | ||
</div> | ||
<div className='text-gray-400 text-xs'>Nhà E3, 144 Xuân Thuỷ, Cầu Giấy, Hà Nội</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
"use client"; | ||
|
||
import { THEME } from "@/styles/theme"; | ||
import React, { ReactNode, useState } from "react"; | ||
import { useDispatch, useSelector } from "react-redux"; | ||
import { authActions } from "@/redux/auth/authSlice"; | ||
import { authSelector } from "@/redux/auth/authSelector"; | ||
import { Avatar, Badge, Select } from "antd"; | ||
import { IoNotificationsOutline, IoNotifications } from "react-icons/io5"; | ||
import SearchBar from "../common/SearchBar"; | ||
import Link from "next/link"; | ||
import { MAIN_FONT } from "@/styles/fonts"; | ||
|
||
const languages = ['Tiếng Việt', 'English']; | ||
|
||
|
||
interface TabProps { | ||
selected: boolean; | ||
children: ReactNode; | ||
} | ||
|
||
const Tab: React.FC<TabProps> = ({ selected, children }: TabProps) => { | ||
const [hover, setHover] = useState<Boolean>(false); | ||
|
||
return ( | ||
<button | ||
style={{ | ||
justifyItems: "center", | ||
height: "100%", | ||
// backgroundColor: 'red', | ||
position: "relative", | ||
}} | ||
onMouseEnter={() => setHover(true)} | ||
onMouseLeave={() => setHover(false)} | ||
> | ||
{hover ? ( | ||
<div | ||
style={{ | ||
height: "2px", | ||
width: "100%", | ||
backgroundColor: THEME.PRIMARY_COLOR, | ||
position: "absolute", | ||
top: "0px", | ||
}} | ||
></div> | ||
) : null} | ||
<div style={selected ? { color: THEME.PRIMARY_COLOR } : {}}> | ||
{children} | ||
</div> | ||
</button> | ||
); | ||
}; | ||
|
||
export default function Header() { | ||
const dispatch = useDispatch(); | ||
const authState = useSelector(authSelector); | ||
const [avtURL, setAvtURL] = useState<string>('https://yt3.googleusercontent.com/-CFTJHU7fEWb7BYEb6Jh9gm1EpetvVGQqtof0Rbh-VQRIznYYKJxCaqv_9HeBcmJmIsp2vOO9JU=s900-c-k-c0x00ffffff-no-rj') | ||
const [avtStrokeColor, setAvtStrokeColor] = useState<string>(THEME.PRIMARY_COLOR); | ||
const [notiCount, setNotiCount] = useState(10) | ||
|
||
const handleSignIn = (): void => { | ||
dispatch(authActions.updateAuthState({ | ||
signedIn: true, | ||
username: "21020059", | ||
name: "Bùi Huy Dược" | ||
})) | ||
}; | ||
|
||
const handleSignOut = (): void => { | ||
dispatch(authActions.updateAuthState({ | ||
signedIn: false | ||
})) | ||
}; | ||
|
||
const handleOnSearch = (value: string): void => { | ||
console.log(value) | ||
} | ||
|
||
return ( | ||
<div className="flex items-center h-[70px] sticky top-0 z-[1000] border-b-[0px] border-gray-200" style={{ backgroundColor: THEME.SECONDARY_COLOR }}> | ||
{/* <NavBar/> */} | ||
<div className="ml-10 flex-1"> | ||
<SearchBar onSearch={handleOnSearch} /> | ||
</div> | ||
<Select | ||
defaultValue={languages[0]} | ||
// onChange={handleProvinceChange} | ||
options={languages.map((language: string, i: number) => ({ | ||
label: language, | ||
value: language, | ||
}))} | ||
className={`w-[110px] mr-[30px] ${MAIN_FONT.className}`} | ||
/> | ||
{ | ||
authState.signedIn ? | ||
<div className="flex mr-5"> | ||
<button onClick={() => setNotiCount(0)}> | ||
<Badge count={notiCount} overflowCount={9} title="Thông báo" className={`mr-7 ${MAIN_FONT.className}`}> | ||
<div className="w-[40px] h-[40px] rounded-full flex items-center justify-center bg-gray-200 hover:bg-gray-300"> | ||
<IoNotificationsOutline size={25} /> | ||
</div> | ||
</Badge> | ||
</button> | ||
<button | ||
onClick={handleSignOut} | ||
onMouseEnter={() => setAvtStrokeColor(THEME.DARK_PRIMARY_COLOR)} | ||
onMouseLeave={() => setAvtStrokeColor(THEME.PRIMARY_COLOR)} | ||
> | ||
<div className="relative flex"> | ||
<Avatar className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2" src={avtURL} size={40}></Avatar> | ||
<svg width="50" height="50" viewBox="0 0 32 32"><circle r="15" cx="16" cy="16" fill="none" stroke-width="2" style={{ stroke: avtStrokeColor }}></circle></svg> | ||
</div> | ||
</button> | ||
<div className="ml-3"> | ||
<div className="font-semibold ">Xin chào,</div> | ||
<div className="text-xs font-semibold">{`${authState.username} ${authState.name}`}</div> | ||
</div> | ||
</div> | ||
: | ||
<div className="flex gap-4 mr-10"> | ||
<Link href='/signup'> | ||
<button | ||
style={{ | ||
// backgroundColor: "gray", | ||
borderRadius: "10px", | ||
padding: "7px 17px", | ||
color: THEME.PRIMARY_COLOR, | ||
}} | ||
className="bg-gray-200 hover:bg-gray-300" | ||
> | ||
Đăng ký | ||
</button> | ||
</Link> | ||
<Link href='/signin'> | ||
<button | ||
className="bg-primary hover:bg-dark-primary" | ||
style={{ | ||
// backgroundColor: THEME.PRIMARY_COLOR, | ||
borderRadius: "10px", | ||
padding: "7px 17px", | ||
color: THEME.SECONDARY_COLOR, | ||
}} | ||
onClick={handleSignIn} | ||
> | ||
Đăng nhập | ||
</button> | ||
</Link> | ||
</div> | ||
} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
'use client'; | ||
|
||
import { THEME } from '@/styles/theme' | ||
import Link from 'next/link' | ||
import React, { useState } from 'react' | ||
import { AiOutlineMenu, AiOutlineSchedule, AiFillSchedule } from 'react-icons/ai' | ||
import { MdOutlineTopic, MdTopic } from 'react-icons/md' | ||
import { BsFiletypeDoc, BsPerson, BsPersonRolodex } from 'react-icons/bs' | ||
import { TfiStatsUp } from 'react-icons/tfi' | ||
import { ImStatsDots } from 'react-icons/im' | ||
import MySubjects from '../../public/images/my-subjects.svg' | ||
import Image from 'next/image' | ||
|
||
const NavsContent: string[] = [ | ||
"Thời khoá biểu", | ||
"Môn học của tôi", | ||
"Học phần", | ||
"Thống kê", | ||
]; | ||
|
||
const iconSize = 22; | ||
|
||
// const NavsIcons = [ | ||
// <AiOutlineSchedule key={0} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
// // <Image src={MySubjects} alt='My subjects' key={1} width={iconSize} height={iconSize}></Image>, | ||
// // <MdOutlineTopic key={1} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
// <BsPersonRolodex key={1} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
// <MdOutlineTopic key={2} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
// <TfiStatsUp key={3} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/> | ||
// ] | ||
|
||
const NavsIcons = [ | ||
<AiFillSchedule key={0} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
// <Image src={MySubjects} alt='My subjects' key={1} width={iconSize} height={iconSize}></Image>, | ||
// <MdOutlineTopic key={1} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
<BsPersonRolodex key={1} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
<MdTopic key={2} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/>, | ||
<ImStatsDots key={3} size={iconSize} color={THEME.ROYAL_GRAY_COLOR}/> | ||
] | ||
|
||
const NavsRoutes = [ | ||
'/schedule', | ||
'/mysubject', | ||
'/allsubject', | ||
'/stats' | ||
] | ||
|
||
export default function NavBar() { | ||
const [expand, setExpand] = useState(true); | ||
|
||
const handleCollapse = () => { | ||
setExpand(!expand); | ||
}; | ||
|
||
return ( | ||
<div | ||
className="h-screen sticky left-0 top-0 border-r-[1px] border-gray-200 px-5 bg-secondary" | ||
> | ||
<div className='flex gap-5 h-[70px] items-center'> | ||
<button onClick={handleCollapse}><AiOutlineMenu size={iconSize} /></button> | ||
{/* <Image src={UETLogo} alt="UET Logo" height={50} width={50} /> */} | ||
{ | ||
expand && | ||
<Link href='/'> | ||
<div className="text-3xl font-extrabold tracking-wide" style={{ color: THEME.PRIMARY_COLOR }}>UETable</div> | ||
</Link> | ||
} | ||
</div> | ||
<div className='mt-[30px]'> | ||
{ | ||
NavsContent.map((navContent: string, i: number) => { | ||
return ( | ||
<div className='hover:bg-light-primary py-[10px] -mx-5 pl-5' key={i}> | ||
<Link href={NavsRoutes[i]} > | ||
<div className="flex gap-3 items-center"> | ||
{NavsIcons[i]} | ||
{expand && <div className='text-royal-gray'>{navContent}</div>} | ||
</div> | ||
</Link> | ||
</div> | ||
) | ||
}) | ||
} | ||
</div> | ||
</div> | ||
) | ||
} |
Oops, something went wrong.