merged
This commit is contained in:
commit
3ae82ecb59
|
@ -10,7 +10,7 @@ import type { CSSOptions } from 'vite'
|
||||||
import defaultGenerateScopedName from 'postcss-modules/build/generateScopedName'
|
import defaultGenerateScopedName from 'postcss-modules/build/generateScopedName'
|
||||||
import { isDev } from './src/utils/config'
|
import { isDev } from './src/utils/config'
|
||||||
|
|
||||||
const PATH_PREFIX = '/src/components/'
|
const PATH_PREFIX = '/src/'
|
||||||
|
|
||||||
const getDevCssClassPrefix = (filename: string): string => {
|
const getDevCssClassPrefix = (filename: string): string => {
|
||||||
return filename
|
return filename
|
||||||
|
|
|
@ -7,12 +7,15 @@ import '../../styles/app.scss'
|
||||||
type Props = {
|
type Props = {
|
||||||
headerTitle?: string
|
headerTitle?: string
|
||||||
children: JSX.Element
|
children: JSX.Element
|
||||||
|
isHeaderFixed?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MainLayout = (props: Props) => {
|
export const MainLayout = (props: Props) => {
|
||||||
|
const isHeaderFixed = props.isHeaderFixed !== undefined ? props.isHeaderFixed : true
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header title={props.headerTitle} />
|
<Header title={props.headerTitle} isHeaderFixed={isHeaderFixed} />
|
||||||
<main class="main-content">{props.children}</main>
|
<main class="main-content">{props.children}</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
header {
|
header {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
margin-bottom: 2.2rem;
|
margin-bottom: 2.2rem;
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
|
@ -15,8 +13,10 @@ header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header--scrolled-bottom,
|
.header--fixed {
|
||||||
.header--scrolled-top {
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
.main-logo {
|
.main-logo {
|
||||||
height: 56px;
|
height: 56px;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { For, Show, createSignal, createMemo, createEffect, onMount, onCleanup, Suspense } from 'solid-js'
|
import { For, Show, createSignal, createMemo, createEffect, onMount, onCleanup } from 'solid-js'
|
||||||
import Private from './Private'
|
import Private from './Private'
|
||||||
import Notifications from './Notifications'
|
import Notifications from './Notifications'
|
||||||
import { Icon } from './Icon'
|
import { Icon } from './Icon'
|
||||||
|
@ -27,6 +27,7 @@ const handleEnterClick = () => {
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title?: string
|
title?: string
|
||||||
|
isHeaderFixed?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Header = (props: Props) => {
|
export const Header = (props: Props) => {
|
||||||
|
@ -82,82 +83,82 @@ export const Header = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
<header
|
||||||
<header
|
class="main-header"
|
||||||
classList={{
|
classList={{
|
||||||
['header--scrolled-top']: !getIsScrollingBottom() && getIsScrolled(),
|
['header--fixed']: props.isHeaderFixed,
|
||||||
['header--scrolled-bottom']: getIsScrollingBottom() && getIsScrolled()
|
['header--scrolled-top']: !getIsScrollingBottom() && getIsScrolled(),
|
||||||
}}
|
['header--scrolled-bottom']: getIsScrollingBottom() && getIsScrolled()
|
||||||
>
|
}}
|
||||||
<Modal name="auth">
|
>
|
||||||
<AuthModal />
|
<Modal name="auth">
|
||||||
</Modal>
|
<AuthModal />
|
||||||
<div class="wide-container">
|
</Modal>
|
||||||
<nav class="row header__inner" classList={{ fixed: fixed() }}>
|
<div class="wide-container">
|
||||||
<div class="main-logo col-auto">
|
<nav class="row header__inner" classList={{ fixed: fixed() }}>
|
||||||
<a href={getPagePath(router, 'home')} onClick={handleClientRouteLinkClick}>
|
<div class="main-logo col-auto">
|
||||||
<img src="/logo.svg" alt={t('Discours')} />
|
<a href={getPagePath(router, 'home')} onClick={handleClientRouteLinkClick}>
|
||||||
</a>
|
<img src="/logo.svg" alt={t('Discours')} />
|
||||||
</div>
|
</a>
|
||||||
<div class="col main-navigation">
|
</div>
|
||||||
<div class="article-header">{props.title}</div>
|
<div class="col main-navigation">
|
||||||
|
<div class="article-header">{props.title}</div>
|
||||||
|
|
||||||
<ul class="col main-navigation text-xl inline-flex" classList={{ fixed: fixed() }}>
|
<ul class="col main-navigation text-xl inline-flex" classList={{ fixed: fixed() }}>
|
||||||
<For each={resources}>
|
<For each={resources}>
|
||||||
{(r) => (
|
{(r) => (
|
||||||
<li classList={{ selected: r.route === getPage().route }}>
|
<li classList={{ selected: r.route === getPage().route }}>
|
||||||
<a href={getPagePath(router, r.route, null)} onClick={handleClientRouteLinkClick}>
|
<a href={getPagePath(router, r.route, null)} onClick={handleClientRouteLinkClick}>
|
||||||
{r.name}
|
{r.name}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
<li class="header__search">
|
<li class="header__search">
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<Icon name="search" />
|
<Icon name="search" />
|
||||||
{t('Search')}
|
{t('Search')}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="usernav">
|
<div class="usernav">
|
||||||
<div class="usercontrol col">
|
<div class="usercontrol col">
|
||||||
<div class="usercontrol__item">
|
<div class="usercontrol__item">
|
||||||
<a href="#auth" onClick={handleBellIconClick}>
|
<a href="#auth" onClick={handleBellIconClick}>
|
||||||
<div>
|
<div>
|
||||||
<Icon name="bell-white" counter={authorized() ? getWarnings().length : 1} />
|
<Icon name="bell-white" counter={authorized() ? getWarnings().length : 1} />
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Show when={visibleWarnings()}>
|
|
||||||
<div class="usercontrol__item notifications">
|
|
||||||
<Notifications />
|
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Show
|
<Show when={visibleWarnings()}>
|
||||||
when={authorized()}
|
<div class="usercontrol__item notifications">
|
||||||
fallback={
|
<Notifications />
|
||||||
<div class="usercontrol__item loginbtn">
|
</div>
|
||||||
<a href="#auth" onClick={handleEnterClick}>
|
</Show>
|
||||||
{t('enter')}
|
|
||||||
</a>
|
<Show
|
||||||
</div>
|
when={authorized()}
|
||||||
}
|
fallback={
|
||||||
>
|
<div class="usercontrol__item loginbtn">
|
||||||
<Private />
|
<a href="#auth" onClick={handleEnterClick}>
|
||||||
</Show>
|
{t('enter')}
|
||||||
</div>
|
</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Private />
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
<div class="burger-container">
|
</div>
|
||||||
<div class="burger" classList={{ fixed: fixed() }} onClick={toggleFixed}>
|
<div class="burger-container">
|
||||||
<div />
|
<div class="burger" classList={{ fixed: fixed() }} onClick={toggleFixed}>
|
||||||
</div>
|
<div />
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
</header>
|
</div>
|
||||||
</Suspense>
|
</header>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin-right: 2.2rem;
|
margin-right: 2.2rem;
|
||||||
|
margin-top: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { MainLayout } from '../Layouts/MainLayout'
|
||||||
|
|
||||||
export const FourOuFourPage = () => {
|
export const FourOuFourPage = () => {
|
||||||
return (
|
return (
|
||||||
<MainLayout>
|
<MainLayout isHeaderFixed={false}>
|
||||||
<FourOuFourView />
|
<FourOuFourView />
|
||||||
</MainLayout>
|
</MainLayout>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,40 +1,41 @@
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { Icon } from '../Nav/Icon'
|
import { Icon } from '../Nav/Icon'
|
||||||
import '../../styles/FourOuFour.scss'
|
import styles from '../../styles/FourOuFour.module.scss'
|
||||||
|
import clsx from 'clsx'
|
||||||
|
|
||||||
export const FourOuFourView = (_props) => {
|
export const FourOuFourView = (_props) => {
|
||||||
return (
|
return (
|
||||||
<div class="error-page-wrapper">
|
<div class={styles.errorPageWrapper}>
|
||||||
<div class="error-page">
|
<div class={styles.errorPage}>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-7 offset-sm-3">
|
<div class="col-md-7 offset-md-3">
|
||||||
<a href="/" class="image-link">
|
<a href="/" class="image-link">
|
||||||
<img class="error-image" src="/error.svg" alt="error" width="auto" height="auto" />
|
<img class={styles.errorImage} src="/error.svg" alt="error" width="auto" height="auto" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-2 col-sm-3 offset-sm-2 error-text-container">
|
<div class={clsx(styles.errorTextContainer, 'col-md-2 col-sm-3 offset-sm-1 offset-md-2')}>
|
||||||
<div class="error-text">
|
<div class={styles.errorText}>
|
||||||
<div>{t('Error')}</div>
|
<div>{t('Error')}</div>
|
||||||
<div class="big">404</div>
|
<div class={styles.big}>404</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 search-form-container">
|
<div class={clsx(styles.searchFormContainer, 'col-sm-5 col-md-4')}>
|
||||||
<div class="error-explain">
|
<div class={styles.errorExplain}>
|
||||||
<p>{t(`You've reached a non-existed page`)}</p>
|
<p>{t(`You've reached a non-existed page`)}</p>
|
||||||
<p>{t('Try to find another way')}:</p>
|
<p>{t('Try to find another way')}:</p>
|
||||||
<form class="errorform pretty-form" action="/search" method="get">
|
<form class={clsx(styles.prettyForm, 'pretty-form')} action="/search" method="get">
|
||||||
<div class="pretty-form__item">
|
<div class={clsx(styles.prettyFormItem, 'pretty-form__item')}>
|
||||||
<input type="text" name="q" placeholder={t('Search')} id="search-field" />
|
<input type="text" name="q" placeholder={t('Search')} id="search-field" />
|
||||||
<label for="search-field">{t('Search')}</label>
|
<label for="search-field">{t('Search')}</label>
|
||||||
<button type="submit" class="search-submit">
|
<button type="submit" class={styles.searchSubmit}>
|
||||||
<Icon name="search" />
|
<Icon name="search" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<p class="text-center">
|
<p class={styles.textCenter}>
|
||||||
<a href="/">{t('Back to mainpage')}</a>
|
<a href="/">{t('Back to mainpage')}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
96
src/styles/FourOuFour.module.scss
Normal file
96
src/styles/FourOuFour.module.scss
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
header {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-logo {
|
||||||
|
height: 80px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding-bottom: 0;
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorPageWrapper {
|
||||||
|
height: 100vh;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorPage {
|
||||||
|
position: relative;
|
||||||
|
top: 35%;
|
||||||
|
transform: translateY(-43%);
|
||||||
|
|
||||||
|
.image-link:hover {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prettyForm {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prettyFormItem input {
|
||||||
|
padding-right: 2.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textCenter {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchSubmit {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 1em;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorImage {
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorText {
|
||||||
|
font-weight: 300;
|
||||||
|
left: 52px;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
position: relative;
|
||||||
|
top: -2.25em;
|
||||||
|
|
||||||
|
@include font-size(3rem);
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
left: 80px;
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.big {
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 4px;
|
||||||
|
|
||||||
|
@include font-size(7rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorExplain {
|
||||||
|
font-size: 16px;
|
||||||
|
position: absolute;
|
||||||
|
top: -3.4em;
|
||||||
|
left: 65px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0 0 0.3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorTextContainer,
|
||||||
|
.searchFormContainer {
|
||||||
|
position: relative;
|
||||||
|
}
|
|
@ -1,70 +0,0 @@
|
||||||
.error-page-wrapper {
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-page {
|
|
||||||
position: relative;
|
|
||||||
top: 35%;
|
|
||||||
transform: translateY(-40%);
|
|
||||||
|
|
||||||
.error-image {
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
width: 85%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-text {
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 28px;
|
|
||||||
left: 80px;
|
|
||||||
position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
top: -2.25em;
|
|
||||||
|
|
||||||
.big {
|
|
||||||
font-weight: 900;
|
|
||||||
letter-spacing: 4px;
|
|
||||||
font-size: 60px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-explain {
|
|
||||||
font-size: 16px;
|
|
||||||
position: absolute;
|
|
||||||
top: -3.4em;
|
|
||||||
left: 65px;
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0 0 0.3em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-link:hover {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-submit {
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 1em;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pretty-form {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pretty-form__item input {
|
|
||||||
padding-right: 2.7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-text-container,
|
|
||||||
.search-form-container {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user