colouring-montreal/app/src/frontend/multi-edit.tsx

133 lines
4.2 KiB
TypeScript
Raw Normal View History

import React, { Fragment } from 'react';
import { Link, Redirect } from 'react-router-dom';
import { parse } from 'query-string';
2019-05-27 15:13:43 -04:00
import PropTypes from 'prop-types';
2019-05-09 04:16:36 -04:00
import Sidebar from './sidebar';
import CONFIG from './fields-config.json';
import InfoBox from './components/info-box';
import { sanitiseURL } from './helpers';
2019-05-09 04:16:36 -04:00
const MultiEdit = (props) => {
if (!props.user){
return <Redirect to="/sign-up.html" />
}
2019-05-10 09:00:20 -04:00
const cat = props.match.params.cat;
if (cat === 'like') {
// special case for likes
return (
<Sidebar
2019-05-27 16:28:47 -04:00
title='Quick edit'
2019-05-27 15:13:43 -04:00
back={`/edit/${cat}.html`}>
<section className='data-section'>
2019-05-27 16:28:47 -04:00
<header className={`section-header view ${cat} active`}>
<a><h3 className="h3">Like me!</h3></a>
</header>
<form className='buttons-container'>
<InfoBox msg='Click all the buildings that you like and think contribute to the city!' />
2019-05-27 15:13:43 -04:00
<Link to='/view/like.html' className='btn btn-secondary'>Back to view</Link>
<Link to='/edit/like.html' className='btn btn-secondary'>Back to edit</Link>
2019-05-27 16:28:47 -04:00
</form>
</section>
</Sidebar>
);
}
2019-05-10 09:00:20 -04:00
const q = parse(props.location.search);
const data = JSON.parse(q.data as string) // TODO: verify what happens when data is string[]
2019-05-27 16:28:47 -04:00
const title = sectionTitleFromCat(cat);
2019-05-09 04:16:36 -04:00
return (
<Sidebar
2019-05-27 15:13:43 -04:00
title='Quick edit'
2019-05-09 04:16:36 -04:00
back={`/edit/${cat}.html`}>
2019-05-27 15:13:43 -04:00
<section className='data-section'>
2019-05-27 16:28:47 -04:00
<header className={`section-header view ${cat} active`}>
<a><h3 className="h3">{title}</h3></a>
</header>
<dl className='data-list'>
{
Object.keys(data).map((key => {
const label = fieldTitleFromSlug(key);
return <DataEntry key={key} label={label} value={data[key]}/>
}))
}
</dl>
2019-05-27 16:28:47 -04:00
<form className='buttons-container'>
<InfoBox msg='Click buildings to colour using the data above' />
2019-05-27 15:13:43 -04:00
<Link to={`/view/${cat}.html`} className='btn btn-secondary'>Back to view</Link>
<Link to={`/edit/${cat}.html`} className='btn btn-secondary'>Back to edit</Link>
2019-05-27 16:28:47 -04:00
</form>
2019-05-09 04:16:36 -04:00
</section>
</Sidebar>
);
}
2019-05-27 15:13:43 -04:00
MultiEdit.propTypes = {
user: PropTypes.object,
match: PropTypes.object,
location: PropTypes.object
}
const DataEntry = (props) => {
let content;
if (props.value != null && props.value !== '') {
if (typeof(props.value) === 'boolean') {
content = (props.value)? 'Yes' : 'No'
} else if (Array.isArray(props.value)) {
if (props.value.length) {
content = <ul>{
props.value.map((item, index) => {
return <li key={index}><a href={sanitiseURL(item)}>{item}</a></li>
})
}</ul>
} else {
content = '\u00A0'
}
} else {
content = props.value
}
} else {
content = '\u00A0'
}
return (
<Fragment>
<dt>{props.label}</dt>
<dd>{content}</dd>
</Fragment>
)
}
2019-05-27 16:28:47 -04:00
function sectionTitleFromCat(cat) {
for (let index = 0; index < CONFIG.length; index++) {
const section = CONFIG[index];
if (section.slug === cat) {
return section.title
}
}
return undefined
}
2019-05-27 15:13:43 -04:00
function fieldTitleFromSlug(slug) {
const fields = CONFIG.reduce(
(prev, section) => {
const el = prev.concat(
section.fields.filter(
(field: any) => field.slug === slug // TODO: remove any
)
)
return el
}, []
)
if (fields.length === 1 && fields[0].title) {
return fields[0].title
} else {
console.error('Expected single match, got', fields)
}
}
2019-05-09 04:16:36 -04:00
export default MultiEdit;