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.
134 lines
5.4 KiB
134 lines
5.4 KiB
import Page, {PageBody, PageFlexColumn, PageFlexRow} from "../primitives/page/Page";
|
|
import Header, {HeaderTitle} from "../primitives/header/Header";
|
|
import {TitleLine} from "../primitives/misc/Misc";
|
|
import {Size} from "../models/Shared";
|
|
import Blob, {BlobText, BlobTextLine} from "../primitives/blob/Blob";
|
|
import {Icon} from "../primitives/Shared";
|
|
import {faChevronDown, faPlay, faPlus} from "@fortawesome/free-solid-svg-icons";
|
|
import {useContext, useEffect, useMemo} from "react";
|
|
import ProgramContext from "../contexts/ProgramContext";
|
|
import LoadingPage from "./LoadingPage";
|
|
import {subTitleOfProgram} from "../models/Programs";
|
|
import {useNavigate} from "react-router";
|
|
import DeviceContext from "../contexts/DeviceContext";
|
|
import WorkoutContext from "../contexts/WorkoutContext";
|
|
import {formatDate, formatTime} from "../helpers/dates";
|
|
import {colorOf, WorkoutStatus} from "../models/Workouts";
|
|
import {faSpinner} from "@fortawesome/free-solid-svg-icons/faSpinner";
|
|
import {useKey} from "../hooks/keyboard";
|
|
import {Boi} from "../primitives/boi/Boi";
|
|
import useLocalStorage from "../hooks/storage";
|
|
|
|
export default function IndexPage(): JSX.Element {
|
|
const {devices} = useContext(DeviceContext);
|
|
const {programs} = useContext(ProgramContext);
|
|
const {workouts, loadingWorkouts, expanded, showMoreWorkouts, refreshWorkouts} = useContext(WorkoutContext);
|
|
const navigate = useNavigate();
|
|
const [statPos, setStatPos] = useLocalStorage<"left" | "right">("stats.position", "left");
|
|
|
|
const isRunning = useMemo(() => workouts.some(w => w.status !== WorkoutStatus.Disconnected), [workouts]);
|
|
|
|
useEffect(() => {
|
|
refreshWorkouts();
|
|
}, [refreshWorkouts]);
|
|
|
|
useKey(["/", "*"], () => navigate("/play"), [navigate]);
|
|
|
|
if (programs === null) {
|
|
return <LoadingPage text="Henter programmer"/>
|
|
} else if (devices === null) {
|
|
return <LoadingPage text="Henter enheter"/>
|
|
}
|
|
|
|
return (
|
|
<Page>
|
|
<Header>
|
|
<HeaderTitle>YKonsole</HeaderTitle>
|
|
</Header>
|
|
<Boi vertical="bottom" horizontal="center">
|
|
<Blob onClick={() => navigate("/play")} color={isRunning ? "yellow" : "green"}>
|
|
<BlobText>
|
|
<Icon value={faPlay}/> {isRunning ? "Fortsett" : "Start"}
|
|
</BlobText>
|
|
</Blob>
|
|
</Boi>
|
|
<PageBody>
|
|
<PageFlexRow collapseOn={Size.Tablet}>
|
|
<PageFlexColumn flex={1}>
|
|
<TitleLine>Siste økter ({loadingWorkouts ? <Icon value={faSpinner} spin/> : workouts.length})</TitleLine>
|
|
{workouts.map(w => (
|
|
<Blob key={w.id} color={colorOf(w)} onClick={() => navigate(`/workouts/${w.id}`)}>
|
|
<BlobText>
|
|
<BlobTextLine>{formatDate(w.createdAt)} {formatTime(w.createdAt)}</BlobTextLine>
|
|
<BlobTextLine secondary>
|
|
{w.program ? w.program.name : (w.device?.name || "Ukjent enhet")}
|
|
</BlobTextLine>
|
|
</BlobText>
|
|
</Blob>
|
|
))}
|
|
{!expanded && (
|
|
<PageFlexRow>
|
|
<Blob onClick={loadingWorkouts ? undefined : () => showMoreWorkouts()}>
|
|
<BlobText>
|
|
{loadingWorkouts && <Icon value={faSpinner} spin/> }
|
|
{!loadingWorkouts && <><Icon value={faChevronDown}/> Vis flere</> }
|
|
</BlobText>
|
|
</Blob>
|
|
</PageFlexRow>
|
|
)}
|
|
</PageFlexColumn>
|
|
|
|
<PageFlexColumn flex={1}>
|
|
<TitleLine>Programmer ({programs.length})</TitleLine>
|
|
{programs.map(p => (
|
|
<Blob key={p.id} onClick={() => navigate(`/programs/${p.id}`)}>
|
|
<BlobText>
|
|
<BlobTextLine>{p.name}</BlobTextLine>
|
|
<BlobTextLine secondary>{subTitleOfProgram(p)}</BlobTextLine>
|
|
</BlobText>
|
|
</Blob>
|
|
))}
|
|
<Blob color="green" onClick={() => navigate(`/programs/new`)}>
|
|
<BlobText>
|
|
<BlobTextLine>
|
|
<Icon value={faPlus}/>
|
|
</BlobTextLine>
|
|
<BlobTextLine secondary>Legg til</BlobTextLine>
|
|
</BlobText>
|
|
</Blob>
|
|
|
|
<TitleLine>Enheter ({devices.length})</TitleLine>
|
|
{devices.map(d => (
|
|
<Blob key={d.id} onClick={() => navigate(`/devices/${d.id}`)}>
|
|
<BlobText>
|
|
<BlobTextLine>{d.name}</BlobTextLine>
|
|
<BlobTextLine secondary>{d.connectionString}</BlobTextLine>
|
|
</BlobText>
|
|
</Blob>
|
|
))}
|
|
<Blob color="green" onClick={() => navigate("/devices/new")}>
|
|
<BlobText>
|
|
<BlobTextLine>
|
|
<Icon value={faPlus}/>
|
|
</BlobTextLine>
|
|
<BlobTextLine secondary>Legg til</BlobTextLine>
|
|
</BlobText>
|
|
</Blob>
|
|
|
|
<TitleLine>Plassering på statistikblokk</TitleLine>
|
|
<Blob onClick={() => setStatPos("left")} color={statPos === "left" ? "blue" : "gray"}>
|
|
<BlobText>
|
|
<BlobTextLine>Til venstre</BlobTextLine>
|
|
</BlobText>
|
|
</Blob>
|
|
<Blob onClick={() => setStatPos("right")} color={statPos === "right" ? "blue" : "gray"}>
|
|
<BlobText>
|
|
<BlobTextLine>Til høyre</BlobTextLine>
|
|
</BlobText>
|
|
</Blob>
|
|
</PageFlexColumn>
|
|
</PageFlexRow>
|
|
</PageBody>
|
|
</Page>
|
|
);
|
|
}
|