feat: added not-found and error pages

pull/1/head
Antonio De Lucreziis 2 years ago
parent 4e417266c4
commit 478d986a7d

@ -6,24 +6,26 @@ import { ServerContext } from './hooks'
import { UserProvider } from './hooks/useCurrentUser'
import { AdminPage } from './pages/AdminPage'
import { ErrorPage } from './pages/ErrorPage'
import { HomePage } from './pages/HomePage'
import { LoginPage } from './pages/LoginPage'
import { NotFoundPage } from './pages/NotFoundPage'
import { ProblemPage } from './pages/ProblemPage'
import { ProfilePage } from './pages/ProfilePage'
import { ScoresPage } from './pages/ScoresPage'
import { UserPage } from './pages/UserPage'
const Redirect = ({ to }: { to: string }) => {
useEffect(() => {
route(prependBaseUrl(to), true)
}, [])
// const Redirect = ({ to }: { to: string }) => {
// useEffect(() => {
// route(prependBaseUrl(to), true)
// }, [])
return (
<>
Redirecting to <pre>{to}</pre>...
</>
)
}
// return (
// <>
// Redirecting to <pre>{to}</pre>...
// </>
// )
// }
export const App = ({ url }: { url?: string }) => {
// during server side rendering don't prepend the BASE_URL
@ -60,10 +62,13 @@ export const App = ({ url }: { url?: string }) => {
// @ts-ignore
path={pbu('/scores')}
/>
<Redirect
<ErrorPage
// @ts-ignore
path={pbu('/error')}
/>
<NotFoundPage
// @ts-ignore
default
to="/"
/>
</Router>
</UserProvider>

@ -9,7 +9,7 @@ const ROLE_LABEL: Record<UserRole, string> = {
['student']: 'Studente',
}
export const Header = ({ }) => {
export const Header = ({}) => {
const [user] = useCurrentUser()
return (

@ -0,0 +1,32 @@
import { Header } from '../components/Header'
function splitFirst(s: string, sep: string): string[] {
const i = s.indexOf(sep)
if (i === -1) {
return [s, '']
} else {
return [s.substring(0, i), s.substring(i + sep.length)]
}
}
const defaultErrorMessage = <>Purtroppo c'è stato un errore inaspettato</>
export const ErrorPage = ({ url }: { url: string }) => {
const query = Object.fromEntries(
splitFirst(url, '?')[1]
.split('&')
.map(kv => splitFirst(kv, '='))
.map(([k, v]) => [k, decodeURIComponent(v)])
)
return (
<>
<Header />
<main class="page-error">
<div class="title">Errore</div>
<p>{query.message.trim().length > 0 ? query.message : defaultErrorMessage}</p>
</main>
</>
)
}

@ -0,0 +1,12 @@
import { Header } from '../components/Header'
export const NotFoundPage = ({}) => {
return (
<>
<Header />
<main class="page-not-found">
<div class="title">Pagina non trovata!</div>
</main>
</>
)
}

@ -223,7 +223,7 @@ p {
margin: 0;
}
p+p {
p + p {
margin-top: 0.5rem;
}
@ -476,11 +476,11 @@ main.page-scores {
}
&:hover {
&:nth-child(3n + 1)+.cell+.cell::after {
&:nth-child(3n + 1) + .cell + .cell::after {
background: #00000006;
}
&:nth-child(3n + 2)+.cell::after {
&:nth-child(3n + 2) + .cell::after {
background: #00000006;
}
}
@ -529,6 +529,8 @@ header {
background: #fdfdfd;
.logo {
z-index: 1;
font-size: 42px;
font-family: 'Lato';
font-weight: 300;
@ -544,6 +546,8 @@ header {
width: 100%;
height: 100%;
z-index: 0;
.nav-left {
gap: 1rem;
display: flex;
@ -797,8 +801,7 @@ header {
}
// On mobile
@media screen and (max-width: $device-s-width),
(pointer: coarse) {
@media screen and (max-width: $device-s-width), (pointer: coarse) {
main {
padding: 2rem 1rem 6rem;
@ -824,7 +827,8 @@ header {
align-items: center;
gap: 1rem;
.nav-left, .nav-right {
.nav-left,
.nav-right {
left: unset;
right: unset;
position: relative;
@ -832,8 +836,6 @@ header {
flex-direction: column;
}
}
}
.problem {
@ -874,8 +876,7 @@ header {
}
}
@media screen and (max-width: $device-m-width),
(pointer: coarse) {
@media screen and (max-width: $device-m-width), (pointer: coarse) {
.markdown-editor {
grid-template-columns: auto;
grid-template-rows: auto auto;

@ -48,5 +48,13 @@
"npm-run-all": "^4.1.5",
"ts-node": "^10.9.1",
"typescript": "^4.8.4"
},
"prettier": {
"printWidth": 140,
"singleQuote": true,
"quoteProps": "consistent",
"tabWidth": 4,
"semi": false,
"arrowParens": "avoid"
}
}

@ -14,7 +14,7 @@ import { RenderFunction } from './shared/ssr'
// Load ".env"
dotenv.config()
const HTML_ROUTES = ['/', '/login', '/problem/:id', '/u/:uid', '/admin', '/profile', '/scores']
// const HTML_ROUTES = ['/', '/login', '/problem/:id', '/u/:uid', '/admin', '/profile', '/scores']
const config = {
isDevelopment: process.env.MODE === 'development',
@ -26,12 +26,12 @@ if (config.isDevelopment) {
console.log(`[Config] PORT = ${config.port}`)
}
function mountIndexHtmlRoutes(r: Router, serveIndexHtml: Handler) {
for (const route of HTML_ROUTES) {
console.log(`[Server] Mounted index html for "${route}"`)
r.get(route, serveIndexHtml)
}
}
// function mountIndexHtmlRoutes(r: Router, serveIndexHtml: Handler) {
// for (const route of HTML_ROUTES) {
// console.log(`[Server] Mounted index html for "${route}"`)
// r.get(route, serveIndexHtml)
// }
// }
async function createDevRouter() {
const r = express.Router()
@ -42,7 +42,8 @@ async function createDevRouter() {
})
r.use(vite.middlewares)
mountIndexHtmlRoutes(r, async (req, res, next) => {
r.use('*', async (req, res, next) => {
try {
const indexHtml = await fs.readFile(path.resolve('./index.html'), 'utf-8')
const transformedTemplate = await vite.transformIndexHtml(req.originalUrl, indexHtml)
@ -66,10 +67,6 @@ async function createDevRouter() {
}
})
r.use('*', (_req, res) => {
res.redirect('/')
})
return r
}
@ -81,7 +78,9 @@ async function createProductionRouter() {
const r = express.Router()
mountIndexHtmlRoutes(r, async (req, res) => {
r.use('/', express.static('dist/entry-client'))
r.use('*', async (req, res) => {
const transformedTemplate = await fs.readFile(path.resolve('./dist/entry-client/index.html'), 'utf-8')
const { html, metadata } = render(req.originalUrl)
@ -96,12 +95,6 @@ async function createProductionRouter() {
res.send(transformedTemplate.replace('<!-- INJECT META TAGS -->', metaTagsHtml).replace('<!-- SSR OUTLET -->', html))
})
r.use('/', express.static('dist/entry-client'))
r.use('*', (_req, res) => {
res.redirect('/')
})
return r
}

Loading…
Cancel
Save