Changeset b3d5fed for frontend/src


Ignore:
Timestamp:
05/05/26 18:06:26 (2 months ago)
Author:
Andrej <asumanovski@…>
Branches:
master
Children:
a8381b1
Parents:
e9a0543
Message:

training graph developed

Location:
frontend/src
Files:
3 added
2 edited

Legend:

Unmodified
Added
Removed
  • frontend/src/pages/Dashboard/pages/Training/TrainingTracking.jsx

    re9a0543 rb3d5fed  
    22import { useNavigate } from "react-router-dom";
    33import api from "../../../../api/axios";
    4 import graphPlaceholder from "../../../../assets/graph-placeholder.svg";
    54
    65import TrainingTrackingHeader from "./components/TrainingTrackingHeader.jsx";
     
    103102        onAddSession={() => navigate("/dashboard/training/sessions/new")}
    104103      />
    105       <TrainingProgressCard graphSrc={graphPlaceholder} />
     104      <TrainingProgressCard sessions={sessions} />
    106105      <TrainingSessionsTable
    107106        columns={columns}
  • frontend/src/pages/Dashboard/pages/Training/components/TrainingProgressCard.jsx

    re9a0543 rb3d5fed  
    1 import React from "react";
     1import React, { useMemo, useState } from "react";
    22
    3 const TrainingProgressCard = ({ graphSrc }) => {
     3import TimeRangeToggle from "../../../../../components/graphs/TimeRangeToggle.jsx";
     4import PercentChangeAreaChart from "../../../../../components/graphs/PercentChangeAreaChart.jsx";
     5import { percentChangeSeries, sumByTimeBucket } from "../../../../../utils/timeSeries.js";
     6
     7const TrainingProgressCard = ({ sessions }) => {
     8  const [range, setRange] = useState("weekly");
     9
     10  const points = useMemo(() => {
     11    const buckets = sumByTimeBucket(
     12      sessions,
     13      range,
     14      (s) => s.date,
     15      (s) => s.calories
     16    );
     17    return percentChangeSeries(buckets);
     18  }, [range, sessions]);
     19
     20  const latest = points?.length ? points[points.length - 1] : null;
     21  const latestPct = latest ? Number(latest.value ?? 0) : 0;
     22  const latestBase = latest ? Number(latest.base ?? 0) : 0;
     23
    424  return (
    525    <div className="card bg-base-200 border border-base-300">
     
    727        <div className="flex items-center justify-between gap-4">
    828          <h2 className="card-title">Progress</h2>
    9           <span className="badge badge-ghost">Graph placeholder</span>
     29          <div className="flex items-center gap-3">
     30            <span className="badge badge-ghost">
     31              {latestPct >= 0 ? "+" : ""}
     32              {latestPct.toFixed(1)}% (last)
     33            </span>
     34            <TimeRangeToggle value={range} onChange={setRange} />
     35          </div>
    1036        </div>
    11         <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100">
    12           <img
    13             src={graphSrc}
    14             alt="Training progress graph placeholder"
    15             className="block h-65 w-full object-cover"
    16           />
     37
     38        <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-2">
     39          {points.length < 2 ? (
     40            <div className="flex h-65 items-center justify-center text-sm opacity-70">
     41              Add at least 2 sessions to see % change.
     42            </div>
     43          ) : (
     44            <PercentChangeAreaChart
     45              points={points}
     46              granularity={range}
     47              height={260}
     48            />
     49          )}
     50        </div>
     51
     52        <div className="mt-2 text-xs opacity-70">
     53          Showing percentage change in calories burned per {range} bucket. Latest bucket total: {Math.round(latestBase)}.
    1754        </div>
    1855      </div>
Note: See TracChangeset for help on using the changeset viewer.