Add data extracts frontend
This commit is contained in:
parent
3494b13dd4
commit
3724d74217
@ -22,6 +22,7 @@ import PrivacyPolicyPage from './privacy-policy';
|
||||
import ContributorAgreementPage from './contributor-agreement';
|
||||
import ForgottenPassword from './forgotten-password';
|
||||
import PasswordReset from './password-reset';
|
||||
import DataExtracts from './data-extracts';
|
||||
|
||||
/**
|
||||
* App component
|
||||
@ -263,6 +264,7 @@ class App extends React.Component<any, any> { // TODO: add proper types
|
||||
</Route>
|
||||
<Route exact path="/privacy-policy.html" component={PrivacyPolicyPage} />
|
||||
<Route exact path="/contributor-agreement.html" component={ContributorAgreementPage} />
|
||||
<Route exact path="/data-extracts.html" component={DataExtracts} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
</main>
|
||||
|
70
app/src/frontend/data-extracts.tsx
Normal file
70
app/src/frontend/data-extracts.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
|
||||
import { dateReviver } from '../helpers';
|
||||
|
||||
interface ExtractViewModel {
|
||||
extract_id: number;
|
||||
extracted_on: Date;
|
||||
download_path: string;
|
||||
}
|
||||
|
||||
interface DataExtractsState {
|
||||
latestExtract: ExtractViewModel;
|
||||
previousExtracts: ExtractViewModel[];
|
||||
}
|
||||
|
||||
export default class DataExtracts extends React.Component<{}, DataExtractsState> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
latestExtract: undefined,
|
||||
previousExtracts: undefined
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const res = await fetch('/api/extracts');
|
||||
const data = JSON.parse(await res.text(), dateReviver);
|
||||
const extracts = (data.extracts as ExtractViewModel[])
|
||||
.sort((a, b) => a.extracted_on.valueOf() - b.extracted_on.valueOf())
|
||||
.reverse();
|
||||
|
||||
|
||||
|
||||
this.setState({ latestExtract: extracts[0], previousExtracts: extracts.slice(1) });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<article>
|
||||
<section className="main-col">
|
||||
<h1 className="h2">Open data extracts</h1>
|
||||
<p>Choose one of the links below to download an archive containing the open data collected on the Colouring London platform</p>
|
||||
{
|
||||
this.state.latestExtract == undefined ?
|
||||
<p>Loading extracts...</p> :
|
||||
<div>
|
||||
<h1 className="h3">Latest extract</h1>
|
||||
<ExtractDownloadLink {...this.state.latestExtract} />
|
||||
</div>
|
||||
}
|
||||
{
|
||||
this.state.previousExtracts && this.state.previousExtracts.length > 0 ?
|
||||
(<div>
|
||||
<h1 className="h3">Older extracts</h1>
|
||||
{this.state.previousExtracts.map(e => <ExtractDownloadLink {...e} />)}
|
||||
</div>) :
|
||||
null
|
||||
}
|
||||
|
||||
</section>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const ExtractDownloadLink: FunctionComponent<ExtractViewModel> = (props) => (
|
||||
<p><a href={props.download_path}>Extracted on {props.extracted_on.toDateString()}</a></p>
|
||||
);
|
6
app/src/helpers.ts
Normal file
6
app/src/helpers.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export function dateReviver(name, value) {
|
||||
if (typeof value === "string" && /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/.test(value)) {
|
||||
return new Date(value);
|
||||
}
|
||||
return value;
|
||||
}
|
Loading…
Reference in New Issue
Block a user