feat: improve header to set locale + remove setup page
| @@ -4,7 +4,7 @@ | ||||
|       "startServerCommand": "npm run start", | ||||
|       "startServerReadyPattern": "ready on", | ||||
|       "startServerReadyTimeout": 20000, | ||||
|       "url": ["http://localhost:3000/", "http://localhost:3000/setup"], | ||||
|       "url": ["http://localhost:3000/"], | ||||
|       "numberOfRuns": 3 | ||||
|     }, | ||||
|     "assert": { | ||||
|   | ||||
| @@ -77,7 +77,7 @@ export const Contact: React.FC = () => { | ||||
|             required | ||||
|           /> | ||||
|  | ||||
|           <div className='text-center'> | ||||
|           <div className='text-center' style={{ marginBottom: 20 }}> | ||||
|             <Button type='submit'>{t('home:contact.sendEmail')}</Button> | ||||
|           </div> | ||||
|         </Form> | ||||
|   | ||||
| @@ -1,29 +0,0 @@ | ||||
| import setLanguage from 'next-translate/setLanguage' | ||||
|  | ||||
| interface LanguageButtonProps { | ||||
|   lang: string | ||||
| } | ||||
|  | ||||
| export const LanguageButton: React.FC<LanguageButtonProps> = (props) => { | ||||
|   return ( | ||||
|     <> | ||||
|       <span | ||||
|         onClick={async () => await setLanguage(props.lang)} | ||||
|         className='important' | ||||
|       > | ||||
|         {props.children} | ||||
|       </span> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           span { | ||||
|             cursor: pointer; | ||||
|           } | ||||
|           span:hover { | ||||
|             text-decoration: underline; | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,39 +0,0 @@ | ||||
| import Image from 'next/image' | ||||
|  | ||||
| import { Tooltip } from 'components/design/Tooltip' | ||||
| import { LanguageButton } from './LanguageButton' | ||||
|  | ||||
| interface LanguageFlagProps { | ||||
|   imageLink: string | ||||
|   title: string | ||||
|   lang: string | ||||
| } | ||||
|  | ||||
| export const LanguageFlag: React.FC<LanguageFlagProps> = (props) => { | ||||
|   const { lang, title, imageLink } = props | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <div className='LanguageFlag'> | ||||
|         <LanguageButton lang={lang}> | ||||
|           <Tooltip title={title}> | ||||
|             <Image alt={title} src={imageLink} width={31} height={31} /> | ||||
|           </Tooltip> | ||||
|         </LanguageButton> | ||||
|       </div> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .LanguageFlag { | ||||
|             margin-right: 7px; | ||||
|           } | ||||
|           @media (max-width: 700px) { | ||||
|             .LanguageFlag { | ||||
|               display: none; | ||||
|             } | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,36 +1,16 @@ | ||||
| import useTranslation from 'next-translate/useTranslation' | ||||
|  | ||||
| import { LanguageButton } from './LanguageButton' | ||||
| import { LanguageFlag } from './LanguageFlag' | ||||
|  | ||||
| export const Footer: React.FC = () => { | ||||
|   const { t } = useTranslation() | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <footer className='Footer text-center'> | ||||
|         <p className='Footer__text'> | ||||
|         <p> | ||||
|           <span className='important'>Divlo</span> | {t('common:allRightsReserved')} | ||||
|         </p> | ||||
|         <p className='Footer__lang'> | ||||
|           <LanguageButton lang='en'>{t('common:english')}</LanguageButton> |{' '} | ||||
|           <LanguageButton lang='fr'>{t('common:french')}</LanguageButton> | ||||
|         </p> | ||||
|       </footer> | ||||
|  | ||||
|       <div className='Footer__flags'> | ||||
|         <LanguageFlag | ||||
|           lang='en' | ||||
|           imageLink='/images/flags/english_flag.png' | ||||
|           title={t('common:english')} | ||||
|         /> | ||||
|         <LanguageFlag | ||||
|           lang='fr' | ||||
|           imageLink='/images/flags/french_flag.png' | ||||
|           title={t('common:french')} | ||||
|         /> | ||||
|       </div> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .Footer { | ||||
| @@ -39,19 +19,7 @@ export const Footer: React.FC = () => { | ||||
|             flex-direction: column; | ||||
|             justify-content: center; | ||||
|             align-items: center; | ||||
|           } | ||||
|           .Footer__text { | ||||
|             margin: 20px 0 10px 0; | ||||
|           } | ||||
|           .Footer__lang { | ||||
|             margin: 0 0 20px 0; | ||||
|           } | ||||
|           .Footer__flags { | ||||
|             display: flex; | ||||
|             position: fixed; | ||||
|             bottom: 28px; | ||||
|             left: 32px; | ||||
|             z-index: 10; | ||||
|             padding: 10px; | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|   | ||||
| @@ -1,38 +0,0 @@ | ||||
| import Link from 'next/link' | ||||
| import Image from 'next/image' | ||||
|  | ||||
| export const BrandLogo: React.FC = () => { | ||||
|   return ( | ||||
|     <> | ||||
|       <Link href='/'> | ||||
|         <a className='Header__brand-link'> | ||||
|           <Image | ||||
|             width={65} | ||||
|             height={65} | ||||
|             src='/images/divlo_icon_small.png' | ||||
|             alt="Divlo's Logo" | ||||
|           /> | ||||
|         </a> | ||||
|       </Link> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .Header__brand-link { | ||||
|             display: inline-block; | ||||
|             padding-top: 0.3125rem; | ||||
|             padding-bottom: 0.3125rem; | ||||
|             margin-right: 1rem; | ||||
|             font-size: 1.25rem; | ||||
|             line-height: inherit; | ||||
|             white-space: nowrap; | ||||
|           } | ||||
|           @media (min-width: 993px) { | ||||
|             .Header__brand-link { | ||||
|               width: 40%; | ||||
|             } | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,76 +0,0 @@ | ||||
| import classNames from 'classnames' | ||||
|  | ||||
| type HamburgerIconComponent = React.FC<{ | ||||
|   isActive: boolean | ||||
|   handleToggleNavbar: () => void | ||||
| }> | ||||
|  | ||||
| export const HamburgerIcon: HamburgerIconComponent = props => { | ||||
|   return ( | ||||
|     <> | ||||
|       <div | ||||
|         onClick={props.handleToggleNavbar} | ||||
|         className={classNames('Header__hamburger', { | ||||
|           'Header__hamburger-active': props.isActive | ||||
|         })} | ||||
|       > | ||||
|         <span /> | ||||
|       </div> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .Header__hamburger { | ||||
|             display: none; | ||||
|             width: 56px; | ||||
|             height: 40px; | ||||
|             cursor: pointer; | ||||
|             background-color: transparent; | ||||
|             border: 1px solid rgba(255, 255, 255, 0.1); | ||||
|             border-radius: 0.25rem; | ||||
|             position: relative; | ||||
|           } | ||||
|           .Header__hamburger > span, | ||||
|           .Header__hamburger > span::before, | ||||
|           .Header__hamburger > span::after { | ||||
|             position: absolute; | ||||
|             width: 22px; | ||||
|             height: 1.3px; | ||||
|             background-color: rgba(255, 255, 255); | ||||
|           } | ||||
|           .Header__hamburger > span { | ||||
|             top: 50%; | ||||
|             left: 50%; | ||||
|             transform: translate(-50%, -50%); | ||||
|             transition: background-color 0.3s ease-in-out; | ||||
|           } | ||||
|           .Header__hamburger > span::before, | ||||
|           .Header__hamburger > span::after { | ||||
|             content: ''; | ||||
|             transition: transform 0.3s ease-in-out; | ||||
|           } | ||||
|           .Header__hamburger > span::before { | ||||
|             transform: translateY(-8px); | ||||
|           } | ||||
|           .Header__hamburger > span::after { | ||||
|             transform: translateY(8px); | ||||
|           } | ||||
|           .Header__hamburger-active span { | ||||
|             background-color: transparent; | ||||
|           } | ||||
|           .Header__hamburger-active > span::before { | ||||
|             transform: translateY(0px) rotateZ(45deg); | ||||
|           } | ||||
|           .Header__hamburger-active > span::after { | ||||
|             transform: translateY(0px) rotateZ(-45deg); | ||||
|           } | ||||
|           /* Hamburger icon on Mobile */ | ||||
|           @media (max-width: 992px) { | ||||
|             .Header__hamburger { | ||||
|               display: flex; | ||||
|             } | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
							
								
								
									
										16
									
								
								components/Header/Language/Arrow.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,16 @@ | ||||
| export const Arrow: React.FC = () => { | ||||
|   return ( | ||||
|     <svg | ||||
|       width='12' | ||||
|       height='8' | ||||
|       viewBox='0 0 12 8' | ||||
|       fill='none' | ||||
|       xmlns='http://www.w3.org/2000/svg' | ||||
|     > | ||||
|       <path | ||||
|         d='M9.8024 0.292969L5.61855 4.58597L1.43469 0.292969L0.0566406 1.70697L5.61855 7.41397L11.1805 1.70697L9.8024 0.292969Z' | ||||
|         fill='#fff' | ||||
|       /> | ||||
|     </svg> | ||||
|   ) | ||||
| } | ||||
							
								
								
									
										31
									
								
								components/Header/Language/LanguageFlag.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,31 @@ | ||||
| import Image from 'next/image' | ||||
|  | ||||
| export interface LanguageFlagProps { | ||||
|   language: string | ||||
| } | ||||
|  | ||||
| export const LanguageFlag: React.FC<LanguageFlagProps> = (props) => { | ||||
|   const { language } = props | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <Image | ||||
|         width={35} | ||||
|         height={35} | ||||
|         src={`/images/languages/${language}.svg`} | ||||
|         alt={language} | ||||
|       /> | ||||
|       <p className='language-title'>{language.toUpperCase()}</p> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .language-title { | ||||
|             margin: 0 8px 0 10px; | ||||
|             font-size: 16px; | ||||
|             font-family: 'Arial', 'sans-serif'; | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
							
								
								
									
										105
									
								
								components/Header/Language/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,105 @@ | ||||
| import { useEffect, useState } from 'react' | ||||
| import useTranslation from 'next-translate/useTranslation' | ||||
| import setLanguage from 'next-translate/setLanguage' | ||||
|  | ||||
| import { Arrow } from './Arrow' | ||||
| import { LanguageFlag } from './LanguageFlag' | ||||
| import { locales } from 'i18n.json' | ||||
|  | ||||
| export const Language: React.FC = () => { | ||||
|   const { lang: currentLanguage } = useTranslation() | ||||
|   const [hiddenMenu, setHiddenMenu] = useState(true) | ||||
|  | ||||
|   useEffect(() => { | ||||
|     if (!hiddenMenu) { | ||||
|       window.document.addEventListener('click', handleHiddenMenu) | ||||
|     } else { | ||||
|       window.document.removeEventListener('click', handleHiddenMenu) | ||||
|     } | ||||
|  | ||||
|     return () => { | ||||
|       window.document.removeEventListener('click', handleHiddenMenu) | ||||
|     } | ||||
|   }, [hiddenMenu]) | ||||
|  | ||||
|   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} /> | ||||
|           <Arrow /> | ||||
|         </div> | ||||
|         {!hiddenMenu && ( | ||||
|           <ul> | ||||
|             {locales.map((language, index) => { | ||||
|               if (language === currentLanguage) { | ||||
|                 return null | ||||
|               } | ||||
|               return ( | ||||
|                 <li | ||||
|                   key={index} | ||||
|                   onClick={async () => await handleLanguage(language)} | ||||
|                 > | ||||
|                   <LanguageFlag language={language} /> | ||||
|                 </li> | ||||
|               ) | ||||
|             })} | ||||
|           </ul> | ||||
|         )} | ||||
|       </div> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .language-menu { | ||||
|             display: flex; | ||||
|             flex-direction: column; | ||||
|             justify-content: center; | ||||
|             align-items: center; | ||||
|             cursor: pointer; | ||||
|           } | ||||
|           .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> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,54 +0,0 @@ | ||||
| import Link from 'next/link' | ||||
| import { useRouter } from 'next/router' | ||||
| import classNames from 'classnames' | ||||
|  | ||||
| type NavigationLinkComponent = React.FC<{ path: string }> | ||||
|  | ||||
| export const NavigationLink: NavigationLinkComponent = props => { | ||||
|   const { pathname } = useRouter() | ||||
|   const isCurrentPage = pathname === props.path | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <li className='navbar-item'> | ||||
|         <Link href={props.path}> | ||||
|           <a | ||||
|             className={classNames('navbar-link', { | ||||
|               'navbar-link-active': isCurrentPage | ||||
|             })} | ||||
|           > | ||||
|             {props.children} | ||||
|           </a> | ||||
|         </Link> | ||||
|       </li> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .navbar-link { | ||||
|             display: block; | ||||
|             padding: 0.5rem 1rem; | ||||
|           } | ||||
|           .navbar-link:hover { | ||||
|             text-decoration: none; | ||||
|             color: rgba(255, 255, 255, 0.75); | ||||
|           } | ||||
|           .navbar-link, | ||||
|           .navbar-link-active { | ||||
|             color: rgba(255, 255, 255, 0.5); | ||||
|           } | ||||
|           .navbar-link-active, | ||||
|           .navbar-link-active:hover { | ||||
|             color: var(--text-color); | ||||
|           } | ||||
|           .navbar-item { | ||||
|             list-style: none; | ||||
|           } | ||||
|           .navbar-link { | ||||
|             font-size: 16px; | ||||
|             padding: 0.5rem; | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,59 +0,0 @@ | ||||
| import classNames from 'classnames' | ||||
| import useTranslation from 'next-translate/useTranslation' | ||||
|  | ||||
| import { NavigationLink } from './NavigationLink' | ||||
|  | ||||
| type NavigationComponent = React.FC<{ isActive: boolean }> | ||||
|  | ||||
| export const Navigation: NavigationComponent = props => { | ||||
|   const { t } = useTranslation() | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <nav className='Header__navbar'> | ||||
|         <ul | ||||
|           className={classNames('navbar__list', { | ||||
|             'navbar__list-active': props.isActive | ||||
|           })} | ||||
|         > | ||||
|           <NavigationLink path='/'>{t('common:home')}</NavigationLink> | ||||
|           <NavigationLink path='/setup'>Setup</NavigationLink> | ||||
|         </ul> | ||||
|       </nav> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           @media (min-width: 992px) { | ||||
|             .Header__navbar { | ||||
|               display: flex; | ||||
|               flex-basis: auto; | ||||
|             } | ||||
|           } | ||||
|           .Header__navbar { | ||||
|             flex-basis: 100%; | ||||
|             flex-grow: 1; | ||||
|             align-items: center; | ||||
|           } | ||||
|           .navbar__list { | ||||
|             display: flex; | ||||
|             flex-direction: row; | ||||
|             margin-left: auto; | ||||
|           } | ||||
|           .navbar__list.navbar__list-active { | ||||
|             margin: 0 !important; | ||||
|             display: flex; | ||||
|           } | ||||
|           @media (max-width: 992px) { | ||||
|             .navbar__list { | ||||
|               display: none; | ||||
|               flex-direction: column; | ||||
|               align-items: center; | ||||
|               padding-left: 0; | ||||
|               list-style: none; | ||||
|             } | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,65 +1,84 @@ | ||||
| import { useState } from 'react' | ||||
| import Link from 'next/link' | ||||
| import Image from 'next/image' | ||||
|  | ||||
| import { HamburgerIcon } from './HamburgerIcon' | ||||
| import { BrandLogo } from './BrandLogo' | ||||
| import { Navigation } from './Navigation' | ||||
| import { Language } from './Language' | ||||
|  | ||||
| export const Header: React.FC = () => { | ||||
|   const [isActive, setIsActive] = useState(false) | ||||
|  | ||||
|   const handleToggleNavbar = (): void => { | ||||
|     setIsActive(!isActive) | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <header className='Header'> | ||||
|       <header className='header'> | ||||
|         <div className='container'> | ||||
|           <BrandLogo /> | ||||
|           <HamburgerIcon | ||||
|             isActive={isActive} | ||||
|             handleToggleNavbar={handleToggleNavbar} | ||||
|           /> | ||||
|           <Navigation isActive={isActive} /> | ||||
|           <nav className='navbar navbar-fixed-top'> | ||||
|             <Link href='/'> | ||||
|               <a className='navbar__brand-link'> | ||||
|                 <div className='navbar__brand'> | ||||
|                   <Image | ||||
|                     width={60} | ||||
|                     height={60} | ||||
|                     src='/images/divlo_icon_small.png' | ||||
|                     alt='Divlo' | ||||
|                   /> | ||||
|                   <strong className='navbar__brand-title'>Divlo</strong> | ||||
|                 </div> | ||||
|               </a> | ||||
|             </Link> | ||||
|             <div className='navbar__buttons'> | ||||
|               <Language /> | ||||
|             </div> | ||||
|           </nav> | ||||
|         </div> | ||||
|       </header> | ||||
|  | ||||
|       <style jsx> | ||||
|         {` | ||||
|           .Header { | ||||
|           .header { | ||||
|             background-color: var(--color-background); | ||||
|             border-bottom: var(--border-header-footer); | ||||
|             padding: 0.5rem 1rem; | ||||
|             position: fixed; | ||||
|             width: 100%; | ||||
|             top: 0; | ||||
|             left: 0; | ||||
|             right: 0; | ||||
|             z-index: 100; | ||||
|  | ||||
|             height: var(--header-height); | ||||
|           } | ||||
|           .container { | ||||
|             max-width: 1280px; | ||||
|             width: 100%; | ||||
|             margin: auto; | ||||
|           } | ||||
|           .navbar { | ||||
|             display: flex; | ||||
|             flex-flow: row wrap; | ||||
|             align-items: center; | ||||
|             justify-content: space-between; | ||||
|             padding: 0.5rem 1rem; | ||||
|  | ||||
|             border-bottom: var(--border-header-footer); | ||||
|             background-color: var(--color-background); | ||||
|             align-items: center; | ||||
|           } | ||||
|           @media (min-width: 992px) { | ||||
|             .Header { | ||||
|               display: flex; | ||||
|               flex-basis: auto; | ||||
|               flex-flow: row nowrap; | ||||
|               justify-content: flex-start; | ||||
|             } | ||||
|           .navbar-fixed-top { | ||||
|             position: sticky; | ||||
|             top: 0; | ||||
|             z-index: 200; | ||||
|           } | ||||
|           .Header > .container { | ||||
|           .navbar__brand-link { | ||||
|             color: var(--color-text-1); | ||||
|             text-decoration: none; | ||||
|             font-size: 16px; | ||||
|           } | ||||
|           .navbar__brand { | ||||
|             display: flex; | ||||
|             flex-wrap: wrap; | ||||
|             align-items: center; | ||||
|             justify-content: space-between; | ||||
|           } | ||||
|           @media (min-width: 992px) { | ||||
|             .Header > .container { | ||||
|               flex-wrap: nowrap; | ||||
|           .navbar__brand-title { | ||||
|             font-weight: 600; | ||||
|             margin-left: 10px; | ||||
|           } | ||||
|           .navbar__buttons { | ||||
|             display: flex; | ||||
|             justify-content: space-between; | ||||
|           } | ||||
|           @media (max-width: 320px) { | ||||
|             .navbar__brand-title { | ||||
|               display: none; | ||||
|             } | ||||
|           } | ||||
|         `} | ||||
|   | ||||
| @@ -1,14 +1,11 @@ | ||||
| import useTranslation from 'next-translate/useTranslation' | ||||
| import Translation from 'next-translate/Trans' | ||||
|  | ||||
| export const ProfileDescriptionBottom: React.FC = () => { | ||||
|   const { t } = useTranslation() | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <p className='profile-description-bottom'> | ||||
|         <Translation | ||||
|           i18nKey={t('home:about.descriptionBottom')} | ||||
|           i18nKey='home:about.descriptionBottom' | ||||
|           components={[<br key='break' />]} | ||||
|         /> | ||||
|       </p> | ||||
|   | ||||
| @@ -1,50 +0,0 @@ | ||||
| export interface TableRow { | ||||
|   title: string | ||||
|   value: string | ||||
| } | ||||
|  | ||||
| export interface TableProps { | ||||
|   rows: TableRow[] | ||||
| } | ||||
|  | ||||
| export const Table: React.FC<TableProps> = props => { | ||||
|   const { rows } = props | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <div className='col-24 table-column text-center'> | ||||
|         <table> | ||||
|           <tbody> | ||||
|             {rows.map((row, index) => { | ||||
|               return ( | ||||
|                 <tr key={index}> | ||||
|                   <th className='table-row'>{row.title}</th> | ||||
|                   <td className='table-row'>{row.value}</td> | ||||
|                 </tr> | ||||
|               ) | ||||
|             })} | ||||
|           </tbody> | ||||
|         </table> | ||||
|       </div> | ||||
|  | ||||
|       <style jsx>{` | ||||
|         .table-column { | ||||
|           display: grid; | ||||
|         } | ||||
|         .table, | ||||
|         th, | ||||
|         td { | ||||
|           border: 1px solid var(--color-text-1); | ||||
|           border-collapse: collapse; | ||||
|         } | ||||
|         .table-row { | ||||
|           padding: 15px; | ||||
|         } | ||||
|         .image-setup { | ||||
|           width: 85%; | ||||
|         } | ||||
|       `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| export const TableTitle: React.FC = props => { | ||||
|   const { children } = props | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <div className='col-24'> | ||||
|         <p className='text-center title-table'> | ||||
|           <strong className='important'>{children}</strong> | ||||
|         </p> | ||||
|       </div> | ||||
|  | ||||
|       <style jsx>{` | ||||
|         .title-table { | ||||
|           font-size: 24px; | ||||
|           margin: 40px 0 20px 0; | ||||
|         } | ||||
|       `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -1,137 +0,0 @@ | ||||
| import useTranslation from 'next-translate/useTranslation' | ||||
| import Image from 'next/image' | ||||
|  | ||||
| import { Table, TableRow } from './Table' | ||||
| import { TableTitle } from './TableTitle' | ||||
|  | ||||
| export const Setup: React.FC = () => { | ||||
|   const { t } = useTranslation() | ||||
|  | ||||
|   const rowsConfigPC: TableRow[] = [ | ||||
|     { | ||||
|       title: t('setup:configPC.motherboard'), | ||||
|       value: 'MSI Z87-G45 GAMING' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:configPC.processor'), | ||||
|       value: 'Intel Core i5-4690k' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:configPC.graphicCard'), | ||||
|       value: 'Zotac GeForce GTX 970' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:configPC.ramMemory'), | ||||
|       value: '16 GB (2 x 8Go) Kingston HyperX' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:configPC.hardDrive'), | ||||
|       value: '256 GB SSD Crucial & 2 TB Seagate' | ||||
|     } | ||||
|   ] | ||||
|  | ||||
|   const rowsPeripherals: TableRow[] = [ | ||||
|     { | ||||
|       title: t('setup:peripheral.keyboard'), | ||||
|       value: 'Corsair K95 RGB' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:peripheral.mouse'), | ||||
|       value: 'SteelSeries Rival 310' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:peripheral.headset'), | ||||
|       value: 'SteelSeries ARCTIS PRO + GAMEDAC' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:peripheral.mainScreen'), | ||||
|       value: 'IIyama PL2480H' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:peripheral.secondScreen'), | ||||
|       value: 'Samsung SyncMaster 2220LM' | ||||
|     } | ||||
|   ] | ||||
|  | ||||
|   const rowsOffice: TableRow[] = [ | ||||
|     { | ||||
|       title: t('setup:officeOther.mousepad'), | ||||
|       value: 'SteelSeries QCK Heavy (Grand) as string' | ||||
|     }, | ||||
|     { | ||||
|       title: 'Mouse Bungee', | ||||
|       value: 'BenQ ZOWIE Camade' | ||||
|     }, | ||||
|     { | ||||
|       title: t('setup:officeOther.usb'), | ||||
|       value: 'Kingston 128GB' | ||||
|     }, | ||||
|     { | ||||
|       title: 'Smartphone', | ||||
|       value: 'Samsung Galaxy A5 (2017)' | ||||
|     } | ||||
|   ] | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <TableTitle>{t('setup:configPC.title')}</TableTitle> | ||||
|       <Table rows={rowsConfigPC} /> | ||||
|  | ||||
|       <TableTitle>{t('setup:peripheral.title')}</TableTitle> | ||||
|       <Table rows={rowsPeripherals} /> | ||||
|  | ||||
|       <TableTitle>{t('setup:officeOther.title')}</TableTitle> | ||||
|       <Table rows={rowsOffice} /> | ||||
|  | ||||
|       <div | ||||
|         className='row row-padding justify-content-center' | ||||
|         style={{ marginTop: 50 }} | ||||
|       > | ||||
|         <Image | ||||
|           src='/images/setup/setup2019.png' | ||||
|           alt='Setup Divlo' | ||||
|           width={856.8} | ||||
|           height={672.58} | ||||
|           className='Setup__image' | ||||
|         /> | ||||
|       </div> | ||||
|  | ||||
|       <div className='row row-padding justify-content-center'> | ||||
|         <Image | ||||
|           src='/images/setup/setup2019-lights.jpg' | ||||
|           alt='Setup Divlo' | ||||
|           width={856.8} | ||||
|           height={672.58} | ||||
|           className='Setup__image' | ||||
|         /> | ||||
|       </div> | ||||
|  | ||||
|       <div className='row row-padding'> | ||||
|         <TableTitle>{t('setup:connexion')}</TableTitle> | ||||
|         <div style={{ marginBottom: 25 }} className='col-24 text-center'> | ||||
|           <a | ||||
|             href='https://www.speedtest.net/result/8533865940' | ||||
|             target='_blank' | ||||
|             rel='noopener noreferrer' | ||||
|             aria-label='Speedtest link' | ||||
|           > | ||||
|             <Image | ||||
|               src='/images/setup/speedtest-result.png' | ||||
|               alt='Speedtest Result' | ||||
|               width={308} | ||||
|               height={165} | ||||
|             /> | ||||
|           </a> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <style jsx global> | ||||
|         {` | ||||
|           .Setup__image { | ||||
|             width: 85% !important; | ||||
|           } | ||||
|         `} | ||||
|       </style> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -4,7 +4,6 @@ | ||||
|   "pages": { | ||||
|     "*": ["common"], | ||||
|     "/": ["home"], | ||||
|     "/setup": ["setup"], | ||||
|     "/404": ["errors"], | ||||
|     "/500": ["errors"] | ||||
|   } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|       }, | ||||
|       { | ||||
|         "title": "Open-Source enthusiast :", | ||||
|         "description": "For me, everyone should work, solve problems, build things and think together. Long live open source, whenever you can share your work, do it! <br/> The website is open-source on <a href='https://github.com/Divlo/divlo.fr' target='_blank' rel='noopener noreferrer'>github</a>." | ||||
|         "description": "For me, everyone should work, solve problems, build things and think together. Long live open source, whenever you can share your work, do it! <br/> The website is open-source on <a href='https://github.com/Divlo/Divlo' target='_blank' rel='noopener noreferrer'>github</a>." | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   | ||||
| @@ -1,26 +0,0 @@ | ||||
| { | ||||
|   "title": "Setup of Divlo", | ||||
|   "description": "The list of all the computer equipment that Divlo has.", | ||||
|   "configPC": { | ||||
|     "title": "Hardware PC Configuration", | ||||
|     "motherboard": "Motherboard", | ||||
|     "processor": "Processor", | ||||
|     "graphicCard": "Graphic card", | ||||
|     "ramMemory": "Ram Memory", | ||||
|     "hardDrive": "Hard Drive" | ||||
|   }, | ||||
|   "peripheral": { | ||||
|     "title": "Computer Peripheral ", | ||||
|     "keyboard": "Keyboard", | ||||
|     "mouse": "Mouse", | ||||
|     "headset": "Micro Headset", | ||||
|     "mainScreen": "Main Screen", | ||||
|     "secondScreen": "2nd screen" | ||||
|   }, | ||||
|   "officeOther": { | ||||
|     "title": "Office / Other", | ||||
|     "mousepad": "Mousepad", | ||||
|     "usb": "USB Key" | ||||
|   }, | ||||
|   "connexion": "My internet connection" | ||||
| } | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "description": "Développeur Full Stack Junior • Passionné de High-Tech", | ||||
|     "birthDate": "Date de naissance", | ||||
|     "nationality": "Nationalité", | ||||
|     "descriptionBottom": "J'apprends en ligne l'informatique et les langages de programmation pour m'améliorer dans ma passion. <br/> <br/> J'ai conçu ma charte graphique et mon site internet." | ||||
|     "descriptionBottom": "J'apprends en ligne l'informatique et les langages de programmation pour m'améliorer dans ma passion. <0/> <0/> J'ai conçu ma charte graphique et mon site internet." | ||||
|   }, | ||||
|   "interests": { | ||||
|     "title": "Mes intérêts", | ||||
| @@ -19,7 +19,7 @@ | ||||
|       }, | ||||
|       { | ||||
|         "title": "Enthousiaste de l'Open-Source :", | ||||
|         "description": "Pour moi, tout le monde devrait travailler, résoudre des problèmes, construire des choses et réfléchir ensemble. Longue vie à l'open-source, chaque fois que vous pouvez partagez votre travail, faites-le! <br/> Le site est open-source sur <a href='https://github.com/Divlo/divlo.fr' target='_blank' rel='noopener noreferrer'>github</a>." | ||||
|         "description": "Pour moi, tout le monde devrait travailler, résoudre des problèmes, construire des choses et réfléchir ensemble. Longue vie à l'open-source, chaque fois que vous pouvez partagez votre travail, faites-le! <br/> Le site est open-source sur <a href='https://github.com/Divlo/Divlo' target='_blank' rel='noopener noreferrer'>github</a>." | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   | ||||
| @@ -1,26 +0,0 @@ | ||||
| { | ||||
|   "title": "Setup de Divlo", | ||||
|   "description": "La liste de tout le matériel informatique dont dispose Divlo.", | ||||
|   "configPC": { | ||||
|     "title": "Configuration matérielle du PC", | ||||
|     "motherboard": "Carte mère", | ||||
|     "processor": "Processeur", | ||||
|     "graphicCard": "Carte graphique", | ||||
|     "ramMemory": "Mémoires Ram", | ||||
|     "hardDrive": "Disques Dur" | ||||
|   }, | ||||
|   "peripheral": { | ||||
|     "title": "Périphériques", | ||||
|     "keyboard": "Clavier", | ||||
|     "mouse": "Souris", | ||||
|     "headset": "Casque Micro", | ||||
|     "mainScreen": "Écran Principal", | ||||
|     "secondScreen": "2ème écran" | ||||
|   }, | ||||
|   "officeOther": { | ||||
|     "title": "Bureautique / Autre", | ||||
|     "mousepad": "Tapis de souris", | ||||
|     "usb": "Clé USB" | ||||
|   }, | ||||
|   "connexion": "Ma connection internet" | ||||
| } | ||||
							
								
								
									
										26
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -18,7 +18,7 @@ | ||||
|         "classnames": "2.3.1", | ||||
|         "html-react-parser": "1.2.5", | ||||
|         "next": "10.1.3", | ||||
|         "next-pwa": "5.2.10", | ||||
|         "next-pwa": "5.2.12", | ||||
|         "next-translate": "1.0.6", | ||||
|         "nodemailer": "6.5.0", | ||||
|         "normalize.css": "8.0.1", | ||||
| @@ -9802,9 +9802,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/next-pwa": { | ||||
|       "version": "5.2.10", | ||||
|       "resolved": "https://registry.npmjs.org/next-pwa/-/next-pwa-5.2.10.tgz", | ||||
|       "integrity": "sha512-0WIEIEqAy9q5YGA/gYwXVWHStGtoIqJRAZusO3PlRHo3HDr5CWs1RCJ/2faCL/UIyZ9msrUxl0+GR9oxlest0A==", | ||||
|       "version": "5.2.12", | ||||
|       "resolved": "https://registry.npmjs.org/next-pwa/-/next-pwa-5.2.12.tgz", | ||||
|       "integrity": "sha512-MWVpV5sq0eQnJnp79o0DQlMOIpmEoBLpeakKqrAXlhyLLKRF+94UmeLaBLtWvj2yadBGfpa59EbiTTGv+cfySw==", | ||||
|       "dependencies": { | ||||
|         "babel-loader": "^8.2.2", | ||||
|         "clean-webpack-plugin": "^3.0.0", | ||||
| @@ -10623,9 +10623,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/object-inspect": { | ||||
|       "version": "1.10.1", | ||||
|       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.1.tgz", | ||||
|       "integrity": "sha512-WQUIkCSDPWm5ing/PTUkLr2KaOXX2uV/vz1hLGW2XbZ/RDUmtgcsOyEqA1ox0rkyNx9mJX4kxX+YWceje3pmag==", | ||||
|       "version": "1.10.2", | ||||
|       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", | ||||
|       "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", | ||||
|       "funding": { | ||||
|         "url": "https://github.com/sponsors/ljharb" | ||||
|       } | ||||
| @@ -22853,9 +22853,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "next-pwa": { | ||||
|       "version": "5.2.10", | ||||
|       "resolved": "https://registry.npmjs.org/next-pwa/-/next-pwa-5.2.10.tgz", | ||||
|       "integrity": "sha512-0WIEIEqAy9q5YGA/gYwXVWHStGtoIqJRAZusO3PlRHo3HDr5CWs1RCJ/2faCL/UIyZ9msrUxl0+GR9oxlest0A==", | ||||
|       "version": "5.2.12", | ||||
|       "resolved": "https://registry.npmjs.org/next-pwa/-/next-pwa-5.2.12.tgz", | ||||
|       "integrity": "sha512-MWVpV5sq0eQnJnp79o0DQlMOIpmEoBLpeakKqrAXlhyLLKRF+94UmeLaBLtWvj2yadBGfpa59EbiTTGv+cfySw==", | ||||
|       "requires": { | ||||
|         "babel-loader": "^8.2.2", | ||||
|         "clean-webpack-plugin": "^3.0.0", | ||||
| @@ -23421,9 +23421,9 @@ | ||||
|       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" | ||||
|     }, | ||||
|     "object-inspect": { | ||||
|       "version": "1.10.1", | ||||
|       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.1.tgz", | ||||
|       "integrity": "sha512-WQUIkCSDPWm5ing/PTUkLr2KaOXX2uV/vz1hLGW2XbZ/RDUmtgcsOyEqA1ox0rkyNx9mJX4kxX+YWceje3pmag==" | ||||
|       "version": "1.10.2", | ||||
|       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", | ||||
|       "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" | ||||
|     }, | ||||
|     "object-is": { | ||||
|       "version": "1.1.5", | ||||
|   | ||||
| @@ -40,7 +40,7 @@ | ||||
|     "classnames": "2.3.1", | ||||
|     "html-react-parser": "1.2.5", | ||||
|     "next": "10.1.3", | ||||
|     "next-pwa": "5.2.10", | ||||
|     "next-pwa": "5.2.12", | ||||
|     "next-translate": "1.0.6", | ||||
|     "nodemailer": "6.5.0", | ||||
|     "normalize.css": "8.0.1", | ||||
|   | ||||
| @@ -18,14 +18,14 @@ const emailTransporter = nodemailer.createTransport({ | ||||
| }) | ||||
|  | ||||
| export default async ( | ||||
|   req: NextApiRequest, | ||||
|   res: NextApiResponse | ||||
|   request: NextApiRequest, | ||||
|   response: NextApiResponse | ||||
| ): Promise<any> => { | ||||
|   if (req.method !== 'POST') { | ||||
|     return res.redirect('/404') | ||||
|   if (request.method !== 'POST') { | ||||
|     return response.redirect('/404') | ||||
|   } | ||||
|  | ||||
|   let { name, email, subject, message } = req.body as { | ||||
|   let { name, email, subject, message } = request.body as { | ||||
|     name: string | ||||
|     email: string | ||||
|     subject: string | ||||
| @@ -38,11 +38,11 @@ export default async ( | ||||
|     validator.isEmpty(subject) || | ||||
|     validator.isEmpty(message) | ||||
|   ) { | ||||
|     return res.status(400).json({ type: 'requiredFields' }) | ||||
|     return response.status(400).json({ type: 'requiredFields' }) | ||||
|   } | ||||
|  | ||||
|   if (!validator.isEmail(email)) { | ||||
|     return res.status(400).json({ type: 'invalidEmail' }) | ||||
|     return response.status(400).json({ type: 'invalidEmail' }) | ||||
|   } | ||||
|  | ||||
|   email = validator.normalizeEmail(email) as string | ||||
| @@ -62,8 +62,8 @@ export default async ( | ||||
|                 <b>Message:</b> ${message} | ||||
|             ` | ||||
|     }) | ||||
|     return res.status(201).json({ type: 'success' }) | ||||
|     return response.status(201).json({ type: 'success' }) | ||||
|   } catch { | ||||
|     return res.status(500).json({ type: 'serverError' }) | ||||
|     return response.status(500).json({ type: 'serverError' }) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,31 +0,0 @@ | ||||
| import { GetStaticProps } from 'next' | ||||
| import useTranslation from 'next-translate/useTranslation' | ||||
|  | ||||
| import { Section } from 'components/design/Section' | ||||
| import Head from 'components/Head' | ||||
| import { Setup } from 'components/Setup' | ||||
|  | ||||
| const SetupPage: React.FC = () => { | ||||
|   const { t } = useTranslation() | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <Head title={t('setup:title')} description={t('setup:description')} /> | ||||
|  | ||||
|       <Section | ||||
|         id='setup' | ||||
|         style={{ marginTop: 60 }} | ||||
|         description={t('setup:description')} | ||||
|         heading={t('setup:title')} | ||||
|       > | ||||
|         <Setup /> | ||||
|       </Section> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
|  | ||||
| export const getStaticProps: GetStaticProps = async () => { | ||||
|   return { props: {} } | ||||
| } | ||||
|  | ||||
| export default SetupPage | ||||
| Before Width: | Height: | Size: 525 B | 
| Before Width: | Height: | Size: 127 B | 
							
								
								
									
										30
									
								
								public/images/languages/en.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,30 @@ | ||||
| <svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M46 4.6C41.3 1.7 35.9 0 30 0V4.6H46Z" fill="#ED4C5C"/> | ||||
| <path d="M30 9.2H51.6C49.9 7.5 48 5.9 46 4.6H30V9.2Z" fill="white"/> | ||||
| <path d="M30 13.8H55.3C54.2 12.1 53 10.6 51.7 9.2H30V13.8Z" fill="#ED4C5C"/> | ||||
| <path d="M30 18.4H57.7C57 16.8 56.2 15.2 55.3 13.8H30V18.4Z" fill="white"/> | ||||
| <path d="M30 23H59.2C58.8 21.4 58.3 19.9 57.7 18.4H30V23Z" fill="#ED4C5C"/> | ||||
| <path d="M30 27.7H59.9C59.8 26.1 59.5 24.6 59.2 23.1H30V27.7Z" fill="white"/> | ||||
| <path d="M59.9 27.7H30V30H0C0 30.8 -9.68575e-08 31.5 0.0999999 32.3H59.9C60 31.5 60 30.8 60 30C60 29.2 60 28.4 59.9 27.7Z" fill="#ED4C5C"/> | ||||
| <path d="M0.800006 36.9H59.2C59.6 35.4 59.8 33.9 59.9 32.3H0.100006C0.200006 33.8 0.400006 35.4 0.800006 36.9Z" fill="white"/> | ||||
| <path d="M2.3 41.5H57.7C58.3 40 58.8 38.5 59.2 36.9H0.800003C1.2 38.5 1.7 40 2.3 41.5Z" fill="#ED4C5C"/> | ||||
| <path d="M4.7 46.1H55.3C56.2 44.6 57 43.1 57.7 41.5H2.3C3 43.1 3.8 44.6 4.7 46.1Z" fill="white"/> | ||||
| <path d="M8.3 50.7H51.7C53 49.3 54.3 47.7 55.3 46.1H4.7C5.7 47.8 7 49.3 8.3 50.7Z" fill="#ED4C5C"/> | ||||
| <path d="M13.9 55.3H46.1C48.2 54 50 52.4 51.7 50.7H8.3C10 52.5 11.9 54 13.9 55.3Z" fill="white"/> | ||||
| <path d="M30 60C35.9 60 41.4 58.3 46.1 55.3H13.9C18.6 58.3 24.1 60 30 60Z" fill="#ED4C5C"/> | ||||
| <path d="M14 4.6C11.9 5.9 10 7.5 8.3 9.2C6.9 10.6 5.7 12.2 4.7 13.8C3.8 15.3 2.9 16.8 2.3 18.4C1.7 19.9 1.2 21.4 0.8 23C0.4 24.5 0.2 26 0.0999999 27.6C-9.68575e-08 28.4 0 29.2 0 30H30V0C24.1 0 18.7 1.7 14 4.6Z" fill="#428BC1"/> | ||||
| <path d="M23 1L23.5 2.5H25L23.8 3.5L24.2 5L23 4.1L21.8 5L22.2 3.5L21 2.5H22.5L23 1Z" fill="white"/> | ||||
| <path d="M27 7L27.5 8.5H29L27.8 9.5L28.2 11L27 10.1L25.8 11L26.2 9.5L25 8.5H26.5L27 7Z" fill="white"/> | ||||
| <path d="M19 7L19.5 8.5H21L19.8 9.5L20.2 11L19 10.1L17.8 11L18.2 9.5L17 8.5H18.5L19 7Z" fill="white"/> | ||||
| <path d="M23 13L23.5 14.5H25L23.8 15.5L24.2 17L23 16.1L21.8 17L22.2 15.5L21 14.5H22.5L23 13Z" fill="white"/> | ||||
| <path d="M15 13L15.5 14.5H17L15.8 15.5L16.2 17L15 16.1L13.8 17L14.2 15.5L13 14.5H14.5L15 13Z" fill="white"/> | ||||
| <path d="M7 13L7.5 14.5H9L7.8 15.5L8.2 17L7 16.1L5.8 17L6.2 15.5L5 14.5H6.5L7 13Z" fill="white"/> | ||||
| <path d="M27 19L27.5 20.5H29L27.8 21.5L28.2 23L27 22.1L25.8 23L26.2 21.5L25 20.5H26.5L27 19Z" fill="white"/> | ||||
| <path d="M19 19L19.5 20.5H21L19.8 21.5L20.2 23L19 22.1L17.8 23L18.2 21.5L17 20.5H18.5L19 19Z" fill="white"/> | ||||
| <path d="M11 19L11.5 20.5H13L11.8 21.5L12.2 23L11 22.1L9.8 23L10.2 21.5L9 20.5H10.5L11 19Z" fill="white"/> | ||||
| <path d="M23 25L23.5 26.5H25L23.8 27.5L24.2 29L23 28.1L21.8 29L22.2 27.5L21 26.5H22.5L23 25Z" fill="white"/> | ||||
| <path d="M15 25L15.5 26.5H17L15.8 27.5L16.2 29L15 28.1L13.8 29L14.2 27.5L13 26.5H14.5L15 25Z" fill="white"/> | ||||
| <path d="M7 25L7.5 26.5H9L7.8 27.5L8.2 29L7 28.1L5.8 29L6.2 27.5L5 26.5H6.5L7 25Z" fill="white"/> | ||||
| <path d="M9.79999 11L11 10.1L12.2 11L11.7 9.5L12.9 8.5H11.4L11 7L10.5 8.5H9.09999L10.3 9.4L9.79999 11Z" fill="white"/> | ||||
| <path d="M1.79999 23L2.99999 22.1L4.19999 23L3.69999 21.5L4.89999 20.5H3.49999L2.99999 19L2.49999 20.5H1.49999C1.49999 20.6 1.39999 20.7 1.39999 20.8L2.19999 21.4L1.79999 23Z" fill="white"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.0 KiB | 
							
								
								
									
										12
									
								
								public/images/languages/fr.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,12 @@ | ||||
| <svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <g clip-path="url(#clip0)"> | ||||
| <path d="M0 17.5C0 25.1417 4.9 31.6167 11.6667 34.0084V0.991699C4.9 3.38337 0 9.85837 0 17.5Z" fill="#428BC1"/> | ||||
| <path d="M35 17.5C35 9.85837 30.1584 3.38337 23.3334 0.991699V34.0084C30.1584 31.6167 35 25.1417 35 17.5Z" fill="#ED4C5C"/> | ||||
| <path d="M11.6666 34.0083C13.475 34.65 15.4583 35 17.5 35C19.5416 35 21.525 34.65 23.3333 34.0083V0.991667C21.525 0.35 19.6 0 17.5 0C15.4 0 13.475 0.35 11.6666 0.991667V34.0083Z" fill="white"/> | ||||
| </g> | ||||
| <defs> | ||||
| <clipPath id="clip0"> | ||||
| <rect width="35" height="35" fill="white"/> | ||||
| </clipPath> | ||||
| </defs> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 659 B | 
| Before Width: | Height: | Size: 216 KiB | 
| Before Width: | Height: | Size: 651 KiB | 
| Before Width: | Height: | Size: 49 KiB | 
| @@ -4,7 +4,8 @@ | ||||
|   --color-text-1: rgb(222, 222, 222); | ||||
|   --color-text-2: #b2bac2; | ||||
|   --color-background: #181818; | ||||
|   --header-height: 99px; | ||||
|   --color-shadow: rgba(255, 255, 255, 0.2); | ||||
|   --header-height: 79px; | ||||
| } | ||||
| *, | ||||
| *::before, | ||||
|   | ||||