API & Client: refactor (rename mpwo to fittrackee)

This commit is contained in:
Sam
2018-06-07 14:45:43 +02:00
parent 1f36de74ba
commit f65d636f85
81 changed files with 99 additions and 98 deletions

View File

@ -0,0 +1,35 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import { Link } from 'react-router-dom'
export default function AdminMenu () {
return (
<div>
<Helmet>
<title>FitTrackee - Admin - Sports</title>
</Helmet>
<h1 className="page-title">Administration</h1>
<div className="container">
<div className="row">
<div className="col-md-2" />
<div className="col-md-8 card">
<div className="card-body">
<ul className="admin-items">
<li>
<Link
to={{
pathname: '/admin/sports',
}}
>
Sports
</Link>
</li>
</ul>
</div>
</div>
<div className="col-md-2" />
</div>
</div>
</div>
)
}

View File

@ -0,0 +1,39 @@
import React from 'react'
import { connect } from 'react-redux'
import { getData } from '../../../actions'
import AdminDetail from '../generic/AdminDetail'
class AdminSports extends React.Component {
componentDidMount() {
this.props.loadSport(this.props.match.params.sportId)
}
componentWillUnmount() {
// reload all Sports
this.props.loadSport(null)
}
render() {
const { sports } = this.props
return (
<div>
<AdminDetail
results={sports}
target="sports"
/>
</div>
)
}
}
export default connect(
state => ({
sports: state.sports.data,
user: state.user,
}),
dispatch => ({
loadSport: sportId => {
dispatch(getData('sports', { id: sportId }))
},
})
)(AdminSports)

View File

@ -0,0 +1,35 @@
import React from 'react'
import { connect } from 'react-redux'
import { getData } from '../../../actions'
import AdminPage from '../generic/AdminPage'
class AdminSports extends React.Component {
componentDidMount() {
this.props.loadSports()
}
render() {
const { sports } = this.props
return (
<div>
<AdminPage
data={sports}
target="sports"
/>
</div>
)
}
}
export default connect(
state => ({
sports: state.sports,
user: state.user,
}),
dispatch => ({
loadSports: () => {
dispatch(getData('sports'))
},
})
)(AdminSports)

View File

@ -0,0 +1,83 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import { connect } from 'react-redux'
import { addData } from '../../../actions/index'
import { history } from '../../../index'
class AdminSportsAdd extends React.Component {
componentDidMount() { }
render() {
const { message, onAddSport } = this.props
return (
<div>
<Helmet>
<title>FitTrackee - Admin - Add Sport</title>
</Helmet>
<h1 className="page-title">
Administration - Sport
</h1>
{message && (
<code>{message}</code>
)}
<div className="container">
<div className="row">
<div className="col-md-2" />
<div className="col-md-8">
<div className="card">
<div className="card-header">
Add a sport
</div>
<div className="card-body">
<form onSubmit={event =>
event.preventDefault()}
>
<div className="form-group">
<label>
Label:
<input
name="label"
className="form-control input-lg"
type="text"
/>
</label>
</div>
<input
type="submit"
className="btn btn-primary btn-lg btn-block"
onClick={event => onAddSport(event)}
value="Submit"
/>
<input
type="submit"
className="btn btn-secondary btn-lg btn-block"
onClick={() => history.push('/admin/sports')}
value="Cancel"
/>
</form>
</div>
</div>
</div>
<div className="col-md-2" />
</div>
</div>
</div>
)
}
}
export default connect(
state => ({
message: state.message,
user: state.user,
}),
dispatch => ({
onAddSport: e => {
const data = { label: e.target.form.label.value }
dispatch(addData('sports', data))
},
})
)(AdminSportsAdd)

View File

@ -0,0 +1,155 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import { connect } from 'react-redux'
import { deleteData, updateData } from '../../../actions/index'
import { history } from '../../../index'
class AdminDetail extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
isInEdition: false,
}
}
render() {
const {
message,
onDataUpdate,
onDataDelete,
results,
target,
} = this.props
const { isInEdition } = this.state
const title = target.charAt(0).toUpperCase() + target.slice(1)
return (
<div>
<Helmet>
<title>FitTrackee - Admin</title>
</Helmet>
<h1 className="page-title">
Administration - {title}
</h1>
{message ? (
<code>{message}</code>
) : (
results.length === 1 && (
<div className="container">
<div className="row">
<div className="col-md-2" />
<div className="col-md-8 card">
<div className="card-body">
<form onSubmit={event =>
event.preventDefault()}
>
{ Object.keys(results[0])
.filter(key => key.charAt(0) !== '_')
.map(key => (
<div className="form-group" key={key}>
<label>
{key}:
{key === 'img' ? (
<img
src={results[0][key]
? results[0][key]
: '/img/photo.png'}
alt="property"
/>
) : (
<input
className="form-control input-lg"
name={key}
readOnly={key === 'id' || !isInEdition}
defaultValue={results[0][key]}
/>
)}
</label>
</div>
))
}
{isInEdition ? (
<div>
<input
type="submit"
className="btn btn-primary btn-lg btn-block"
onClick={event => {
onDataUpdate(event, target)
this.setState({ isInEdition: false })
}
}
value="Submit"
/>
<input
type="submit"
className="btn btn-secondary btn-lg btn-block"
onClick={event => {
event.target.form.reset()
this.setState({ isInEdition: false })
}}
value="Cancel"
/>
</div>
) : (
<div>
<input
type="submit"
className="btn btn-primary btn-lg btn-block"
onClick={() => this.setState({ isInEdition: true })}
value="Edit"
/>
<input
type="submit"
className="btn btn-danger btn-lg btn-block"
disabled={!results[0]._can_be_deleted}
onClick={event => onDataDelete(event, target)}
title={results[0]._can_be_deleted
? ''
: 'Can\'t be deleted, associated data exist'}
value="Delete"
/>
<input
type="submit"
className="btn btn-secondary btn-lg btn-block"
onClick={() => history.push(`/admin/${target}`)}
value="Back to the list"
/>
</div>
)}
</form>
</div>
</div>
<div className="col-md-2" />
</div>
</div>
)
)}
</div>
)
}
}
export default connect(
state => ({
message: state.message,
}),
dispatch => ({
onDataDelete: (e, target) => {
const id = e.target.form.id.value
dispatch(deleteData(target, id))
},
onDataUpdate: (e, target) => {
const data = [].slice
.call(e.target.form.elements)
.reduce(function(map, obj) {
if (obj.name) {
map[obj.name] = obj.value
}
return map
}, {})
dispatch(updateData(target, data))
},
})
)(AdminDetail)

View File

@ -0,0 +1,97 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import { Link } from 'react-router-dom'
import { history } from '../../../index'
export default function AdminPage(props) {
const { data, target } = props
const { error } = data
const results = data.data
const tbKeys = []
if (results.length > 0) {
Object.keys(results[0])
.filter(key => key.charAt(0) !== '_')
.map(key => tbKeys.push(key))
}
const title = target.charAt(0).toUpperCase() + target.slice(1)
return (
<div>
<Helmet>
<title>FitTrackee - Admin</title>
</Helmet>
<h1 className="page-title">
Administration - {title}
</h1>
{error ? (
<code>{error}</code>
) : (
<div className="container">
<div className="row">
<div className="col-md-2" />
<div className="col-md-8 card">
<div className="card-body">
<table className="table">
<thead>
<tr>
{tbKeys.map(
tbKey => <th key={tbKey} scope="col">{tbKey}</th>
)}
</tr>
</thead>
<tbody>
{ results.map((result, idx) => (
// eslint-disable-next-line react/no-array-index-key
<tr key={idx}>
{ Object.keys(result)
.filter(key => key.charAt(0) !== '_')
.map(key => {
if (key === 'id') {
return (
<th key={key} scope="row">
<Link to={`/admin/${target}/${result[key]}`}>
{result[key]}
</Link>
</th>
)
} else if (key === 'img') {
return (<td key={key}>
<img
className="admin-img"
src={result[key]
? result[key]
: '/img/photo.png'}
alt="logo"
/>
</td>)
}
return <td key={key}>{result[key]}</td>
})
}
</tr>
))}
</tbody>
</table>
<input
type="submit"
className="btn btn-primary btn-lg btn-block"
onClick={() => history.push(`/admin/${target}/add`)}
value="Add a new item"
/>
<input
type="submit"
className="btn btn-secondary btn-lg btn-block"
onClick={() => history.push('/admin/')}
value="Back"
/>
</div>
</div>
<div className="col-md-2" />
</div>
</div>
)}
</div>
)
}

View File

@ -0,0 +1,48 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import { connect } from 'react-redux'
import { Redirect, Route, Switch } from 'react-router-dom'
import AdminMenu from './Sports/AdminMenu'
import AdminSport from './Sports/AdminSport'
import AdminSports from './Sports/AdminSports'
import AdminSportsAdd from './Sports/AdminSportsAdd'
import AccessDenied from './../Others/AccessDenied'
import NotFound from './../Others/NotFound'
import { isLoggedIn } from '../../utils'
function Admin (props) {
const { user } = props
return (
<div>
<Helmet>
<title>FitTrackee - Admin</title>
</Helmet>
{isLoggedIn() ? (
user.isAdmin ? (
<Switch>
<Route exact path="/admin" component={AdminMenu} />
<Route exact path="/admin/sports" component={AdminSports} />
<Route
exact path="/admin/sports/add"
component={AdminSportsAdd}
/>
<Route
exact path="/admin/sports/:sportId"
component={AdminSport}
/>
<Route component={NotFound} />
</Switch>
) : (
<AccessDenied />
)
) : (<Redirect to="/login" />)}
</div>
)
}
export default connect(
state => ({
user: state.user,
})
)(Admin)