Apply Prettier to all the code
This commit is contained in:
parent
812dafcbd1
commit
806c733597
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"printWidth": 120,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
27
src/App.tsx
27
src/App.tsx
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState, useCallback } from "react";
|
||||||
import { WorkoutPlot } from './components/WorkoutPlot';
|
import { WorkoutPlot } from "./components/WorkoutPlot";
|
||||||
import { WorkoutStats } from './components/WorkoutStats';
|
import { WorkoutStats } from "./components/WorkoutStats";
|
||||||
import { parse, chunkRangeIntervals, Duration } from 'zwiftout';
|
import { parse, chunkRangeIntervals, Duration } from "zwiftout";
|
||||||
import { ErrorMessage } from './components/ErrorMessage';
|
import { ErrorMessage } from "./components/ErrorMessage";
|
||||||
import styled from 'styled-components';
|
import styled from "styled-components";
|
||||||
import { CodeEditor } from './components/CodeEditor';
|
import { CodeEditor } from "./components/CodeEditor";
|
||||||
import { ZwoOutput } from './components/ZwoOutput';
|
import { ZwoOutput } from "./components/ZwoOutput";
|
||||||
import { AppTitle } from './components/AppTitle';
|
import { AppTitle } from "./components/AppTitle";
|
||||||
import { Credits } from './components/Credits';
|
import { Credits } from "./components/Credits";
|
||||||
|
|
||||||
const defaultWorkout = `Name: Sample workout
|
const defaultWorkout = `Name: Sample workout
|
||||||
Description: Try changing it, and see what happens below.
|
Description: Try changing it, and see what happens below.
|
||||||
|
|
@ -37,7 +37,8 @@ export function App() {
|
||||||
const [workout, setWorkout] = useState(parse(defaultWorkout));
|
const [workout, setWorkout] = useState(parse(defaultWorkout));
|
||||||
const [error, setError] = useState<string | undefined>(undefined);
|
const [error, setError] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
const onChange = useCallback((value: string) => {
|
const onChange = useCallback(
|
||||||
|
(value: string) => {
|
||||||
setText(value);
|
setText(value);
|
||||||
try {
|
try {
|
||||||
setWorkout(parse(value));
|
setWorkout(parse(value));
|
||||||
|
|
@ -45,7 +46,9 @@ export function App() {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(e.message);
|
setError(e.message);
|
||||||
}
|
}
|
||||||
}, [setText, setWorkout, setError]);
|
},
|
||||||
|
[setText, setWorkout, setError],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppContainer>
|
<AppContainer>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import logo from "../logo.png";
|
import logo from "../logo.png";
|
||||||
|
|
||||||
|
|
@ -21,5 +21,8 @@ const Beta = styled.span`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const AppTitle: React.FC<{}> = () => (
|
export const AppTitle: React.FC<{}> = () => (
|
||||||
<Title><Logo />Workout editor <Beta>beta</Beta></Title>
|
<Title>
|
||||||
|
<Logo />
|
||||||
|
Workout editor <Beta>beta</Beta>
|
||||||
|
</Title>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ export type BarProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const zoneColorsMap: Record<ZoneType, string> = {
|
const zoneColorsMap: Record<ZoneType, string> = {
|
||||||
"free": "linear-gradient(to top, rgba(204,204,204,1), rgba(255,255,255,0))",
|
free: "linear-gradient(to top, rgba(204,204,204,1), rgba(255,255,255,0))",
|
||||||
"Z1": "#7f7f7f",
|
Z1: "#7f7f7f",
|
||||||
"Z2": "#338cff",
|
Z2: "#338cff",
|
||||||
"Z3": "#59bf59",
|
Z3: "#59bf59",
|
||||||
"Z4": "#ffcc3f",
|
Z4: "#ffcc3f",
|
||||||
"Z5": "#ff6639",
|
Z5: "#ff6639",
|
||||||
"Z6": "#ff330c",
|
Z6: "#ff330c",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Bar = styled.div<BarProps>`
|
export const Bar = styled.div<BarProps>`
|
||||||
|
|
@ -26,7 +26,7 @@ export const Bar = styled.div<BarProps>`
|
||||||
margin-right: 0.1%;
|
margin-right: 0.1%;
|
||||||
/* exclude 0.1% margin from bar width */
|
/* exclude 0.1% margin from bar width */
|
||||||
width: ${(props) => props.durationPercentage - 0.1}%;
|
width: ${(props) => props.durationPercentage - 0.1}%;
|
||||||
height: ${(props) => props.zone === "free" ? 100 : props.intensityPercentage}%;
|
height: ${(props) => (props.zone === "free" ? 100 : props.intensityPercentage)}%;
|
||||||
background: ${(props) => zoneColorsMap[props.zone]};
|
background: ${(props) => zoneColorsMap[props.zone]};
|
||||||
transition: width 0.1s, height 0.1s, background-color 0.1s;
|
transition: width 0.1s, height 0.1s, background-color 0.1s;
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import Editor from 'react-simple-code-editor';
|
import Editor from "react-simple-code-editor";
|
||||||
import styled from 'styled-components';
|
import styled from "styled-components";
|
||||||
|
|
||||||
const highlight = (code: string): string => {
|
const highlight = (code: string): string => {
|
||||||
return code
|
return code
|
||||||
|
|
@ -12,7 +12,7 @@ const highlight = (code: string): string => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CodeEditor = styled(Editor).attrs({ padding: 10, highlight })`
|
export const CodeEditor = styled(Editor).attrs({ padding: 10, highlight })`
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
border: 1px inset #bbb;
|
border: 1px inset #bbb;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import styled from 'styled-components';
|
import styled from "styled-components";
|
||||||
|
|
||||||
const Text = styled.p`
|
const Text = styled.p`
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
@ -12,10 +12,7 @@ const Text = styled.p`
|
||||||
|
|
||||||
export const Credits: React.FC<{}> = () => (
|
export const Credits: React.FC<{}> = () => (
|
||||||
<Text>
|
<Text>
|
||||||
Built by Rene Saarsoo.
|
Built by Rene Saarsoo. · Graphics inspired by <a href="https://whatsonzwift.com/workouts/">What's on Zwift?</a>
|
||||||
·
|
· Sweat provided by <a href="https://zwift.com">Zwift</a> :-)
|
||||||
Graphics inspired by <a href="https://whatsonzwift.com/workouts/">What's on Zwift?</a>
|
|
||||||
·
|
|
||||||
Sweat provided by <a href="https://zwift.com">Zwift</a> :-)
|
|
||||||
</Text>
|
</Text>
|
||||||
)
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import styled from 'styled-components';
|
import styled from "styled-components";
|
||||||
|
|
||||||
export const ErrorMessage = styled.p`
|
export const ErrorMessage = styled.p`
|
||||||
color: red;
|
color: red;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import { BarProps, Bar } from "./Bar";
|
||||||
|
|
||||||
const toBarProps = (interval: Interval, workoutDuration: Duration, maxIntensity: Intensity): BarProps => ({
|
const toBarProps = (interval: Interval, workoutDuration: Duration, maxIntensity: Intensity): BarProps => ({
|
||||||
zone: interval.intensity.zone,
|
zone: interval.intensity.zone,
|
||||||
durationPercentage: interval.duration.seconds / workoutDuration.seconds * 100,
|
durationPercentage: (interval.duration.seconds / workoutDuration.seconds) * 100,
|
||||||
intensityPercentage: interval.intensity.value / maxIntensity.value * 100,
|
intensityPercentage: (interval.intensity.value / maxIntensity.value) * 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
const Plot = styled.div`
|
const Plot = styled.div`
|
||||||
|
|
@ -24,7 +24,11 @@ export const WorkoutPlot: React.FC<{ intervals: Interval[] }> = ({ intervals })
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Plot>
|
<Plot>
|
||||||
{ intervals.map((interval) => toBarProps(interval, workoutDuration, maxIntensity)).map((props, i) => (<Bar key={i} {...props} />)) }
|
{intervals
|
||||||
|
.map((interval) => toBarProps(interval, workoutDuration, maxIntensity))
|
||||||
|
.map((props, i) => (
|
||||||
|
<Bar key={i} {...props} />
|
||||||
|
))}
|
||||||
</Plot>
|
</Plot>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,9 @@ import { stats, Workout, Intensity } from "zwiftout";
|
||||||
import { formatDuration } from "./formatDuration";
|
import { formatDuration } from "./formatDuration";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
const formatIntensity = (intensity: Intensity): string =>
|
const formatIntensity = (intensity: Intensity): string => `${Math.round(intensity.value * 100)}%`;
|
||||||
`${Math.round(intensity.value * 100)}%`;
|
|
||||||
|
|
||||||
const StatsLine: React.FC<{ label: string; value: string | number }> = ({
|
const StatsLine: React.FC<{ label: string; value: string | number }> = ({ label, value }) => (
|
||||||
label,
|
|
||||||
value,
|
|
||||||
}) => (
|
|
||||||
<li>
|
<li>
|
||||||
<strong>{label}</strong> {value}
|
<strong>{label}</strong> {value}
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -42,14 +38,7 @@ const ZoneList = styled(List)`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const WorkoutStats: React.FC<{ workout: Workout }> = ({ workout }) => {
|
export const WorkoutStats: React.FC<{ workout: Workout }> = ({ workout }) => {
|
||||||
const {
|
const { totalDuration, averageIntensity, normalizedIntensity, tss, xp, zones } = stats(workout);
|
||||||
totalDuration,
|
|
||||||
averageIntensity,
|
|
||||||
normalizedIntensity,
|
|
||||||
tss,
|
|
||||||
xp,
|
|
||||||
zones,
|
|
||||||
} = stats(workout);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
|
@ -57,30 +46,17 @@ export const WorkoutStats: React.FC<{ workout: Workout }> = ({ workout }) => {
|
||||||
<Header>Summary</Header>
|
<Header>Summary</Header>
|
||||||
<List>
|
<List>
|
||||||
<StatsLine label="Duration:" value={formatDuration(totalDuration)} />
|
<StatsLine label="Duration:" value={formatDuration(totalDuration)} />
|
||||||
<StatsLine
|
<StatsLine label="Average intensity:" value={formatIntensity(averageIntensity)} />
|
||||||
label="Average intensity:"
|
<StatsLine label="Normalized intensity:" value={formatIntensity(normalizedIntensity)} />
|
||||||
value={formatIntensity(averageIntensity)}
|
|
||||||
/>
|
|
||||||
<StatsLine
|
|
||||||
label="Normalized intensity:"
|
|
||||||
value={formatIntensity(normalizedIntensity)}
|
|
||||||
/>
|
|
||||||
<StatsLine label="TSS:" value={Math.round(tss)} />
|
<StatsLine label="TSS:" value={Math.round(tss)} />
|
||||||
<StatsLine
|
<StatsLine label="Zwift XP:" value={`${xp} (like riding ${Math.ceil(xp / 20)} km)`} />
|
||||||
label="Zwift XP:"
|
|
||||||
value={`${xp} (like riding ${Math.ceil(xp / 20)} km)`}
|
|
||||||
/>
|
|
||||||
</List>
|
</List>
|
||||||
</Section>
|
</Section>
|
||||||
<Section>
|
<Section>
|
||||||
<Header>Zone distribution</Header>
|
<Header>Zone distribution</Header>
|
||||||
<ZoneList>
|
<ZoneList>
|
||||||
{zones.map((zone) => (
|
{zones.map((zone) => (
|
||||||
<StatsLine
|
<StatsLine key={zone.name} label={zone.name} value={formatDuration(zone.duration)} />
|
||||||
key={zone.name}
|
|
||||||
label={zone.name}
|
|
||||||
value={formatDuration(zone.duration)}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</ZoneList>
|
</ZoneList>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import { Workout, generateZwo } from 'zwiftout';
|
import { Workout, generateZwo } from "zwiftout";
|
||||||
import styled from 'styled-components';
|
import styled from "styled-components";
|
||||||
|
|
||||||
const Header = styled.h2`
|
const Header = styled.h2`
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
@ -19,5 +19,5 @@ export const ZwoOutput: React.FC<{ workout: Workout }> = ({ workout }) => {
|
||||||
<Header>Generated Zwift workout file (.zwo):</Header>
|
<Header>Generated Zwift workout file (.zwo):</Header>
|
||||||
<ZwoCode>{generateZwo(workout)}</ZwoCode>
|
<ZwoCode>{generateZwo(workout)}</ZwoCode>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,11 @@ export const formatDuration = (duration: Duration): string => {
|
||||||
const { hours, minutes, seconds } = splitDuration(duration);
|
const { hours, minutes, seconds } = splitDuration(duration);
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
return `${hours}h ${minutes}min`;
|
return `${hours}h ${minutes}min`;
|
||||||
}
|
} else if (minutes > 0) {
|
||||||
else if (minutes > 0) {
|
|
||||||
return `${minutes}min`;
|
return `${minutes}min`;
|
||||||
}
|
} else if (seconds > 0) {
|
||||||
else if (seconds > 0) {
|
|
||||||
return `${seconds}sec`;
|
return `${seconds}sec`;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return `-`;
|
return `-`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,12 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
background-color: #f7f7f2;
|
background-color: #f7f7f2;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
|
||||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
"Droid Sans", "Helvetica Neue", sans-serif;
|
||||||
sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||||
monospace;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from "react-dom";
|
||||||
import './index.css';
|
import "./index.css";
|
||||||
import { App } from './App';
|
import { App } from "./App";
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById("root"),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue