feat: coming soon

This commit is contained in:
Divlo
2021-10-24 05:48:06 +02:00
parent 21123c4477
commit 33bd2bb6bf
176 changed files with 36858 additions and 22133 deletions

View File

@ -0,0 +1,12 @@
import { Meta, Story } from '@storybook/react'
import { Header as Component } from './'
const Stories: Meta = {
title: 'Header',
component: Component
}
export default Stories
export const Header: Story = (arguments_) => <Component {...arguments_} />

View File

@ -0,0 +1,10 @@
import { render } from '@testing-library/react'
import { Header } from './'
describe('<Header />', () => {
it('should render', async () => {
const { getByText } = render(<Header />)
expect(getByText('Thream')).toBeInTheDocument()
})
})

View File

@ -0,0 +1,33 @@
import Link from 'next/link'
import Image from 'next/image'
import { Language } from './Language'
import { SwitchTheme } from './SwitchTheme'
export const Header: React.FC = () => {
return (
<header className='bg-white flex justify-center sticky top-0 z-50 w-full px-6 py-2 border-b-2 border-gray-600 dark:border-gray-400 dark:bg-black'>
<div className='container flex justify-between'>
<Link href='/'>
<a>
<div className='flex items-center justify-center'>
<Image
width={60}
height={60}
src='/images/icons/Thream.png'
alt='Thream'
/>
<span className='ml-1 font-medium font-headline hidden xs:block text-green-800 dark:text-green-400'>
Thream
</span>
</div>
</a>
</Link>
<div className='flex justify-between'>
<Language />
<SwitchTheme />
</div>
</div>
</header>
)
}

View File

@ -1,8 +1,4 @@
import { useTheme } from 'contexts/Theme'
export const Arrow: React.FC = () => {
const { theme } = useTheme()
return (
<svg
width='12'
@ -12,8 +8,8 @@ export const Arrow: React.FC = () => {
xmlns='http://www.w3.org/2000/svg'
>
<path
className='fill-current text-black dark:text-white'
d='M9.8024 0.292969L5.61855 4.58597L1.43469 0.292969L0.0566406 1.70697L5.61855 7.41397L11.1805 1.70697L9.8024 0.292969Z'
fill={theme === 'dark' ? '#fff' : '#181818'}
/>
</svg>
)

View File

@ -1,9 +1,7 @@
import Image from 'next/image'
import { Language } from 'utils/authentication'
export interface LanguageFlagProps {
language: Language
language: string
}
export const LanguageFlag: React.FC<LanguageFlagProps> = (props) => {
@ -17,15 +15,9 @@ export const LanguageFlag: React.FC<LanguageFlagProps> = (props) => {
src={`/images/svg/languages/${language}.svg`}
alt={language}
/>
<p className='language-title'>{language.toUpperCase()}</p>
<style jsx>
{`
.language-title {
margin: 0 8px 0 10px;
}
`}
</style>
<p data-cy='language-flag-text' className='mx-2 text-base'>
{language.toUpperCase()}
</p>
</>
)
}

View File

@ -1,15 +1,20 @@
import { useEffect, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import useTranslation from 'next-translate/useTranslation'
import setLanguage from 'next-translate/setLanguage'
import classNames from 'classnames'
import { Arrow } from './Arrow'
import { languages, Language as LanguageType } from 'utils/authentication'
import { LanguageFlag } from './LanguageFlag'
import i18n from '../../../i18n.json'
export const Language: React.FC = () => {
const { lang: currentLanguage } = useTranslation()
const [hiddenMenu, setHiddenMenu] = useState(true)
const handleHiddenMenu = useCallback(() => {
setHiddenMenu(!hiddenMenu)
}, [hiddenMenu])
useEffect(() => {
if (!hiddenMenu) {
window.document.addEventListener('click', handleHiddenMenu)
@ -20,86 +25,46 @@ export const Language: React.FC = () => {
return () => {
window.document.removeEventListener('click', handleHiddenMenu)
}
}, [hiddenMenu])
}, [hiddenMenu, handleHiddenMenu])
const handleLanguage = async (language: LanguageType): Promise<void> => {
const handleLanguage = async (language: string): Promise<void> => {
await setLanguage(language)
handleHiddenMenu()
}
const handleHiddenMenu = (): void => {
setHiddenMenu(!hiddenMenu)
}
return (
<>
<div className='language-menu'>
<div className='selected-language' onClick={handleHiddenMenu}>
<LanguageFlag language={currentLanguage as LanguageType} />
<Arrow />
</div>
{!hiddenMenu && (
<ul>
{languages.map((language, index) => {
if (language === currentLanguage) {
return null
}
return (
<li
key={index}
onClick={async () => await handleLanguage(language)}
>
<LanguageFlag language={language} />
</li>
)
})}
</ul>
)}
<div className='flex flex-col justify-center items-center cursor-pointer'>
<div
data-cy='language-click'
className='flex items-center mr-5'
onClick={handleHiddenMenu}
>
<LanguageFlag language={currentLanguage} />
<Arrow />
</div>
<style jsx>
{`
.language-menu {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
<ul
data-cy='languages-list'
className={classNames(
'flex flex-col justify-center items-center absolute p-0 top-14 z-10 w-24 mt-3 mr-4 rounded-lg list-none shadow-light dark:shadow-dark bg-white dark:bg-black',
{ hidden: hiddenMenu }
)}
>
{i18n.locales.map((language, index) => {
if (language === currentLanguage) {
return null
}
.selected-language {
display: flex;
align-items: center;
margin-right: 15px;
}
ul {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
top: 60px;
width: 100px;
padding: 10px;
margin: 10px 15px 0 0px;
border-radius: 15%;
padding: 0;
box-shadow: 0px 1px 10px var(--color-shadow);
background-color: var(--color-background-primary);
z-index: 10;
}
ul > li {
list-style: none;
display: flex;
align-items: center;
justify-content: center;
height: 50px;
width: 100%;
}
ul > li:hover {
background-color: rgba(79, 84, 92, 0.16);
}
`}
</style>
</>
return (
<li
key={index}
className='flex items-center justify-center w-full h-12 hover:bg-[#4f545c] hover:bg-opacity-20 pl-2'
onClick={async () => await handleLanguage(language)}
>
<LanguageFlag language={language} />
</li>
)
})}
</ul>
</div>
)
}

View File

@ -1,25 +1,54 @@
import { useTheme } from 'contexts/Theme'
import { useEffect, useState } from 'react'
import { useTheme } from 'next-themes'
export const SwitchTheme: React.FC = () => {
const { handleToggleTheme, theme } = useTheme()
const [mounted, setMounted] = useState(false)
const { theme, setTheme } = useTheme()
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return null
}
const handleClick = (): void => {
setTheme(theme === 'dark' ? 'light' : 'dark')
}
return (
<>
<div className='toggle-button' onClick={handleToggleTheme}>
<div className='toggle-theme-button'>
<div
className='flex items-center'
data-cy='switch-theme-click'
onClick={handleClick}
>
<div className='toggle-theme-button relative cursor-pointer bg-transparent inline-block'>
<div className='toggle-track'>
<div className='toggle-track-check'>
<span className='toggle_Dark'>🌜</span>
<div
data-cy='switch-theme-dark'
className='toggle-track-check absolute'
>
<span className='toggle_Dark flex justify-center items-center relative'>
🌜
</span>
</div>
<div className='toggle-track-x'>
<span className='toggle_Light'>🌞</span>
<div
data-cy='switch-theme-light'
className='toggle-track-x absolute'
>
<span className='toggle_Light flex justify-center items-center relative'>
🌞
</span>
</div>
</div>
<div className='toggle-thumb' />
<div className='toggle-thumb absolute' />
<input
data-cy='switch-theme-input'
type='checkbox'
aria-label='Dark mode toggle'
className='toggle-screenreader-only'
className='toggle-screenreader-only absolute overflow-hidden'
defaultChecked
/>
</div>
@ -27,16 +56,8 @@ export const SwitchTheme: React.FC = () => {
<style jsx>
{`
.toggle-button {
display: flex;
align-items: center;
}
.toggle-theme-button {
touch-action: pan-x;
display: inline-block;
position: relative;
cursor: pointer;
background-color: transparent;
border: 0;
padding: 0;
user-select: none;
@ -51,7 +72,6 @@ export const SwitchTheme: React.FC = () => {
color: #fff;
}
.toggle-track-check {
position: absolute;
width: 14px;
height: 10px;
top: 0;
@ -64,7 +84,6 @@ export const SwitchTheme: React.FC = () => {
transition: opacity 0.25s ease;
}
.toggle-track-x {
position: absolute;
width: 10px;
height: 10px;
top: 0;
@ -77,15 +96,10 @@ export const SwitchTheme: React.FC = () => {
}
.toggle_Dark,
.toggle_Light {
align-items: center;
display: flex;
height: 10px;
justify-content: center;
position: relative;
width: 10px;
}
.toggle-thumb {
position: absolute;
left: ${theme === 'dark' ? '27px' : '0px'};
width: 22px;
height: 22px;
@ -102,9 +116,7 @@ export const SwitchTheme: React.FC = () => {
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
`}

View File

@ -0,0 +1 @@
export * from './SwitchTheme'

View File

@ -0,0 +1 @@
export * from './Header'

View File

@ -1,94 +0,0 @@
import Link from 'next/link'
import Image from 'next/image'
import { Language } from './Language'
import { SwitchTheme } from './SwitchTheme'
export const Header: React.FC = () => {
return (
<>
<header className='header'>
<div className='container'>
<nav className='navbar navbar-fixed-top'>
<Link href='/'>
<a className='navbar__brand-link'>
<div className='navbar__brand'>
<Image
width={60}
height={60}
src='/images/icons/Thream.png'
alt='Thream'
/>
<strong className='navbar__brand-title'>Thream</strong>
</div>
</a>
</Link>
<div className='navbar__buttons'>
<Language />
<SwitchTheme />
</div>
</nav>
</div>
</header>
<style jsx global>
{`
body {
padding: 0 32px;
}
@media (max-width: 404px) {
body {
padding: 0;
}
}
`}
</style>
<style jsx>
{`
.header {
margin-top: 20px;
}
.container {
max-width: 1280px;
width: 100%;
margin: auto;
}
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem 1rem;
}
.navbar-fixed-top {
position: sticky;
top: 0;
z-index: 200;
}
.navbar__brand-link {
color: var(--color-secondary);
text-decoration: none;
font-size: 16px;
}
.navbar__brand {
display: flex;
align-items: center;
justify-content: space-between;
}
.navbar__brand-title {
font-weight: 400;
margin-left: 10px;
}
.navbar__buttons {
display: flex;
justify-content: space-between;
}
@media (max-width: 320px) {
.navbar__brand-title {
display: none;
}
}
`}
</style>
</>
)
}