refactor - use of PureComponents to avoid useless re-rendering
This commit is contained in:
parent
3fdbca0404
commit
18df5b994a
@ -320,7 +320,7 @@
|
|||||||
"react/no-unknown-property": "error",
|
"react/no-unknown-property": "error",
|
||||||
"react/no-unused-prop-types": "off",
|
"react/no-unused-prop-types": "off",
|
||||||
"react/prefer-es6-class": "error",
|
"react/prefer-es6-class": "error",
|
||||||
"react/prefer-stateless-function": "error",
|
"react/prefer-stateless-function": [1, { "ignorePureComponents": true }],
|
||||||
"react/prop-types": "off",
|
"react/prop-types": "off",
|
||||||
"react/react-in-jsx-scope": "error",
|
"react/react-in-jsx-scope": "error",
|
||||||
"react/react-default-props": "off",
|
"react/react-default-props": "off",
|
||||||
|
@ -1,176 +1,178 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
export default function ActivitiesList (props) {
|
export default class ActivitiesFilter extends React.PureComponent {
|
||||||
const { loadActivities, sports, updateParams } = props
|
render() {
|
||||||
return (
|
const { loadActivities, sports, updateParams } = this.props
|
||||||
<div className="card">
|
return (
|
||||||
<div className="card-body activity-filter">
|
<div className="card">
|
||||||
<form onSubmit={event => event.preventDefault()}>
|
<div className="card-body activity-filter">
|
||||||
<div className="form-group">
|
<form onSubmit={event => event.preventDefault()}>
|
||||||
<label>
|
<div className="form-group">
|
||||||
From:
|
<label>
|
||||||
<input
|
From:
|
||||||
className="form-control col-md"
|
<input
|
||||||
name="from"
|
className="form-control col-md"
|
||||||
onChange={e => updateParams(e)}
|
name="from"
|
||||||
type="date"
|
onChange={e => updateParams(e)}
|
||||||
/>
|
type="date"
|
||||||
</label>
|
/>
|
||||||
<label>
|
</label>
|
||||||
To:
|
<label>
|
||||||
<input
|
To:
|
||||||
className="form-control col-md"
|
<input
|
||||||
name="to"
|
className="form-control col-md"
|
||||||
onChange={e => updateParams(e)}
|
name="to"
|
||||||
type="date"
|
onChange={e => updateParams(e)}
|
||||||
/>
|
type="date"
|
||||||
</label>
|
/>
|
||||||
</div>
|
</label>
|
||||||
<div className="form-group">
|
</div>
|
||||||
<label>
|
<div className="form-group">
|
||||||
Sport:
|
<label>
|
||||||
<select
|
Sport:
|
||||||
className="form-control input-lg"
|
<select
|
||||||
name="sport_id"
|
className="form-control input-lg"
|
||||||
onChange={e => updateParams(e)}
|
name="sport_id"
|
||||||
>
|
onChange={e => updateParams(e)}
|
||||||
<option value="" />
|
>
|
||||||
{sports.map(sport => (
|
<option value="" />
|
||||||
<option key={sport.id} value={sport.id}>
|
{sports.map(sport => (
|
||||||
{sport.label}
|
<option key={sport.id} value={sport.id}>
|
||||||
</option>
|
{sport.label}
|
||||||
))}
|
</option>
|
||||||
</select>
|
))}
|
||||||
</label>
|
</select>
|
||||||
</div>
|
</label>
|
||||||
<div className="form-group">
|
</div>
|
||||||
<label>
|
<div className="form-group">
|
||||||
Distance (km):
|
<label>
|
||||||
<div className="container">
|
Distance (km):
|
||||||
<div className="row">
|
<div className="container">
|
||||||
<div className="col-5">
|
<div className="row">
|
||||||
<input
|
<div className="col-5">
|
||||||
className="form-control"
|
<input
|
||||||
min={0}
|
className="form-control"
|
||||||
name="distance_from"
|
min={0}
|
||||||
onChange={e => updateParams(e)}
|
name="distance_from"
|
||||||
step="1"
|
onChange={e => updateParams(e)}
|
||||||
type="number"
|
step="1"
|
||||||
/>
|
type="number"
|
||||||
</div>
|
/>
|
||||||
<div className="col-2 align-middle text-center">to</div>
|
</div>
|
||||||
<div className="col-5">
|
<div className="col-2 align-middle text-center">to</div>
|
||||||
<input
|
<div className="col-5">
|
||||||
className="form-control"
|
<input
|
||||||
min={0}
|
className="form-control"
|
||||||
name="distance_to"
|
min={0}
|
||||||
onChange={e => updateParams(e)}
|
name="distance_to"
|
||||||
step="1"
|
onChange={e => updateParams(e)}
|
||||||
type="number"
|
step="1"
|
||||||
/>
|
type="number"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</label>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
<div className="form-group">
|
||||||
<div className="form-group">
|
<label>
|
||||||
<label>
|
Duration:
|
||||||
Duration:
|
<div className="container">
|
||||||
<div className="container">
|
<div className="row">
|
||||||
<div className="row">
|
<div className="col-5">
|
||||||
<div className="col-5">
|
<input
|
||||||
<input
|
className="form-control"
|
||||||
className="form-control"
|
name="duration_from"
|
||||||
name="duration_from"
|
onChange={e => updateParams(e)}
|
||||||
onChange={e => updateParams(e)}
|
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
||||||
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
placeholder="hh:mm"
|
||||||
placeholder="hh:mm"
|
type="text"
|
||||||
type="text"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
<div className="col-2 align-middle text-center">to</div>
|
||||||
<div className="col-2 align-middle text-center">to</div>
|
<div className="col-5">
|
||||||
<div className="col-5">
|
<input
|
||||||
<input
|
className="form-control"
|
||||||
className="form-control"
|
name="duration_to"
|
||||||
name="duration_to"
|
onChange={e => updateParams(e)}
|
||||||
onChange={e => updateParams(e)}
|
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
||||||
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
placeholder="hh:mm"
|
||||||
placeholder="hh:mm"
|
type="text"
|
||||||
type="text"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</label>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
<div className="form-group">
|
||||||
<div className="form-group">
|
<label>
|
||||||
<label>
|
Average speed (km/h):
|
||||||
Average speed (km/h):
|
<div className="container">
|
||||||
<div className="container">
|
<div className="row">
|
||||||
<div className="row">
|
<div className="col-5">
|
||||||
<div className="col-5">
|
<input
|
||||||
<input
|
className="form-control"
|
||||||
className="form-control"
|
min={0}
|
||||||
min={0}
|
name="ave_speed_from"
|
||||||
name="ave_speed_from"
|
onChange={e => updateParams(e)}
|
||||||
onChange={e => updateParams(e)}
|
step="1"
|
||||||
step="1"
|
type="number"
|
||||||
type="number"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
<div className="col-2 align-middle text-center">to</div>
|
||||||
<div className="col-2 align-middle text-center">to</div>
|
<div className="col-5">
|
||||||
<div className="col-5">
|
<input
|
||||||
<input
|
className="form-control"
|
||||||
className="form-control"
|
min={0}
|
||||||
min={0}
|
name="ave_speed_to"
|
||||||
name="ave_speed_to"
|
onChange={e => updateParams(e)}
|
||||||
onChange={e => updateParams(e)}
|
step="1"
|
||||||
step="1"
|
type="number"
|
||||||
type="number"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</label>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
<div className="form-group">
|
||||||
<div className="form-group">
|
<label>
|
||||||
<label>
|
Max speed (km/h):
|
||||||
Max speed (km/h):
|
<div className="container">
|
||||||
<div className="container">
|
<div className="row">
|
||||||
<div className="row">
|
<div className="col-5">
|
||||||
<div className="col-5">
|
<input
|
||||||
<input
|
className="form-control"
|
||||||
className="form-control"
|
min={0}
|
||||||
min={0}
|
name="max_speed_from"
|
||||||
name="max_speed_from"
|
onChange={e => updateParams(e)}
|
||||||
onChange={e => updateParams(e)}
|
step="1"
|
||||||
step="1"
|
type="number"
|
||||||
type="number"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
<div className="col-2 align-middle text-center">to</div>
|
||||||
<div className="col-2 align-middle text-center">to</div>
|
<div className="col-5">
|
||||||
<div className="col-5">
|
<input
|
||||||
<input
|
className="form-control"
|
||||||
className="form-control"
|
min={0}
|
||||||
min={0}
|
name="max_speed_to"
|
||||||
name="max_speed_to"
|
onChange={e => updateParams(e)}
|
||||||
onChange={e => updateParams(e)}
|
step="1"
|
||||||
step="1"
|
type="number"
|
||||||
type="number"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</label>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
<input
|
||||||
<input
|
className="btn btn-primary btn-lg btn-block"
|
||||||
className="btn btn-primary btn-lg btn-block"
|
onClick={() => loadActivities()}
|
||||||
onClick={() => loadActivities()}
|
type="submit"
|
||||||
type="submit"
|
value="Filter"
|
||||||
value="Filter"
|
/>
|
||||||
/>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,14 @@ import { Link } from 'react-router-dom'
|
|||||||
|
|
||||||
import { getDateWithTZ } from '../../utils'
|
import { getDateWithTZ } from '../../utils'
|
||||||
|
|
||||||
export default function ActivitiesList (props) {
|
export default class ActivitiesList extends React.PureComponent {
|
||||||
const { activities, sports, user } = props
|
render() {
|
||||||
return (
|
const { activities, sports, user } = this.props
|
||||||
<div className="card activity-card">
|
return (
|
||||||
<div className="card-body">
|
<div className="card activity-card">
|
||||||
<table className="table">
|
<div className="card-body">
|
||||||
<thead>
|
<table className="table">
|
||||||
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
<th scope="col">Workout</th>
|
<th scope="col">Workout</th>
|
||||||
@ -20,12 +21,12 @@ export default function ActivitiesList (props) {
|
|||||||
<th scope="col">Ave. speed</th>
|
<th scope="col">Ave. speed</th>
|
||||||
<th scope="col">Max. speed</th>
|
<th scope="col">Max. speed</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{ sports && activities.map((activity, idx) => (
|
{sports && activities.map((activity, idx) => (
|
||||||
// eslint-disable-next-line react/no-array-index-key
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
<tr key={idx}>
|
<tr key={idx}>
|
||||||
<td >
|
<td>
|
||||||
<img
|
<img
|
||||||
className="activity-sport"
|
className="activity-sport"
|
||||||
src={sports
|
src={sports
|
||||||
@ -34,11 +35,11 @@ export default function ActivitiesList (props) {
|
|||||||
alt="activity sport logo"
|
alt="activity sport logo"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td >
|
<td>
|
||||||
<Link to={`/activities/${activity.id}`}>
|
<Link to={`/activities/${activity.id}`}>
|
||||||
{activity.title}
|
{activity.title}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{format(
|
{format(
|
||||||
getDateWithTZ(activity.activity_date, user.timezone),
|
getDateWithTZ(activity.activity_date, user.timezone),
|
||||||
@ -53,9 +54,10 @@ export default function ActivitiesList (props) {
|
|||||||
<td className="text-right">{activity.max_speed} km/h</td>
|
<td className="text-right">{activity.max_speed} km/h</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,136 +4,141 @@ import { Link } from 'react-router-dom'
|
|||||||
|
|
||||||
import { apiUrl } from '../../utils'
|
import { apiUrl } from '../../utils'
|
||||||
|
|
||||||
|
class NavBar extends React.PureComponent {
|
||||||
function NavBar(props) {
|
render() {
|
||||||
return (
|
const { user } = this.props
|
||||||
<header>
|
return (
|
||||||
<nav className="navbar navbar-expand-lg navbar-light bg-light">
|
<header>
|
||||||
<div className="container">
|
<nav className="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
<span className="navbar-brand">FitTrackee</span>
|
<div className="container">
|
||||||
<button
|
<span className="navbar-brand">FitTrackee</span>
|
||||||
className="navbar-toggler"
|
<button
|
||||||
type="button"
|
className="navbar-toggler"
|
||||||
data-toggle="collapse"
|
type="button"
|
||||||
data-target="#navbarSupportedContent"
|
data-toggle="collapse"
|
||||||
aria-controls="navbarSupportedContent"
|
data-target="#navbarSupportedContent"
|
||||||
aria-expanded="false"
|
aria-controls="navbarSupportedContent"
|
||||||
aria-label="Toggle navigation"
|
aria-expanded="false"
|
||||||
>
|
aria-label="Toggle navigation"
|
||||||
<span className="navbar-toggler-icon" />
|
>
|
||||||
</button>
|
<span className="navbar-toggler-icon" />
|
||||||
<div className="collapse navbar-collapse" id="navbarSupportedContent">
|
</button>
|
||||||
<ul className="navbar-nav mr-auto">
|
<div
|
||||||
<li className="nav-item">
|
className="collapse navbar-collapse"
|
||||||
<Link
|
id="navbarSupportedContent"
|
||||||
className="nav-link"
|
>
|
||||||
to={{
|
<ul className="navbar-nav mr-auto">
|
||||||
pathname: '/',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Dashboard
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
{props.user.isAuthenticated && (
|
|
||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<Link
|
<Link
|
||||||
className="nav-link"
|
className="nav-link"
|
||||||
to={{
|
to={{
|
||||||
pathname: '/activities/history',
|
pathname: '/',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Workouts
|
Dashboard
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
{user.isAuthenticated && (
|
||||||
{props.user.isAuthenticated && (
|
<li className="nav-item">
|
||||||
<li className="nav-item">
|
<Link
|
||||||
<Link
|
className="nav-link"
|
||||||
className="nav-link"
|
to={{
|
||||||
to={{
|
pathname: '/activities/history',
|
||||||
pathname: '/activities/add',
|
}}
|
||||||
}}
|
>
|
||||||
>
|
Workouts
|
||||||
<strong>Add workout</strong>
|
</Link>
|
||||||
</Link>
|
</li>
|
||||||
</li>
|
)}
|
||||||
)}
|
{user.isAuthenticated && (
|
||||||
{/* {props.user.admin && ( */}
|
<li className="nav-item">
|
||||||
{/* <li className="nav-item"> */}
|
<Link
|
||||||
{/* <Link */}
|
className="nav-link"
|
||||||
{/* className="nav-link" */}
|
to={{
|
||||||
{/* to={{ */}
|
pathname: '/activities/add',
|
||||||
{/* pathname: '/admin', */}
|
}}
|
||||||
{/* }} */}
|
>
|
||||||
{/* > */}
|
<strong>Add workout</strong>
|
||||||
{/* Admin */}
|
</Link>
|
||||||
{/* </Link> */}
|
</li>
|
||||||
{/* </li> */}
|
)}
|
||||||
{/* )} */}
|
{/* {user.admin && ( */}
|
||||||
</ul>
|
{/* <li className="nav-item"> */}
|
||||||
<ul className="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
{/* <Link */}
|
||||||
{!props.user.isAuthenticated && (
|
{/* className="nav-link" */}
|
||||||
<li className="nav-item">
|
{/* to={{ */}
|
||||||
<Link
|
{/* pathname: '/admin', */}
|
||||||
className="nav-link"
|
{/* }} */}
|
||||||
to={{
|
{/* > */}
|
||||||
pathname: '/register',
|
{/* Admin */}
|
||||||
}}
|
{/* </Link> */}
|
||||||
>
|
{/* </li> */}
|
||||||
Register
|
{/* )} */}
|
||||||
</Link>
|
</ul>
|
||||||
</li>
|
<ul className="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||||
)}
|
{!user.isAuthenticated && (
|
||||||
{!props.user.isAuthenticated && (
|
<li className="nav-item">
|
||||||
<li className="nav-item">
|
<Link
|
||||||
<Link
|
className="nav-link"
|
||||||
className="nav-link"
|
to={{
|
||||||
to={{
|
pathname: '/register',
|
||||||
pathname: '/login',
|
}}
|
||||||
}}
|
>
|
||||||
>
|
Register
|
||||||
Login
|
</Link>
|
||||||
</Link>
|
</li>
|
||||||
</li>
|
)}
|
||||||
)}
|
{!user.isAuthenticated && (
|
||||||
{props.user.picture === true && (
|
<li className="nav-item">
|
||||||
<img
|
<Link
|
||||||
alt="Avatar"
|
className="nav-link"
|
||||||
src={`${apiUrl}users/${props.user.id}/picture` +
|
to={{
|
||||||
`?${Date.now()}`}
|
pathname: '/login',
|
||||||
className="img-fluid App-nav-profile-img"
|
}}
|
||||||
/>
|
>
|
||||||
)}
|
Login
|
||||||
{props.user.isAuthenticated && (
|
</Link>
|
||||||
<li className="nav-item">
|
</li>
|
||||||
<Link
|
)}
|
||||||
className="nav-link"
|
{user.picture === true && (
|
||||||
to={{
|
<img
|
||||||
pathname: '/profile',
|
alt="Avatar"
|
||||||
}}
|
src={`${apiUrl}users/${user.id}/picture` +
|
||||||
>
|
`?${Date.now()}`}
|
||||||
{props.user.username}
|
className="img-fluid App-nav-profile-img"
|
||||||
</Link>
|
/>
|
||||||
</li>
|
)}
|
||||||
)}
|
{user.isAuthenticated && (
|
||||||
{props.user.isAuthenticated && (
|
<li className="nav-item">
|
||||||
<li className="nav-item">
|
<Link
|
||||||
<Link
|
className="nav-link"
|
||||||
className="nav-link"
|
to={{
|
||||||
to={{
|
pathname: '/profile',
|
||||||
pathname: '/logout',
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{user.username}
|
||||||
Logout
|
</Link>
|
||||||
</Link>
|
</li>
|
||||||
</li>
|
)}
|
||||||
)}
|
{user.isAuthenticated && (
|
||||||
</ul>
|
<li className="nav-item">
|
||||||
|
<Link
|
||||||
|
className="nav-link"
|
||||||
|
to={{
|
||||||
|
pathname: '/logout',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
</nav>
|
</header>
|
||||||
</header>
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
Loading…
Reference in New Issue
Block a user