You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

127 lines
4.8 KiB

import {useCallback, useContext, useEffect, useMemo, useState} from "react";
import DeviceContext from "../contexts/DeviceContext";
import {useNavigate, useParams} from "react-router";
import {useSearchParams} from "react-router-dom";
import WorkoutContext from "../contexts/WorkoutContext";
import {PastWorkout, stateString, WorkoutState} from "../models/Workouts";
import Page, {PageBody, PageFlexColumn, PageFlexRow} from "../primitives/page/Page";
import LoadingPage, {LoadingSection} from "./LoadingPage";
import Header, {HeaderButton, HeaderTitle} from "../primitives/header/Header";
import {Icon} from "../primitives/Shared";
import {
faChevronDown,
faChevronLeft,
faClock,
faClockFour,
faClockRotateLeft,
faTableList
} from "@fortawesome/free-solid-svg-icons";
import {Size} from "../models/Shared";
import {TitleLine} from "../primitives/misc/Misc";
import Blob, {BlobText, BlobTextLine} from "../primitives/blob/Blob";
import {subTitleOfProgram} from "../models/Programs";
import {formatDate, formatTime} from "../helpers/dates";
import {faSpinner} from "@fortawesome/free-solid-svg-icons/faSpinner";
export default function WorkoutPage(): JSX.Element {
const {getWorkout, fetchWorkout, getStates, fetchStates} = useContext(WorkoutContext);
const navigate = useNavigate();
const {id} = useParams();
const workout = useMemo(() => getWorkout(id || "random"), [getWorkout, id]);
const states = useMemo(() => getStates(id || "random"), [getStates, id]);
const [expanded, setExpanded] = useState(false);
const wsFilter = useCallback((ws: WorkoutState, index: number, arr: WorkoutState[]) => {
return expanded || (ws.time % 15 === 0) || index === arr.length - 1;
}, [expanded]);
useEffect(() => {
fetchWorkout(id || "random");
fetchStates(id || "random");
}, [id]);
return (
<Page title={`Økt ${id}`}>
<Header>
<HeaderButton onClick={() => navigate("/")} shortcut="/">
<Icon value={faChevronLeft}/>
</HeaderButton>
<HeaderTitle>Øktdetaljer</HeaderTitle>
</Header>
<PageBody>
<PageFlexRow collapseOn={Size.Tablet}>
<PageFlexColumn flex={1}>
<TitleLine>Økt</TitleLine>
{workout ? (
<>
<Blob>
<BlobText>
<BlobTextLine>
<Icon value={faClockFour}/> {formatTime(workout.createdAt)}
</BlobTextLine>
<BlobTextLine secondary>{formatDate(workout.createdAt)}</BlobTextLine>
</BlobText>
</Blob>
{workout.message && (
<Blob color="red">
<BlobText>
<BlobTextLine>Det oppsto en feil!</BlobTextLine>
<BlobTextLine secondary>{workout.message.trim() || "(Ingen melding)"}</BlobTextLine>
</BlobText>
</Blob>
)}
{workout.device && (
<Blob>
<BlobText>
<BlobTextLine>{workout.device.name}</BlobTextLine>
<BlobTextLine secondary>{workout.device.connectionString}</BlobTextLine>
</BlobText>
</Blob>
)}
{workout.program && (
<Blob>
<BlobText>
<BlobTextLine>{workout.program.name}</BlobTextLine>
<BlobTextLine secondary>{subTitleOfProgram(workout.program)}</BlobTextLine>
</BlobText>
</Blob>
)}
</>
) : <LoadingSection/>}
</PageFlexColumn>
<PageFlexColumn flex={1}>
<TitleLine>Målinger</TitleLine>
{states ? (
states.filter(wsFilter).map(s => (
<PageFlexRow key={s.time}>
<Blob>
<BlobText>{stateString(s, "time")}</BlobText>
</Blob>
<Blob>
<BlobText>{stateString(s, "calories")}</BlobText>
</Blob>
<Blob>
<BlobText>{stateString(s, "distance")}</BlobText>
</Blob>
<Blob>
<BlobText>{stateString(s, "level")}</BlobText>
</Blob>
</PageFlexRow>
))
) : <LoadingSection/>}
{!expanded && (
<PageFlexRow>
<Blob onClick={() => setExpanded(true)}>
<BlobText>
<Icon value={faChevronDown}/> Vis alle
</BlobText>
</Blob>
</PageFlexRow>
)}
</PageFlexColumn>
</PageFlexRow>
</PageBody>
</Page>
);
}