Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 50 additions & 42 deletions app/src/components/Report.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -387,48 +387,56 @@ export default function Report({ onShowHome, onShowLogger, onShowHistory, onShow
)}

<div style={{ background: "var(--cds-layer-01)", border: "1px solid var(--cds-border-subtle-01)", padding: 14 }}>
<p style={{ ...labelStyle, marginBottom: 8 }}>Muskelfrekvens</p>
<div style={{ display: "flex", alignItems: "center", gap: 10, paddingBottom: 6, borderBottom: "1px solid var(--cds-border-strong-01)", marginBottom: 2 }}>
<span style={{ fontSize: 10, color: "var(--cds-text-secondary)", width: 140, flexShrink: 0, fontFamily: "var(--cds-font-mono)", letterSpacing: "1px" }}>MUSKEL</span>
<div style={{ flex: 1 }} />
<span style={{ fontSize: 10, color: "var(--cds-text-secondary)", fontFamily: "var(--cds-font-mono)", width: 36, textAlign: "right", flexShrink: 0, letterSpacing: "1px" }}>ØKT</span>
<span style={{ fontSize: 10, color: "var(--cds-text-secondary)", fontFamily: "var(--cds-font-mono)", width: 40, textAlign: "right", flexShrink: 0, letterSpacing: "1px" }}>SETT</span>
</div>
{frequencyTable.map(({ id, primary, secondary }) => {
const barWidth = maxPrimaryCount > 0 ? (primary / maxPrimaryCount) * 100 : 0;
const countColor = primary > 0
? "var(--cds-text-primary)"
: secondary > 0
? "#4589ff"
: "var(--cds-text-disabled)";
const countLabel = primary > 0
? String(primary)
: secondary > 0
? `(${secondary})`
: "—";
return (
<div key={id} style={{ display: "flex", alignItems: "center", gap: 10, padding: "6px 0", borderBottom: "1px solid var(--cds-border-subtle-01)" }}>
<span style={{ fontSize: 12, color: "var(--cds-text-primary)", width: 140, flexShrink: 0 }}>
{muscleExercises[id]?.size > 0 ? (
<DefinitionTooltip definition={[...muscleExercises[id]].join(", ")} openOnHover align="bottom">
{MUSCLES[id]?.label || id}
</DefinitionTooltip>
) : MUSCLES[id]?.label || id}
</span>
<div style={{ flex: 1, height: 6, background: "var(--cds-layer-02)" }}>
{primary > 0 && (
<div style={{ height: "100%", width: `${barWidth}%`, background: "var(--heat-4)" }} />
)}
</div>
<span style={{ fontSize: 11, color: countColor, fontFamily: "var(--cds-font-mono)", width: 36, textAlign: "right", flexShrink: 0 }}>
{countLabel}
</span>
<span style={{ fontSize: 11, color: "var(--cds-text-secondary)", fontFamily: "var(--cds-font-mono)", width: 40, textAlign: "right", flexShrink: 0 }}>
{muscleVolume[id] > 0 ? muscleVolume[id] : "—"}
</span>
</div>
);
})}
<p style={{ ...labelStyle, marginBottom: 8 }} id="freq-table-label">Muskelfrekvens</p>
<table aria-labelledby="freq-table-label" style={{ width: "100%", borderCollapse: "collapse", tableLayout: "fixed" }}>
<thead>
<tr style={{ borderBottom: "1px solid var(--cds-border-strong-01)" }}>
<th scope="col" style={{ fontSize: 10, color: "var(--cds-text-secondary)", fontFamily: "var(--cds-font-mono)", letterSpacing: "1px", textAlign: "left", paddingBottom: 6, width: 140 }}>MUSKEL</th>
<th scope="col" aria-label="Frekvensbar" style={{ width: "100%" }} />
<th scope="col" style={{ fontSize: 10, color: "var(--cds-text-secondary)", fontFamily: "var(--cds-font-mono)", letterSpacing: "1px", textAlign: "right", paddingBottom: 6, width: 36 }}>ØKT</th>
<th scope="col" style={{ fontSize: 10, color: "var(--cds-text-secondary)", fontFamily: "var(--cds-font-mono)", letterSpacing: "1px", textAlign: "right", paddingBottom: 6, width: 40 }}>SETT</th>
</tr>
</thead>
<tbody>
{frequencyTable.map(({ id, primary, secondary }) => {
const barWidth = maxPrimaryCount > 0 ? (primary / maxPrimaryCount) * 100 : 0;
const countColor = primary > 0
? "var(--cds-text-primary)"
: secondary > 0
? "#4589ff"
: "var(--cds-text-disabled)";
const countLabel = primary > 0
? String(primary)
: secondary > 0
? `(${secondary})`
: "—";
return (
<tr key={id} style={{ borderBottom: "1px solid var(--cds-border-subtle-01)" }}>
<td style={{ fontSize: 12, color: "var(--cds-text-primary)", padding: "6px 0" }}>
{muscleExercises[id]?.size > 0 ? (
<DefinitionTooltip definition={[...muscleExercises[id]].join(", ")} openOnHover align="bottom">
{MUSCLES[id]?.label || id}
</DefinitionTooltip>
) : MUSCLES[id]?.label || id}
</td>
<td style={{ padding: "6px 10px" }}>
<div style={{ height: 6, background: "var(--cds-layer-02)" }}>
{primary > 0 && (
<div style={{ height: "100%", width: `${barWidth}%`, background: "var(--heat-4)" }} />
)}
</div>
</td>
<td style={{ fontSize: 11, color: countColor, fontFamily: "var(--cds-font-mono)", textAlign: "right", padding: "6px 0" }}>
{countLabel}
</td>
<td style={{ fontSize: 11, color: "var(--cds-text-secondary)", fontFamily: "var(--cds-font-mono)", textAlign: "right", padding: "6px 0" }}>
{muscleVolume[id] > 0 ? muscleVolume[id] : "—"}
</td>
</tr>
);
})}
</tbody>
</table>
</div>

{sessionCount > 0 && (
Expand Down
4 changes: 4 additions & 0 deletions app/src/lib/bodymap.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";

export const EX_DB = [

Check warning on line 3 in app/src/lib/bodymap.jsx

View workflow job for this annotation

GitHub Actions / Lint, test and audit

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
{ kw: ["benkpress","bench press","chest press","push up","pushup","armhevinger","brystpress","flies","fly","pec deck"], p: ["chest"], s: ["shoulders_front","triceps"] },
{ kw: ["skulderpress","shoulder press","overhead press","ohp","militærpress","military press","arnold"], p: ["shoulders_front","shoulders_side"], s: ["triceps","traps"] },
{ kw: ["sidehev","lateral raise","lateral"], p: ["shoulders_side"], s: [] },
Expand All @@ -25,7 +25,7 @@
{ kw: ["shrug","skuldertrekk","upright row"], p: ["traps"], s: ["shoulders_side"] },
];

export const MUSCLES = {

Check warning on line 28 in app/src/lib/bodymap.jsx

View workflow job for this annotation

GitHub Actions / Lint, test and audit

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
chest: { label: "Bryst", view: "front" },
shoulders_front: { label: "Fremre skuldre", view: "front" },
shoulders_side: { label: "Laterale skuldre", view: "front" },
Expand All @@ -46,7 +46,7 @@
};

// shape.d = SVG path string; otherwise ellipse (cx/cy/rx/ry)
export const SHAPES = {

Check warning on line 49 in app/src/lib/bodymap.jsx

View workflow job for this annotation

GitHub Actions / Lint, test and audit

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
chest: [{ cx:62, cy:80, rx:18, ry:13 }, { cx:98, cy:80, rx:18, ry:13 }],
shoulders_front: [{ cx:42, cy:60, rx:10, ry:8 }, { cx:118, cy:60, rx:10, ry:8 }],
shoulders_side: [{ cx:23, cy:68, rx:9, ry:8 }, { cx:137, cy:68, rx:9, ry:8 }],
Expand Down Expand Up @@ -83,7 +83,7 @@
export const SEC_HOVER = "none";
export const SEC_STROKE = "none";

export function useIsMobile(breakpoint = 500) {

Check warning on line 86 in app/src/lib/bodymap.jsx

View workflow job for this annotation

GitHub Actions / Lint, test and audit

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
const [mobile, setMobile] = React.useState(() => window.innerWidth < breakpoint);
React.useEffect(() => {
const fn = () => setMobile(window.innerWidth < breakpoint);
Expand All @@ -93,7 +93,7 @@
return mobile;
}

export function calcMuscles(exercises) {

Check warning on line 96 in app/src/lib/bodymap.jsx

View workflow job for this annotation

GitHub Actions / Lint, test and audit

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
const p = new Set(), s = new Set();
exercises.forEach(ex => {
if (ex.primary?.length || ex.secondary?.length) {
Expand Down Expand Up @@ -145,6 +145,8 @@
return (
<div ref={wrapRef} style={{ position: "relative", width: "100%" }}>
<svg viewBox="0 0 160 360" xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label={`Treningsfrekvenskart, ${view === "front" ? "fremside" : "bakside"}`}
style={{ width: "100%", height: "auto", display: "block" }}>
<defs>
<pattern id={`sec-stripe-${view}`} patternUnits="userSpaceOnUse" width="6" height="6" patternTransform="rotate(45 0 0)">
Expand Down Expand Up @@ -271,6 +273,8 @@
return (
<div ref={wrapRef} style={{ position: "relative", width: "100%" }}>
<svg viewBox="0 0 160 360" xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label={`Muskelkart, ${view === "front" ? "fremside" : "bakside"}. Primære: ${[...pSet].map(id => MUSCLES[id]?.label).filter(Boolean).join(", ") || "ingen"}.`}
style={{ width: "100%", height: "auto", display: "block" }}>
<defs>
<pattern id={`sec-stripe-${view}`} patternUnits="userSpaceOnUse" width="6" height="6" patternTransform="rotate(45 0 0)">
Expand Down
Loading