Admin: sports edition
This commit is contained in:
parent
b89b40a4de
commit
b69a55362d
@ -1,4 +1,6 @@
|
|||||||
from flask import Blueprint, jsonify
|
from flask import Blueprint, jsonify, request
|
||||||
|
from mpwo_api import appLog, db
|
||||||
|
from sqlalchemy import exc
|
||||||
|
|
||||||
from ..users.utils import authenticate
|
from ..users.utils import authenticate
|
||||||
from .models import Activity, Sport
|
from .models import Activity, Sport
|
||||||
@ -10,7 +12,7 @@ activities_blueprint = Blueprint('activities', __name__)
|
|||||||
@authenticate
|
@authenticate
|
||||||
def get_sports(auth_user_id):
|
def get_sports(auth_user_id):
|
||||||
"""Get all sports"""
|
"""Get all sports"""
|
||||||
sports = Sport.query.all()
|
sports = Sport.query.order_by(Sport.id).all()
|
||||||
sports_list = []
|
sports_list = []
|
||||||
for sport in sports:
|
for sport in sports:
|
||||||
sport_object = {
|
sport_object = {
|
||||||
@ -27,6 +29,83 @@ def get_sports(auth_user_id):
|
|||||||
return jsonify(response_object), 200
|
return jsonify(response_object), 200
|
||||||
|
|
||||||
|
|
||||||
|
@activities_blueprint.route('/sports/<int:sport_id>', methods=['GET'])
|
||||||
|
@authenticate
|
||||||
|
def get_sport(auth_user_id, sport_id):
|
||||||
|
"""Get a sport"""
|
||||||
|
sport = Sport.query.filter_by(id=sport_id).first()
|
||||||
|
sports_list = []
|
||||||
|
if sport:
|
||||||
|
sports_list.append({
|
||||||
|
'id': sport.id,
|
||||||
|
'label': sport.label
|
||||||
|
})
|
||||||
|
response_object = {
|
||||||
|
'status': 'success',
|
||||||
|
'data': {
|
||||||
|
'sports': sports_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = 200
|
||||||
|
else:
|
||||||
|
response_object = {
|
||||||
|
'status': 'not found',
|
||||||
|
'data': {
|
||||||
|
'sports': sports_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = 404
|
||||||
|
return jsonify(response_object), code
|
||||||
|
|
||||||
|
|
||||||
|
@activities_blueprint.route('/sports/<int:sport_id>', methods=['PATCH'])
|
||||||
|
@authenticate
|
||||||
|
def update_sport(auth_user_id, sport_id):
|
||||||
|
"""Update a sport"""
|
||||||
|
sport_data = request.get_json()
|
||||||
|
if not sport_data or sport_data.get('label') is None:
|
||||||
|
response_object = {
|
||||||
|
'status': 'error',
|
||||||
|
'message': 'Invalid payload.'
|
||||||
|
}
|
||||||
|
return jsonify(response_object), 400
|
||||||
|
|
||||||
|
sports_list = []
|
||||||
|
try:
|
||||||
|
sport = Sport.query.filter_by(id=sport_id).first()
|
||||||
|
if sport:
|
||||||
|
sport.label = sport_data.get('label')
|
||||||
|
db.session.commit()
|
||||||
|
sports_list.append({
|
||||||
|
'id': sport.id,
|
||||||
|
'label': sport.label
|
||||||
|
})
|
||||||
|
response_object = {
|
||||||
|
'status': 'success',
|
||||||
|
'data': {
|
||||||
|
'sports': sports_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = 200
|
||||||
|
else:
|
||||||
|
response_object = {
|
||||||
|
'status': 'not found',
|
||||||
|
'data': {
|
||||||
|
'sports': sports_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = 404
|
||||||
|
except (exc.IntegrityError, exc.OperationalError, ValueError) as e:
|
||||||
|
db.session.rollback()
|
||||||
|
appLog.error(e)
|
||||||
|
response_object = {
|
||||||
|
'status': 'error',
|
||||||
|
'message': 'Error. Please try again or contact the administrator.'
|
||||||
|
}
|
||||||
|
code = 500
|
||||||
|
return jsonify(response_object), code
|
||||||
|
|
||||||
|
|
||||||
@activities_blueprint.route('/activities', methods=['GET'])
|
@activities_blueprint.route('/activities', methods=['GET'])
|
||||||
@authenticate
|
@authenticate
|
||||||
def get_activities(auth_user_id):
|
def get_activities(auth_user_id):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from mpwo_api.tests.utils import add_activity, add_sport, add_user
|
from mpwo_api.tests.utils import add_activity, add_admin, add_sport, add_user
|
||||||
|
|
||||||
|
|
||||||
def test_get_all_sports(app):
|
def test_get_all_sports(app):
|
||||||
@ -85,3 +85,67 @@ def test_get_all_activities(app):
|
|||||||
assert 2 == data['data']['activities'][1]['sport_id']
|
assert 2 == data['data']['activities'][1]['sport_id']
|
||||||
assert 3600 == data['data']['activities'][0]['duration']
|
assert 3600 == data['data']['activities'][0]['duration']
|
||||||
assert 1024 == data['data']['activities'][1]['duration']
|
assert 1024 == data['data']['activities'][1]['duration']
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_a_sport(app):
|
||||||
|
add_user('test', 'test@test.com', '12345678')
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
client = app.test_client()
|
||||||
|
resp_login = client.post(
|
||||||
|
'/api/auth/login',
|
||||||
|
data=json.dumps(dict(
|
||||||
|
email='test@test.com',
|
||||||
|
password='12345678'
|
||||||
|
)),
|
||||||
|
content_type='application/json'
|
||||||
|
)
|
||||||
|
response = client.get(
|
||||||
|
'/api/sports/1',
|
||||||
|
headers=dict(
|
||||||
|
Authorization='Bearer ' + json.loads(
|
||||||
|
resp_login.data.decode()
|
||||||
|
)['auth_token']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data = json.loads(response.data.decode())
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert 'success' in data['status']
|
||||||
|
|
||||||
|
assert len(data['data']['sports']) == 1
|
||||||
|
assert 'cycling' in data['data']['sports'][0]['label']
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_a_sport(app):
|
||||||
|
add_admin()
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
client = app.test_client()
|
||||||
|
resp_login = client.post(
|
||||||
|
'/api/auth/login',
|
||||||
|
data=json.dumps(dict(
|
||||||
|
email='admin@example.com',
|
||||||
|
password='12345678'
|
||||||
|
)),
|
||||||
|
content_type='application/json'
|
||||||
|
)
|
||||||
|
response = client.patch(
|
||||||
|
'/api/sports/1',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(dict(
|
||||||
|
label='cycling updated'
|
||||||
|
)),
|
||||||
|
headers=dict(
|
||||||
|
Authorization='Bearer ' + json.loads(
|
||||||
|
resp_login.data.decode()
|
||||||
|
)['auth_token']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data = json.loads(response.data.decode())
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert 'success' in data['status']
|
||||||
|
|
||||||
|
assert len(data['data']['sports']) == 1
|
||||||
|
assert 'cycling updated' in data['data']['sports'][0]['label']
|
||||||
|
@ -5,6 +5,18 @@ from mpwo_api.activities.models import Activity, Sport
|
|||||||
from mpwo_api.users.models import User
|
from mpwo_api.users.models import User
|
||||||
|
|
||||||
|
|
||||||
|
def add_admin():
|
||||||
|
admin = User(
|
||||||
|
username="admin",
|
||||||
|
email="admin@example.com",
|
||||||
|
password="12345678"
|
||||||
|
)
|
||||||
|
admin.admin = True
|
||||||
|
db.session.add(admin)
|
||||||
|
db.session.commit()
|
||||||
|
return admin
|
||||||
|
|
||||||
|
|
||||||
def add_user(username, email, password):
|
def add_user(username, email, password):
|
||||||
user = User(username=username, email=email, password=password)
|
user = User(username=username, email=email, password=password)
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
|
@ -7,25 +7,43 @@ export const setData = (target, data) => ({
|
|||||||
target,
|
target,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const setError = (target, error) => ({
|
export const setError = message => ({
|
||||||
type: 'SET_ERROR',
|
type: 'SET_ERROR',
|
||||||
error,
|
message,
|
||||||
target,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export function getData(target) {
|
export function getData(target, id = null) {
|
||||||
return function(dispatch) {
|
return function(dispatch) {
|
||||||
|
if (id !== null && isNaN(id)) {
|
||||||
|
return dispatch(setError(target, `${target}: Incorrect id`))
|
||||||
|
}
|
||||||
return mpwoApi
|
return mpwoApi
|
||||||
.getData(target)
|
.getData(target, id)
|
||||||
.then(ret => {
|
.then(ret => {
|
||||||
if (ret.status === 'success') {
|
if (ret.status === 'success') {
|
||||||
dispatch(setData(target, ret.data))
|
dispatch(setData(target, ret.data))
|
||||||
} else {
|
} else {
|
||||||
dispatch(setError(target, ret.message))
|
dispatch(setError(`${target}: ${ret.status}`))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => dispatch(setError(`${target}: ${error}`)))
|
||||||
throw error
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateData(target, data) {
|
||||||
|
return function(dispatch) {
|
||||||
|
if (isNaN(data.id)) {
|
||||||
|
return dispatch(setError(target, `${target}: Incorrect id`))
|
||||||
|
}
|
||||||
|
return mpwoApi
|
||||||
|
.updateData(target, data)
|
||||||
|
.then(ret => {
|
||||||
|
if (ret.status === 'success') {
|
||||||
|
dispatch(setData(target, ret.data))
|
||||||
|
} else {
|
||||||
|
dispatch(setError(`${target}: ${ret.status}`))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
.catch(error => dispatch(setError(`${target}: ${error}`)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { Helmet } from 'react-helmet'
|
|
||||||
|
|
||||||
|
|
||||||
export default function AdminPage(props) {
|
|
||||||
|
|
||||||
const { target, data } = props
|
|
||||||
const error = data.error
|
|
||||||
const results = data.data
|
|
||||||
const tbKeys = []
|
|
||||||
if (results.length > 0) {
|
|
||||||
Object.keys(results[0]).map(key => tbKeys.push(key))
|
|
||||||
}
|
|
||||||
const title = target.charAt(0).toUpperCase() + target.slice(1)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Helmet>
|
|
||||||
<title>mpwo - Admin</title>
|
|
||||||
</Helmet>
|
|
||||||
{error && (
|
|
||||||
<code>{error}</code>
|
|
||||||
)}
|
|
||||||
<h1 className="page-title">
|
|
||||||
Administration - {title}
|
|
||||||
</h1>
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-2" />
|
|
||||||
<div className="col-md-8 card">
|
|
||||||
|
|
||||||
<table className="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
{tbKeys.map(
|
|
||||||
tbKey => <th key={tbKey} scope="col">{tbKey}</th>
|
|
||||||
)}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{ results.map((result, idx) => (
|
|
||||||
<tr key={idx}>
|
|
||||||
{ Object.keys(result).map(key => {
|
|
||||||
if (key === 'id') {
|
|
||||||
return <th key={key} scope="row">{result[key]}</th>
|
|
||||||
}
|
|
||||||
return <td key={key}>{result[key]}</td>
|
|
||||||
}) }
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-2" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
37
mpwo_client/src/components/Admin/AdminSport.jsx
Normal file
37
mpwo_client/src/components/Admin/AdminSport.jsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import { getData } from '../../actions/index'
|
||||||
|
import AdminDetail from './generic/AdminDetail'
|
||||||
|
|
||||||
|
class AdminSports extends React.Component {
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.loadSport(
|
||||||
|
this.props.location.pathname.replace('/admin/sport/', '')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
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', sportId))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)(AdminSports)
|
@ -2,18 +2,20 @@ import React from 'react'
|
|||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
import { getData } from '../../actions/index'
|
import { getData } from '../../actions/index'
|
||||||
import AdminPage from './AdminPage'
|
import AdminPage from './generic/AdminPage'
|
||||||
|
|
||||||
class AdminSports extends React.Component {
|
class AdminSports extends React.Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.loadSport()
|
this.props.loadSports()
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const { sports } = this.props
|
const { sports } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AdminPage
|
<AdminPage
|
||||||
data={sports}
|
data={sports}
|
||||||
|
detailLink="sport"
|
||||||
target="sports"
|
target="sports"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +29,7 @@ export default connect(
|
|||||||
user: state.user,
|
user: state.user,
|
||||||
}),
|
}),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
loadSport: () => {
|
loadSports: () => {
|
||||||
dispatch(getData('sports'))
|
dispatch(getData('sports'))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
130
mpwo_client/src/components/Admin/generic/AdminDetail.jsx
Normal file
130
mpwo_client/src/components/Admin/generic/AdminDetail.jsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Helmet } from 'react-helmet'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
import { updateData } from '../../../actions/index'
|
||||||
|
|
||||||
|
class AdminDetail extends React.Component {
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
this.state = {
|
||||||
|
isInEdition: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
message,
|
||||||
|
onDataUpdate,
|
||||||
|
results,
|
||||||
|
target,
|
||||||
|
} = this.props
|
||||||
|
const { isInEdition } = this.state
|
||||||
|
const title = target.charAt(0).toUpperCase() + target.slice(1)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Helmet>
|
||||||
|
<title>mpwo - 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()}
|
||||||
|
>
|
||||||
|
{ results.map(result => (
|
||||||
|
Object.keys(result).map(key => (
|
||||||
|
<div className="form-group" key={key}>
|
||||||
|
<label>
|
||||||
|
{key}:
|
||||||
|
<input
|
||||||
|
className="form-control input-lg"
|
||||||
|
name={key}
|
||||||
|
readOnly={key === 'id' || !isInEdition}
|
||||||
|
defaultValue={result[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"
|
||||||
|
value="Delete"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
<Link to={`/admin/${target}`}>Back to the list</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
state => ({
|
||||||
|
message: state.message,
|
||||||
|
}),
|
||||||
|
dispatch => ({
|
||||||
|
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)
|
67
mpwo_client/src/components/Admin/generic/AdminPage.jsx
Normal file
67
mpwo_client/src/components/Admin/generic/AdminPage.jsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Helmet } from 'react-helmet'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
export default function AdminPage(props) {
|
||||||
|
|
||||||
|
const { data, detailLink, target } = props
|
||||||
|
const { error } = data
|
||||||
|
const results = data.data
|
||||||
|
const tbKeys = []
|
||||||
|
if (results.length > 0) {
|
||||||
|
Object.keys(results[0]).map(key => tbKeys.push(key))
|
||||||
|
}
|
||||||
|
const title = target.charAt(0).toUpperCase() + target.slice(1)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Helmet>
|
||||||
|
<title>mpwo - 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">
|
||||||
|
<table className="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{tbKeys.map(
|
||||||
|
tbKey => <th key={tbKey} scope="col">{tbKey}</th>
|
||||||
|
)}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{ results.map((result, idx) => (
|
||||||
|
<tr key={idx}>
|
||||||
|
{ Object.keys(result).map(key => {
|
||||||
|
if (key === 'id') {
|
||||||
|
return (
|
||||||
|
<th key={key} scope="row">
|
||||||
|
<Link to={`/admin/${detailLink}/${result[key]}`}>
|
||||||
|
{result[key]}
|
||||||
|
</Link>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return <td key={key}>{result[key]}</td>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -4,6 +4,7 @@ import { connect } from 'react-redux'
|
|||||||
import { Redirect, Route, Switch } from 'react-router-dom'
|
import { Redirect, Route, Switch } from 'react-router-dom'
|
||||||
|
|
||||||
import AdminMenu from './AdminMenu'
|
import AdminMenu from './AdminMenu'
|
||||||
|
import AdminSport from './AdminSport'
|
||||||
import AdminSports from './AdminSports'
|
import AdminSports from './AdminSports'
|
||||||
import AccessDenied from './../Others/AccessDenied'
|
import AccessDenied from './../Others/AccessDenied'
|
||||||
import NotFound from './../Others/NotFound'
|
import NotFound from './../Others/NotFound'
|
||||||
@ -22,7 +23,8 @@ class Admin extends React.Component {
|
|||||||
user.isAdmin ? (
|
user.isAdmin ? (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/admin" component={AdminMenu} />
|
<Route exact path="/admin" component={AdminMenu} />
|
||||||
<Route path="/admin/sports" component={AdminSports} />
|
<Route exact path="/admin/sports" component={AdminSports} />
|
||||||
|
<Route path="/admin/sport" component={AdminSport} />
|
||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
</Switch>
|
</Switch>
|
||||||
) : (
|
) : (
|
||||||
|
@ -2,8 +2,8 @@ import { apiUrl } from '../utils'
|
|||||||
|
|
||||||
export default class MpwoApi {
|
export default class MpwoApi {
|
||||||
|
|
||||||
static getData(target) {
|
static getData(target, id = null) {
|
||||||
const request = new Request(`${apiUrl}${target}`, {
|
const request = new Request(`${apiUrl}${target}${id ? `/${id}` : ''}`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@ -14,4 +14,18 @@ export default class MpwoApi {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.catch(error => error)
|
.catch(error => error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static updateData(target, data) {
|
||||||
|
const request = new Request(`${apiUrl}${target}/${data.id}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: new Headers({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${window.localStorage.getItem('authToken')}`,
|
||||||
|
}),
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
return fetch(request)
|
||||||
|
.then(response => response.json())
|
||||||
|
.catch(error => error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,6 @@ const handleDataAndError = (state, type, action) => {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
data: action.data[action.target],
|
data: action.data[action.target],
|
||||||
error: null,
|
|
||||||
}
|
|
||||||
case 'SET_ERROR':
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
data: { ...initial[type].data },
|
|
||||||
error: action.error,
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
@ -76,9 +69,11 @@ const message = (state = initial.message, action) => {
|
|||||||
case 'PROFILE_ERROR':
|
case 'PROFILE_ERROR':
|
||||||
case 'PROFILE_UPDATE_ERROR':
|
case 'PROFILE_UPDATE_ERROR':
|
||||||
case 'PICTURE_ERROR':
|
case 'PICTURE_ERROR':
|
||||||
|
case 'SET_ERROR':
|
||||||
return action.message
|
return action.message
|
||||||
case 'LOGOUT':
|
case 'LOGOUT':
|
||||||
case 'PROFILE_SUCCESS':
|
case 'PROFILE_SUCCESS':
|
||||||
|
case 'SET_RESULTS':
|
||||||
case '@@router/LOCATION_CHANGE':
|
case '@@router/LOCATION_CHANGE':
|
||||||
return ''
|
return ''
|
||||||
default:
|
default:
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
const emptyData = {
|
const emptyData = {
|
||||||
data: [],
|
data: [],
|
||||||
error: null,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
Loading…
Reference in New Issue
Block a user