|
|
import Page, {PageBody, PageFlexColumn, PageFlexRow} from "../primitives/page/Page"; import {useNavigate, useParams} from "react-router"; import React, {useCallback, useContext, useEffect, useMemo, useState} from "react"; import ProgramContext from "../contexts/ProgramContext"; import LoadingPage from "./LoadingPage"; import Header, {HeaderButton, HeaderTitle} from "../primitives/header/Header"; import {Icon} from "../primitives/Shared"; import { faArrowUpRightDots, faCheck, faChevronLeft, faClose, faLevelUpAlt, faPlus, faStopwatch } from "@fortawesome/free-solid-svg-icons"; import {Size, stringToValues, valuesToString} from "../models/Shared"; import {TitleLine} from "../primitives/misc/Misc"; import Blob, {BlobInput, BlobText} from "../primitives/blob/Blob"; import {ProgramStep} from "../models/Programs"; import programRepo from "../actions/programs";
interface StepOption { level: number duration: string }
export default function EditProgramPage() { const {programs, refreshPrograms} = useContext(ProgramContext); const navigate = useNavigate(); const {id} = useParams(); const program = useMemo(() => programs?.find(p => p.id === id), [programs, id]);
const [name, setName] = useState(program?.name || ""); const [steps, setSteps] = useState<StepOption[]>([]);
const [wait, setWait] = useState<boolean>(false);
useEffect(() => { if (program) { setName(program.name) setSteps(program.steps.map(s => ({ level: s.values.level || 0, duration: valuesToString(s.duration || {}), }))); } }, [program]);
const onSave = useCallback(() => { const id = program?.id || undefined; const newSteps: ProgramStep[] = steps.map(s => ({ values: {level: s.level}, duration: stringToValues(s.duration), }));
setWait(true); programRepo().save({id, name, steps: newSteps}) .then(res => { if (res) { navigate(program ? `/programs/${program.id}` : "/"); refreshPrograms(); } else { setWait(false); } }); }, [program, name, steps, navigate, refreshPrograms]);
if (programs === null) { return <LoadingPage text="Henter programmer"/>; } else if (wait) { return <LoadingPage text="Lagrer programm"/>; }
const title = program ? `Endre "${program.name}"` : "Nytt programm"; const canSave = name.trim() !== "" && steps.length > 0 && !steps.find(p => p.level === 0);
return ( <Page title={title}> <Header> <HeaderButton onClick={() => navigate(program ? `/programs/${program.id}` : "/")}> <Icon value={faChevronLeft}/> </HeaderButton> <HeaderTitle>{title}</HeaderTitle> </Header> <PageBody> <PageFlexRow collapseOn={Size.Tablet}> <PageFlexColumn flex={1}> <TitleLine>Programm</TitleLine> <Blob fillOn={Size.Any}> <BlobText>Navn</BlobText> <BlobInput type="text" value={name} onChange={setName} flex={1}/> </Blob> <Blob color={canSave ? "indigo" : "gray"} onClick={onSave} disabled={!canSave}> <BlobText> <Icon value={faCheck}/> Lagre </BlobText> </Blob> </PageFlexColumn> <PageFlexColumn flex={1}> <TitleLine>Steg</TitleLine> {steps.map((s, i) => { const onChange = (arg: Partial<StepOption>) => setSteps(prev => { return prev.map((ps, pi) => (pi === i ? {...ps, ...arg} : ps)); });
const onRemove = () => setSteps(prev => { return prev.filter((ignored, pi) => pi !== i); })
return ( <PageFlexRow key={i}> <Blob> <BlobText> <Icon value={faArrowUpRightDots}/> </BlobText> <BlobInput type="number" value={s.level} onChange={level => onChange({level})} /> </Blob> <Blob flex={2}> <BlobText> <Icon value={faStopwatch}/> </BlobText> <BlobInput flex={1} type="text" value={s.duration} placeholder="Manuell" onChange={duration => onChange({duration})} /> </Blob> <Blob color="red" onClick={onRemove}> <BlobText> <Icon value={faClose}/> </BlobText> </Blob> </PageFlexRow> ); })} <Blob color="green" onClick={() => setSteps(prev => [...prev, {duration: "", level: 1}])}> <BlobText> <Icon value={faPlus}/> Legg til </BlobText> </Blob> </PageFlexColumn> </PageFlexRow> </PageBody> </Page> ); }
|