Use stats object and format it on react side
This commit is contained in:
parent
2046f1adc9
commit
48347baca4
|
|
@ -10,7 +10,7 @@
|
|||
"@types/node": "^12.0.0",
|
||||
"@types/react": "^16.9.0",
|
||||
"@types/react-dom": "^16.9.0",
|
||||
"make-workout": "^0.0.0",
|
||||
"luxon": "^1.25.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-scripts": "3.4.3",
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/luxon": "^1.25.0",
|
||||
"@types/styled-components": "^5.1.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,45 @@
|
|||
import React from 'react';
|
||||
import { stats, Workout } from 'make-workout';
|
||||
import { stats, Workout, Duration, Intensity } from 'make-workout';
|
||||
import { Duration as LuxonDuration } from 'luxon';
|
||||
|
||||
export const WorkoutStats: React.FC<{workout: Workout}> = ({ workout }) => (
|
||||
<pre>{stats(workout)}</pre>
|
||||
const formatDuration = (duration: Duration): string => {
|
||||
const {hours, minutes, seconds} = LuxonDuration.fromObject({seconds: duration.seconds}).shiftTo('hours', 'minutes', 'seconds');
|
||||
if (hours > 0) {
|
||||
return `${hours}h ${minutes}min`;
|
||||
}
|
||||
else if (minutes > 0) {
|
||||
return `${minutes}min`;
|
||||
}
|
||||
else if (seconds > 0) {
|
||||
return `${seconds}sec`;
|
||||
}
|
||||
else {
|
||||
return `-`;
|
||||
}
|
||||
};
|
||||
|
||||
const formatIntensity = (intensity: Intensity): string => `${Math.round(intensity.value * 100)}%`;
|
||||
|
||||
const StatsLine: React.FC<{ label: string, value: string | number }> = ({ label, value }) => (
|
||||
<li><strong>{label}</strong> {value}</li>
|
||||
);
|
||||
|
||||
export const WorkoutStats: React.FC<{workout: Workout}> = ({ workout }) => {
|
||||
const {totalDuration, averageIntensity, normalizedIntensity, tss, zones} = stats(workout);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Summary</h2>
|
||||
<ul>
|
||||
<StatsLine label="Duration:" value={formatDuration(totalDuration)} />
|
||||
<StatsLine label="Average intensity:" value={formatIntensity(averageIntensity)} />
|
||||
<StatsLine label="Normalized intensity:" value={formatIntensity(normalizedIntensity)} />
|
||||
<StatsLine label="TSS:" value={Math.round(tss)} />
|
||||
</ul>
|
||||
<h2>Zone distribution</h2>
|
||||
<ul>
|
||||
{zones.map(zone => (<StatsLine label={zone.name} value={formatDuration(zone.duration)} />)) }
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
|
|
|||
10
yarn.lock
10
yarn.lock
|
|
@ -1622,6 +1622,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
|
||||
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
|
||||
|
||||
"@types/luxon@^1.25.0":
|
||||
version "1.25.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.25.0.tgz#3d6fe591fac874f48dd225cb5660b2b785a21a05"
|
||||
integrity sha512-iIJp2CP6C32gVqI08HIYnzqj55tlLnodIBMCcMf28q9ckqMfMzocCmIzd9JWI/ALLPMUiTkCu1JGv3FFtu6t3g==
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
|
|
@ -6676,6 +6681,11 @@ lru-cache@^5.1.1:
|
|||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
luxon@^1.25.0:
|
||||
version "1.25.0"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.25.0.tgz#d86219e90bc0102c0eb299d65b2f5e95efe1fe72"
|
||||
integrity sha512-hEgLurSH8kQRjY6i4YLey+mcKVAWXbDNlZRmM6AgWDJ1cY3atl8Ztf5wEY7VBReFbmGnwQPz7KYJblL8B2k0jQ==
|
||||
|
||||
make-dir@^2.0.0, make-dir@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
|
||||
|
|
|
|||
Loading…
Reference in New Issue