2018-09-09 17:22:44 -04:00
|
|
|
import React, { Fragment } from 'react';
|
2019-11-07 02:39:26 -05:00
|
|
|
import { Link, Route, Switch } from 'react-router-dom';
|
2018-09-17 16:27:52 -04:00
|
|
|
|
2019-11-13 14:23:22 -05:00
|
|
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
2019-11-13 14:20:47 -05:00
|
|
|
import './app.css';
|
|
|
|
|
2018-09-09 17:22:44 -04:00
|
|
|
import Header from './header';
|
2019-11-07 02:39:26 -05:00
|
|
|
import MapApp from './map-app';
|
|
|
|
import { Building } from './models/building';
|
|
|
|
import { User } from './models/user';
|
2019-08-14 03:37:27 -04:00
|
|
|
import AboutPage from './pages/about';
|
2019-11-14 10:28:12 -05:00
|
|
|
import ChangesPage from './pages/changes';
|
2019-11-07 02:39:26 -05:00
|
|
|
import ContactPage from './pages/contact';
|
2019-08-14 03:37:27 -04:00
|
|
|
import ContributorAgreementPage from './pages/contributor-agreement';
|
2019-11-07 02:39:26 -05:00
|
|
|
import DataAccuracyPage from './pages/data-accuracy';
|
2019-09-30 11:03:16 -04:00
|
|
|
import DataExtracts from './pages/data-extracts';
|
2019-11-07 02:39:26 -05:00
|
|
|
import OrdnanceSurveyLicencePage from './pages/ordnance-survey-licence';
|
|
|
|
import OrdnanceSurveyUprnPage from './pages/ordnance-survey-uprn';
|
|
|
|
import PrivacyPolicyPage from './pages/privacy-policy';
|
|
|
|
import ForgottenPassword from './user/forgotten-password';
|
2019-08-14 04:02:57 -04:00
|
|
|
import Login from './user/login';
|
|
|
|
import MyAccountPage from './user/my-account';
|
2019-08-23 09:16:40 -04:00
|
|
|
import PasswordReset from './user/password-reset';
|
2019-11-07 02:39:26 -05:00
|
|
|
import SignUp from './user/signup';
|
2019-08-14 04:02:57 -04:00
|
|
|
|
2019-09-08 20:09:05 -04:00
|
|
|
|
|
|
|
interface AppProps {
|
2019-11-05 15:13:10 -05:00
|
|
|
user?: User;
|
|
|
|
building?: Building;
|
2019-09-08 20:09:05 -04:00
|
|
|
building_like?: boolean;
|
2019-10-29 12:56:49 -04:00
|
|
|
revisionId: number;
|
2019-09-08 20:09:05 -04:00
|
|
|
}
|
2019-08-14 03:37:27 -04:00
|
|
|
|
2019-11-05 15:13:10 -05:00
|
|
|
interface AppState {
|
|
|
|
user?: User;
|
|
|
|
}
|
|
|
|
|
2019-02-05 16:41:31 -05:00
|
|
|
/**
|
|
|
|
* App component
|
|
|
|
*
|
|
|
|
* This is the top-level stateful frontend component
|
|
|
|
* - rendered from props, instantiated either server-side in server.js or client-side in
|
|
|
|
* client.js
|
|
|
|
* - state (including user, current building) is initialised from props
|
|
|
|
* - callbacks to update top-level state are passed down to subcomponents
|
|
|
|
* - render method wraps a react-router switch - this drives which version of the sidebar and
|
|
|
|
* map or other pages are rendered, based on the URL. Use a react-router-dom <Link /> in
|
|
|
|
* child components to navigate without a full page reload.
|
|
|
|
*/
|
2019-11-05 15:13:10 -05:00
|
|
|
class App extends React.Component<AppProps, AppState> {
|
2019-10-29 13:58:01 -04:00
|
|
|
static mapAppPaths = ['/', '/:mode(view|edit|multi-edit)/:category/:building(\\d+)?/(history)?'];
|
2019-10-28 12:46:22 -04:00
|
|
|
|
2019-09-08 20:09:05 -04:00
|
|
|
constructor(props: Readonly<AppProps>) {
|
2018-09-09 17:22:44 -04:00
|
|
|
super(props);
|
2019-09-08 20:09:05 -04:00
|
|
|
|
2018-09-10 18:34:56 -04:00
|
|
|
this.state = {
|
2019-09-08 20:09:05 -04:00
|
|
|
user: props.user
|
2018-09-10 18:34:56 -04:00
|
|
|
};
|
2018-09-09 17:22:44 -04:00
|
|
|
this.login = this.login.bind(this);
|
2018-10-20 07:20:10 -04:00
|
|
|
this.updateUser = this.updateUser.bind(this);
|
2018-09-09 17:22:44 -04:00
|
|
|
this.logout = this.logout.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
login(user) {
|
2018-09-30 15:28:33 -04:00
|
|
|
if (user.error) {
|
|
|
|
this.logout();
|
2019-09-08 20:09:05 -04:00
|
|
|
return;
|
2018-09-30 15:28:33 -04:00
|
|
|
}
|
2018-09-09 17:22:44 -04:00
|
|
|
this.setState({user: user});
|
|
|
|
}
|
|
|
|
|
2018-10-20 07:20:10 -04:00
|
|
|
updateUser(user){
|
|
|
|
this.setState({user: { ...this.state.user, ...user }});
|
|
|
|
}
|
|
|
|
|
2018-09-10 18:34:56 -04:00
|
|
|
logout() {
|
2018-09-09 17:22:44 -04:00
|
|
|
this.setState({user: undefined});
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<Fragment>
|
2019-10-28 12:46:22 -04:00
|
|
|
<Switch>
|
|
|
|
<Route exact path={App.mapAppPaths}>
|
|
|
|
<Header user={this.state.user} animateLogo={false} />
|
|
|
|
</Route>
|
|
|
|
<Route>
|
|
|
|
<Header user={this.state.user} animateLogo={true} />
|
|
|
|
</Route>
|
|
|
|
</Switch>
|
2019-08-14 14:33:26 -04:00
|
|
|
<main>
|
|
|
|
<Switch>
|
|
|
|
<Route exact path="/about.html" component={AboutPage} />
|
|
|
|
<Route exact path="/login.html">
|
|
|
|
<Login user={this.state.user} login={this.login} />
|
|
|
|
</Route>
|
|
|
|
<Route exact path="/forgotten-password.html" component={ForgottenPassword} />
|
|
|
|
<Route exact path="/password-reset.html" component={PasswordReset} />
|
|
|
|
<Route exact path="/sign-up.html">
|
|
|
|
<SignUp user={this.state.user} login={this.login} />
|
|
|
|
</Route>
|
|
|
|
<Route exact path="/my-account.html">
|
|
|
|
<MyAccountPage
|
|
|
|
user={this.state.user}
|
|
|
|
updateUser={this.updateUser}
|
|
|
|
logout={this.logout}
|
|
|
|
/>
|
|
|
|
</Route>
|
|
|
|
<Route exact path="/privacy-policy.html" component={PrivacyPolicyPage} />
|
|
|
|
<Route exact path="/contributor-agreement.html" component={ContributorAgreementPage} />
|
2019-10-03 09:55:54 -04:00
|
|
|
<Route exact path="/ordnance-survey-licence.html" component={OrdnanceSurveyLicencePage} />
|
|
|
|
<Route exact path="/ordnance-survey-uprn.html" component={OrdnanceSurveyUprnPage} />
|
2019-10-02 14:26:18 -04:00
|
|
|
<Route exact path="/data-accuracy.html" component={DataAccuracyPage} />
|
2019-09-30 10:06:01 -04:00
|
|
|
<Route exact path="/data-extracts.html" component={DataExtracts} />
|
2019-10-02 13:38:12 -04:00
|
|
|
<Route exact path="/contact.html" component={ContactPage} />
|
2019-11-14 10:28:12 -05:00
|
|
|
<Route exact path="/history.html" component={ChangesPage} />
|
2019-10-28 12:46:22 -04:00
|
|
|
<Route exact path={App.mapAppPaths} render={(props) => (
|
2019-09-08 20:09:05 -04:00
|
|
|
<MapApp
|
|
|
|
{...props}
|
|
|
|
building={this.props.building}
|
|
|
|
building_like={this.props.building_like}
|
|
|
|
user={this.state.user}
|
2019-10-29 12:56:49 -04:00
|
|
|
revisionId={this.props.revisionId}
|
2019-09-08 20:09:05 -04:00
|
|
|
/>
|
|
|
|
)} />
|
2019-08-14 14:33:26 -04:00
|
|
|
<Route component={NotFound} />
|
|
|
|
</Switch>
|
|
|
|
</main>
|
2018-09-09 17:22:44 -04:00
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-02-05 16:41:31 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Component to fall back on in case of 404 or no other match
|
|
|
|
*/
|
2018-09-09 17:22:44 -04:00
|
|
|
const NotFound = () => (
|
|
|
|
<article>
|
|
|
|
<section className="main-col">
|
2018-10-03 16:46:51 -04:00
|
|
|
<h1 className="h1">Page not found</h1>
|
2018-09-13 15:41:42 -04:00
|
|
|
<p className="lead">
|
|
|
|
|
2019-05-27 11:23:58 -04:00
|
|
|
We can’t find that one anywhere.
|
2018-09-13 15:41:42 -04:00
|
|
|
|
|
|
|
</p>
|
|
|
|
<Link className="btn btn-outline-dark" to="/">Back home</Link>
|
2018-09-09 17:22:44 -04:00
|
|
|
</section>
|
|
|
|
</article>
|
|
|
|
);
|
|
|
|
|
|
|
|
export default App;
|