file reorganization

This commit is contained in:
Sam
2019-01-03 12:53:47 +01:00
parent af5b0e1889
commit 8e5f83d909
9 changed files with 6 additions and 6 deletions

View File

@ -1,201 +0,0 @@
// eslint-disable-next-line max-len
// source: https://blog.flowandform.agency/create-a-custom-calendar-in-react-3df1bfd0b728
import dateFns from 'date-fns'
import React, { Fragment } from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { getMonthActivities } from '../../actions/activities'
import { getDateWithTZ, recordsLabels } from '../../utils'
const getStartAndEndMonth = date => {
const monthStart = dateFns.startOfMonth(date)
const monthEnd = dateFns.endOfMonth(date)
return {
start: dateFns.startOfWeek(monthStart),
end: dateFns.endOfWeek(monthEnd),
}
}
class Calendar extends React.Component {
constructor(props, context) {
super(props, context)
const calendarDate = new Date()
this.state = {
currentMonth: calendarDate,
startDate: getStartAndEndMonth(calendarDate).start,
endDate: getStartAndEndMonth(calendarDate).end,
}
}
componentDidMount() {
this.props.loadMonthActivities(this.state.startDate, this.state.endDate)
}
renderHeader() {
const dateFormat = 'MMM YYYY'
return (
<div className="header row flex-middle">
<div className="col col-start" onClick={() => this.handlePrevMonth()}>
<i
className="fa fa-chevron-left"
aria-hidden="true"
/>
</div>
<div className="col col-center">
<span>
{dateFns.format(this.state.currentMonth, dateFormat)}
</span>
</div>
<div className="col col-end" onClick={() => this.handleNextMonth()}>
<i
className="fa fa-chevron-right"
aria-hidden="true"
/>
</div>
</div>
)
}
renderDays() {
const dateFormat = 'ddd'
const days = []
const { startDate } = this.state
for (let i = 0; i < 7; i++) {
days.push(
<div className="col col-center" key={i}>
{dateFns.format(dateFns.addDays(startDate, i), dateFormat)}
</div>
)
}
return <div className="days row">{days}</div>
}
filterActivities(day) {
const { activities, user } = this.props
if (activities) {
return activities
.filter(act => dateFns.isSameDay(
getDateWithTZ(act.activity_date, user.timezone),
day
))
}
return []
}
renderCells() {
const { currentMonth, startDate, endDate } = this.state
const { sports } = this.props
const dateFormat = 'D'
const rows = []
let days = []
let day = startDate
let formattedDate = ''
while (day <= endDate) {
for (let i = 0; i < 7; i++) {
formattedDate = dateFns.format(day, dateFormat)
const dayActivities = this.filterActivities(day)
const isDisabled = dateFns.isSameMonth(day, currentMonth)
? ''
: 'disabled'
days.push(
<div
className={`col cell img-${isDisabled}`}
key={day}
>
<span className="number">{formattedDate}</span>
{dayActivities.map(act => (
<Link key={act.id} to={`/activities/${act.id}`}>
<Fragment>
<img
alt="activity sport logo"
className={`activity-sport ${isDisabled}`}
src={sports
.filter(s => s.id === act.sport_id)
.map(s => s.img)}
title={act.title}
/>
{act.records.length > 0 && (
<sup>
<i
className="fa fa-trophy custom-fa-small"
aria-hidden="true"
title={act.records.map(rec => ` ${
recordsLabels.filter(
r => r.record_type === rec.record_type
)[0].label
}`)}
/>
</sup>
)}
</Fragment>
</Link>
))}
</div>
)
day = dateFns.addDays(day, 1)
}
rows.push(
<div className="row" key={day}>
{days}
</div>
)
days = []
}
return <div className="body">{rows}</div>
}
updateStateDate(calendarDate) {
const { start, end } = getStartAndEndMonth(calendarDate)
this.setState({
currentMonth: calendarDate,
startDate: start,
endDate: end,
})
this.props.loadMonthActivities(start, end)
}
handleNextMonth() {
const calendarDate = dateFns.addMonths(this.state.currentMonth, 1)
this.updateStateDate(calendarDate)
}
handlePrevMonth() {
const calendarDate = dateFns.subMonths(this.state.currentMonth, 1)
this.updateStateDate(calendarDate)
}
render() {
return (
<div className="card activity-card">
<div className="calendar">
{this.renderHeader()}
{this.renderDays()}
{this.renderCells()}
</div>
</div>
)
}
}
export default connect(
state => ({
activities: state.calendarActivities.data,
sports: state.sports.data,
user: state.user,
}),
dispatch => ({
loadMonthActivities: (start, end) => {
const dateFormat = 'YYYY-MM-DD'
dispatch(getMonthActivities(
dateFns.format(start, dateFormat),
dateFns.format(end, dateFormat),
))
},
})
)(Calendar)

View File

@ -1,42 +0,0 @@
import React from 'react'
export default function CustomModal(props) {
return (
<div className="custom-modal-backdrop">
<div className="custom-modal">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{props.title}</h5>
<button
type="button"
className="close"
aria-label="Close"
onClick={() => props.close}
>
<span aria-hidden="true">&times;</span>
</button>
</div>
<div className="modal-body">
<p>{props.text}</p>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-primary"
onClick={() => props.confirm()}
>
Yes
</button>
<button
type="button"
className="btn btn-secondary"
onClick={() => props.close()}
>
No
</button>
</div>
</div>
</div>
</div>
)
}

View File

@ -1,38 +0,0 @@
import React from 'react'
import { formatDuration } from '../../utils'
const formatValue = (displayedData, value) => displayedData === 'duration'
? formatDuration(value, true)
: displayedData === 'distance'
? value.toFixed(3)
: value
/**
* @return {null}
*/
export default function CustomTooltip (props) {
const { active } = props
if (active) {
const { displayedData, payload, label } = props
let total = 0
payload.map(p => total += p.value)
return (
<div className="custom-tooltip">
<p className="custom-tooltip-label">{label}</p>
{payload.map(p => (
<p key={p.name} style={{ color: p.fill }}>
{p.name}: {formatValue(displayedData, p.value)} {p.unit}
</p>))
}
{payload.length > 0 && (
<p>
Total: {formatValue(displayedData, total)} {payload[0].unit}
</p>
)}
</div>
)
}
return null
}

View File

@ -1,97 +0,0 @@
import React from 'react'
import {
Bar, BarChart, ResponsiveContainer, Tooltip, XAxis, YAxis
} from 'recharts'
import { activityColors, formatDuration } from '../../../utils'
import CustomTooltip from '../CustomTooltip'
export default class StatsCharts extends React.PureComponent {
constructor(props, context) {
super(props, context)
this.state = {
displayedData: 'distance'
}
}
handleRadioChange (changeEvent) {
this.setState({
displayedData: changeEvent.target.name
})
}
render() {
const { displayedData } = this.state
const { sports, stats } = this.props
if (Object.keys(stats).length === 0) {
return 'No workouts'
}
return (
<div className="chart-stats">
<div className="row chart-radio">
<label className="radioLabel col">
<input
type="radio"
name="distance"
checked={displayedData === 'distance'}
onChange={e => this.handleRadioChange(e)}
/>
distance
</label>
<label className="radioLabel col">
<input
type="radio"
name="duration"
checked={displayedData === 'duration'}
onChange={e => this.handleRadioChange(e)}
/>
duration
</label>
<label className="radioLabel col">
<input
type="radio"
name="activities"
checked={displayedData === 'activities'}
onChange={e => this.handleRadioChange(e)}
/>
activities
</label>
</div>
<ResponsiveContainer height={300}>
<BarChart
data={stats[displayedData]}
margin={{ top: 15, bottom: 0 }}
>
<XAxis
dataKey="date"
interval={0} // to force to display all ticks
/>
<YAxis
tickFormatter={value => displayedData === 'distance'
? `${value} km`
: displayedData === 'duration'
? formatDuration(value)
: value
}
/>
<Tooltip content={
<CustomTooltip
displayedData={displayedData}
/>
}
/>
{sports.map((s, i) => (
<Bar
key={s.id}
dataKey={s.label}
stackId="a"
fill={activityColors[i]}
unit={displayedData === 'distance' ? ' km' : ''}
/>
))}
</BarChart>
</ResponsiveContainer>
</div>
)
}
}

View File

@ -1,50 +0,0 @@
import { format } from 'date-fns'
import React from 'react'
import { connect } from 'react-redux'
import { getStats } from '../../../actions/stats'
import { formatStats } from '../../../utils'
import StatsChart from './StatsChart'
class Statistics extends React.PureComponent {
componentDidMount() {
this.props.loadMonthActivities(
this.props.user.id,
this.props.statsParams,
)
}
render() {
const { sports, statistics, statsParams } = this.props
const stats = formatStats(statistics, sports, statsParams)
return (
<>
{Object.keys(statistics).length === 0 ? (
'No workouts'
) : (
<StatsChart sports={sports} stats={stats} />
)}
</>
)
}
}
export default connect(
state => ({
sports: state.sports.data,
statistics: state.statistics.data,
user: state.user,
}),
dispatch => ({
loadMonthActivities: (userId, data) => {
const dateFormat = 'YYYY-MM-DD'
const params = {
from: format(data.start, dateFormat),
to: format(data.end, dateFormat),
time: data.duration
}
dispatch(getStats(userId, data.type, params))
},
})
)(Statistics)