added redirector component (#199)

* added redirector component
    * it will redirect every request to /$something that is not handled otherwise (/intro, /login and such) to /n/$something
* added getNote API Call
* added NotFound component
* added LandingLayout around the NotFound component, so users can easily navigate away from the component

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2020-06-13 00:29:39 +02:00 committed by GitHub
parent 773fc60f07
commit c679f5524c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 0 deletions

14
public/api/v2/notes/old Normal file
View file

@ -0,0 +1,14 @@
{
"id": "ABC123",
"alias": "old",
"lastChange": {
"userId": "snskxnksnxksnxksnx",
"username": "testy",
"timestamp": 123456789
},
"viewcount": 0,
"createtime": "2020-05-22T20:46:08.962Z",
"content": "test123",
"authorship": [],
"preVersionTwoNote": true
}

View file

@ -1,6 +1,29 @@
import { expectResponseCode, getBackendUrl } from '../utils/apiUtils'
import { defaultFetchConfig } from './default'
interface LastChange {
userId: string
username: string
timestamp: number
}
export interface Note {
id: string
alias: string
lastChange: LastChange
viewcount: number
createtime: string
content: string
authorship: number[]
preVersionTwoNote: boolean
}
export const getNote = async (noteId: string): Promise<Note> => {
const response = await fetch(getBackendUrl() + `/notes/${noteId}`)
expectResponseCode(response)
return await response.json() as Promise<Note>
}
export const deleteNote = async (noteId: string): Promise<void> => {
const response = await fetch(getBackendUrl() + `/notes/${noteId}`, {
...defaultFetchConfig,

View file

@ -0,0 +1,12 @@
import React from 'react'
import { LandingLayout } from '../landing/landing-layout'
export const NotFound: React.FC = () => {
return (
<LandingLayout>
<div className='text-white d-flex align-items-center justify-content-center my-5'>
<h1>404 Not Found <small>oops.</small></h1>
</div>
</LandingLayout>
)
}

View file

@ -0,0 +1,28 @@
import React, { useEffect, useState } from 'react'
import { Redirect } from 'react-router'
import { useParams } from 'react-router-dom'
import { getNote } from '../../api/note'
import { NotFound } from '../error/not-found'
interface RouteParameters {
id: string
}
export const Redirector: React.FC = () => {
const { id } = useParams<RouteParameters>()
const [error, setError] = useState<boolean | null>(null)
useEffect(() => {
getNote(id)
.then((noteFromAPI) => setError(!noteFromAPI.preVersionTwoNote))
.catch(() => setError(true))
}, [id])
if (error) {
return (<NotFound/>)
} else if (!error && error != null) {
return (<Redirect to={`/n/${id}`}/>)
} else {
return (<span>Loading</span>)
}
}

View file

@ -4,6 +4,7 @@ import { Provider } from 'react-redux'
import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom'
import { ApplicationLoader } from './components/application-loader/application-loader'
import { Editor } from './components/editor/editor'
import { NotFound } from './components/error/not-found'
import { LandingLayout } from './components/landing/landing-layout'
import { History } from './components/landing/pages/history/history'
import { Intro } from './components/landing/pages/intro/intro'
@ -12,6 +13,7 @@ import { Profile } from './components/landing/pages/profile/profile'
import './global-style/index.scss'
import * as serviceWorker from './service-worker'
import { store } from './utils/store'
import { Redirector } from './components/redirector/redirector'
ReactDOM.render(
<Provider store={store}>
@ -41,9 +43,15 @@ ReactDOM.render(
<Route path="/n/:id">
<Editor/>
</Route>
<Route path="/:id">
<Redirector/>
</Route>
<Route path="/">
<Redirect to="/intro"/>
</Route>
<Route>
<NotFound/>
</Route>
</Switch>
</ApplicationLoader>
</Router>