@burdenoff/microfe-mybodyshield 2026.827.1 → 2026.830.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/mybodyshield/MyBodyShieldRoot.d.ts.map +1 -1
  2. package/dist/mybodyshield/MyBodyShieldRoot.js +54 -56
  3. package/dist/mybodyshield/MyBodyShieldRoot.js.map +1 -1
  4. package/dist/mybodyshield/MyBodyShieldRoutes.d.ts.map +1 -1
  5. package/dist/mybodyshield/MyBodyShieldRoutes.js +121 -62
  6. package/dist/mybodyshield/MyBodyShieldRoutes.js.map +1 -1
  7. package/dist/mybodyshield/components/EvidenceUpload.d.ts.map +1 -1
  8. package/dist/mybodyshield/components/EvidenceUpload.js +46 -45
  9. package/dist/mybodyshield/components/EvidenceUpload.js.map +1 -1
  10. package/dist/mybodyshield/components/FileLink.d.ts.map +1 -1
  11. package/dist/mybodyshield/components/FileLink.js +27 -18
  12. package/dist/mybodyshield/components/FileLink.js.map +1 -1
  13. package/dist/mybodyshield/components/MybDiscussion.d.ts +1 -1
  14. package/dist/mybodyshield/components/MybDiscussion.d.ts.map +1 -1
  15. package/dist/mybodyshield/components/MybDiscussion.js +59 -58
  16. package/dist/mybodyshield/components/MybDiscussion.js.map +1 -1
  17. package/dist/mybodyshield/components/MybTags.d.ts +1 -1
  18. package/dist/mybodyshield/components/MybTags.d.ts.map +1 -1
  19. package/dist/mybodyshield/components/MybTags.js +83 -74
  20. package/dist/mybodyshield/components/MybTags.js.map +1 -1
  21. package/dist/mybodyshield/components/PageDisabled.d.ts.map +1 -1
  22. package/dist/mybodyshield/components/PageDisabled.js +16 -11
  23. package/dist/mybodyshield/components/PageDisabled.js.map +1 -1
  24. package/dist/mybodyshield/components/Pagination.d.ts.map +1 -1
  25. package/dist/mybodyshield/components/Pagination.js +36 -27
  26. package/dist/mybodyshield/components/Pagination.js.map +1 -1
  27. package/dist/mybodyshield/components/StateViews.d.ts.map +1 -1
  28. package/dist/mybodyshield/components/StateViews.js +42 -34
  29. package/dist/mybodyshield/components/StateViews.js.map +1 -1
  30. package/dist/mybodyshield/components/UserSearchSelect.d.ts.map +1 -1
  31. package/dist/mybodyshield/components/UserSearchSelect.js +66 -68
  32. package/dist/mybodyshield/components/UserSearchSelect.js.map +1 -1
  33. package/dist/mybodyshield/hooks/index.d.ts +1 -0
  34. package/dist/mybodyshield/hooks/index.d.ts.map +1 -1
  35. package/dist/mybodyshield/hooks/index.js +1 -0
  36. package/dist/mybodyshield/hooks/useTr.d.ts +5 -0
  37. package/dist/mybodyshield/hooks/useTr.d.ts.map +1 -0
  38. package/dist/mybodyshield/hooks/useTr.js +12 -0
  39. package/dist/mybodyshield/hooks/useTr.js.map +1 -0
  40. package/dist/mybodyshield/pages/DashboardPage.d.ts.map +1 -1
  41. package/dist/mybodyshield/pages/DashboardPage.js +157 -136
  42. package/dist/mybodyshield/pages/DashboardPage.js.map +1 -1
  43. package/dist/mybodyshield/pages/SettingsPage.d.ts.map +1 -1
  44. package/dist/mybodyshield/pages/SettingsPage.js +50 -59
  45. package/dist/mybodyshield/pages/SettingsPage.js.map +1 -1
  46. package/dist/mybodyshield/pages/_shared/visuals.d.ts +2 -1
  47. package/dist/mybodyshield/pages/_shared/visuals.d.ts.map +1 -1
  48. package/dist/mybodyshield/pages/_shared/visuals.js +91 -81
  49. package/dist/mybodyshield/pages/_shared/visuals.js.map +1 -1
  50. package/dist/mybodyshield/pages/ai/AiControlsPage.d.ts.map +1 -1
  51. package/dist/mybodyshield/pages/ai/AiControlsPage.js +255 -266
  52. package/dist/mybodyshield/pages/ai/AiControlsPage.js.map +1 -1
  53. package/dist/mybodyshield/pages/coaching/CoachingPage.d.ts.map +1 -1
  54. package/dist/mybodyshield/pages/coaching/CoachingPage.js +321 -301
  55. package/dist/mybodyshield/pages/coaching/CoachingPage.js.map +1 -1
  56. package/dist/mybodyshield/pages/goals/GoalsPage.d.ts.map +1 -1
  57. package/dist/mybodyshield/pages/goals/GoalsPage.js +247 -251
  58. package/dist/mybodyshield/pages/goals/GoalsPage.js.map +1 -1
  59. package/dist/mybodyshield/pages/insights/InsightsCharts.d.ts.map +1 -1
  60. package/dist/mybodyshield/pages/insights/InsightsCharts.js +216 -213
  61. package/dist/mybodyshield/pages/insights/InsightsCharts.js.map +1 -1
  62. package/dist/mybodyshield/pages/insights/InsightsPage.d.ts.map +1 -1
  63. package/dist/mybodyshield/pages/insights/InsightsPage.js +290 -284
  64. package/dist/mybodyshield/pages/insights/InsightsPage.js.map +1 -1
  65. package/dist/mybodyshield/pages/nutrition/NutritionPage.d.ts.map +1 -1
  66. package/dist/mybodyshield/pages/nutrition/NutritionPage.js +575 -529
  67. package/dist/mybodyshield/pages/nutrition/NutritionPage.js.map +1 -1
  68. package/dist/mybodyshield/pages/programs/ProgramDetailPage.d.ts.map +1 -1
  69. package/dist/mybodyshield/pages/programs/ProgramDetailPage.js +333 -275
  70. package/dist/mybodyshield/pages/programs/ProgramDetailPage.js.map +1 -1
  71. package/dist/mybodyshield/pages/programs/ProgramsPage.d.ts.map +1 -1
  72. package/dist/mybodyshield/pages/programs/ProgramsPage.js +258 -253
  73. package/dist/mybodyshield/pages/programs/ProgramsPage.js.map +1 -1
  74. package/dist/mybodyshield/pages/progress/ProgressPage.d.ts.map +1 -1
  75. package/dist/mybodyshield/pages/progress/ProgressPage.js +271 -254
  76. package/dist/mybodyshield/pages/progress/ProgressPage.js.map +1 -1
  77. package/dist/mybodyshield/pages/recovery/RecoveryPage.d.ts.map +1 -1
  78. package/dist/mybodyshield/pages/recovery/RecoveryPage.js +206 -200
  79. package/dist/mybodyshield/pages/recovery/RecoveryPage.js.map +1 -1
  80. package/dist/mybodyshield/pages/train/SessionDetailPage.d.ts.map +1 -1
  81. package/dist/mybodyshield/pages/train/SessionDetailPage.js +327 -294
  82. package/dist/mybodyshield/pages/train/SessionDetailPage.js.map +1 -1
  83. package/dist/mybodyshield/pages/train/SessionsPage.d.ts.map +1 -1
  84. package/dist/mybodyshield/pages/train/SessionsPage.js +180 -163
  85. package/dist/mybodyshield/pages/train/SessionsPage.js.map +1 -1
  86. package/dist/mybodyshield/utils/i18n.d.ts +1 -2
  87. package/dist/mybodyshield/utils/i18n.d.ts.map +1 -1
  88. package/dist/mybodyshield/utils/i18n.js +15 -0
  89. package/dist/mybodyshield/utils/i18n.js.map +1 -0
  90. package/package.json +1 -1
@@ -1,33 +1,34 @@
1
1
  import { useMyBodyShield as e } from "../../context/MyBodyShieldContext.js";
2
2
  import { PageLayout as t } from "../../components/PageLayout.js";
3
3
  import { MetricsCard as n } from "../../components/MetricsCard.js";
4
- import { formatDateTime as ee, formatDuration as r, formatEnumLabel as te, formatKcal as ne, formatNumber as i, formatRelativeTime as a, formatWeight as o } from "../../utils/formatters.js";
4
+ import { formatDateTime as r, formatDuration as i, formatEnumLabel as ee, formatKcal as te, formatNumber as a, formatRelativeTime as o, formatWeight as ne } from "../../utils/formatters.js";
5
5
  import { StatusBadge as re } from "../../components/StatusBadge.js";
6
6
  import { EmptyState as ie } from "../../components/EmptyState.js";
7
- import { ErrorView as ae, LoadingView as oe } from "../../components/StateViews.js";
8
7
  import "../../context/index.js";
9
- import { useMybCompleteSession as se, useMybExerciseBestSet as ce, useMybLogSet as le, useMybSession as ue, useMybWorkoutExercises as de } from "../../hooks/useMyBodyShieldApi.js";
10
- import { useMyBodyShieldAnalytics as fe } from "../../hooks/useMyBodyShieldAnalytics.js";
8
+ import { useMybCompleteSession as ae, useMybExerciseBestSet as oe, useMybLogSet as se, useMybSession as ce, useMybWorkoutExercises as le } from "../../hooks/useMyBodyShieldApi.js";
9
+ import { useMyBodyShieldAnalytics as ue } from "../../hooks/useMyBodyShieldAnalytics.js";
10
+ import { useTr as de } from "../../hooks/useTr.js";
11
11
  import "../../hooks/index.js";
12
- import { MybDiscussion as pe } from "../../components/MybDiscussion.js";
12
+ import { ErrorView as fe, LoadingView as pe } from "../../components/StateViews.js";
13
+ import { MybDiscussion as me } from "../../components/MybDiscussion.js";
13
14
  import "../../components/index.js";
14
15
  import { motion as s } from "../../../node_modules/framer-motion/dist/es/render/components/motion/proxy.js";
15
- import { useReducedMotion as me } from "../../../node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js";
16
+ import { useReducedMotion as he } from "../../../node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js";
16
17
  import { IconChip as c } from "../_shared/visuals.js";
17
- import { listPendingActionsForSession as he } from "../../lib/offlineSessionQueue.js";
18
- import { useOfflineSessionSync as ge } from "../../lib/useOfflineSessionSync.js";
19
- import { useCallback as _e, useEffect as ve, useMemo as l, useState as u } from "react";
20
- import { AlertTriangle as ye, ArrowLeft as be, CheckCircle2 as xe, ChevronLeft as Se, ChevronRight as Ce, Dumbbell as d, Flame as we, Gauge as Te, ListChecks as Ee, Plus as f, Ruler as De, Timer as p, Trophy as Oe, Weight as ke, WifiOff as Ae, X as je } from "lucide-react";
21
- import { useParams as Me } from "react-router";
22
- import { Fragment as Ne, jsx as m, jsxs as h } from "react/jsx-runtime";
23
- import { Button as g, GlassCard as _, Input as v, Label as y, ResponsiveDialog as Pe, ResponsiveDialogContent as Fe, ResponsiveDialogDescription as Ie, ResponsiveDialogFooter as Le, ResponsiveDialogHeader as Re, ResponsiveDialogTitle as ze, Switch as Be, Textarea as Ve } from "@burdenoff/fe-libs/ui";
18
+ import { listPendingActionsForSession as ge } from "../../lib/offlineSessionQueue.js";
19
+ import { useOfflineSessionSync as _e } from "../../lib/useOfflineSessionSync.js";
20
+ import { useCallback as ve, useEffect as ye, useMemo as l, useState as u } from "react";
21
+ import { AlertTriangle as be, ArrowLeft as xe, CheckCircle2 as Se, ChevronLeft as Ce, ChevronRight as we, Dumbbell as d, Flame as Te, Gauge as Ee, ListChecks as De, Plus as f, Ruler as Oe, Timer as p, Trophy as ke, Weight as Ae, WifiOff as je, X as Me } from "lucide-react";
22
+ import { useParams as Ne } from "react-router";
23
+ import { Fragment as Pe, jsx as m, jsxs as h } from "react/jsx-runtime";
24
+ import { Button as g, GlassCard as _, Input as v, Label as y, ResponsiveDialog as Fe, ResponsiveDialogContent as Ie, ResponsiveDialogDescription as Le, ResponsiveDialogFooter as Re, ResponsiveDialogHeader as ze, ResponsiveDialogTitle as Be, Switch as Ve, Textarea as He } from "@burdenoff/fe-libs/ui";
24
25
  //#region src/mybodyshield/pages/train/SessionDetailPage.tsx
25
- function He(e) {
26
+ function Ue(e) {
26
27
  if (typeof navigator < "u" && !navigator.onLine || e instanceof TypeError) return !0;
27
28
  let t = e instanceof Error ? e.message.toLowerCase() : "";
28
29
  return t.includes("failed to fetch") || t.includes("load failed") || t.includes("network");
29
30
  }
30
- function Ue(e, t) {
31
+ function We(e, t) {
31
32
  let n = e.input;
32
33
  return {
33
34
  id: `pending-${e.clientActionId}`,
@@ -44,8 +45,8 @@ function Ue(e, t) {
44
45
  updatedAt: e.capturedAt
45
46
  };
46
47
  }
47
- var We = 90, Ge = [];
48
- function Ke(e, t, n) {
48
+ var Ge = 90, Ke = [];
49
+ function qe(e, t, n) {
49
50
  return n ? e > n.weight || e === n.weight && t > n.reps : !1;
50
51
  }
51
52
  var b = [
@@ -53,7 +54,7 @@ var b = [
53
54
  1,
54
55
  .3,
55
56
  1
56
- ], qe = {
57
+ ], Je = {
57
58
  hidden: {},
58
59
  show: { transition: { staggerChildren: .06 } }
59
60
  }, x = {
@@ -84,23 +85,23 @@ var C = {
84
85
  distanceM: "",
85
86
  durationSec: "",
86
87
  isPersonalRecord: !1
87
- }, Je = {
88
+ }, Ye = {
88
89
  caloriesBurned: "",
89
90
  perceivedExertion: "",
90
91
  notes: ""
91
92
  };
92
93
  function w() {
93
- let { navigateTo: w, workspaceId: Ye } = e(), T = me(), { id: E } = Me();
94
- fe();
95
- let D = ue(E), O = le(), k = se(), Xe = de(D.data?.workoutId ?? void 0), A = ge((e) => O.mutateAsync(e), (e) => k.mutateAsync(e), () => D.refetch()), [j, Ze] = u([]), M = _e(() => {
96
- E && he(E).then(Ze);
94
+ let w = de(), { navigateTo: Xe, workspaceId: Ze } = e(), T = he(), { id: E } = Ne();
95
+ ue();
96
+ let D = ce(E), O = se(), k = ae(), Qe = le(D.data?.workoutId ?? void 0), A = _e((e) => O.mutateAsync(e), (e) => k.mutateAsync(e), () => D.refetch()), [j, $e] = u([]), M = ve(() => {
97
+ E && ge(E).then($e);
97
98
  }, [E]);
98
- ve(() => {
99
+ ye(() => {
99
100
  M();
100
101
  }, [M, A.pendingCount]);
101
- let Qe = l(() => E ? j.filter((e) => e.type === "LOG_SET").map((e) => Ue(e, E)) : [], [j, E]), $e = j.some((e) => e.type === "COMPLETE_SESSION"), [et, N] = u(!1), [P, F] = u(C), [tt, I] = u(null), [nt, L] = u(!1), [rt, R] = u(!1), [z, B] = u(Je), [it, V] = u(null), [at, H] = u(null), [ot, st] = u(D.data?.workoutId), [ct, U] = u(null), [lt, W] = u(0), G = ce(P.exerciseName), K = D.data, q = l(() => [...K?.sets ?? [], ...Qe], [K?.sets, Qe]), J = l(() => {
102
+ let et = l(() => E ? j.filter((e) => e.type === "LOG_SET").map((e) => We(e, E)) : [], [j, E]), tt = j.some((e) => e.type === "COMPLETE_SESSION"), [nt, N] = u(!1), [P, F] = u(C), [rt, I] = u(null), [it, L] = u(!1), [at, R] = u(!1), [z, B] = u(Ye), [ot, V] = u(null), [st, ct] = u(null), [lt, ut] = u(D.data?.workoutId), [dt, H] = u(null), [ft, U] = u(0), W = oe(P.exerciseName), G = D.data, K = l(() => [...G?.sets ?? [], ...et], [G?.sets, et]), q = l(() => {
102
103
  let e = /* @__PURE__ */ new Map();
103
- for (let t of q) {
104
+ for (let t of K) {
104
105
  let n = e.get(t.exerciseName) ?? [];
105
106
  n.push(t), e.set(t.exerciseName, n);
106
107
  }
@@ -108,51 +109,51 @@ function w() {
108
109
  name: e,
109
110
  sets: t.slice().sort((e, t) => e.setNumber - t.setNumber)
110
111
  }));
111
- }, [q]), ut = l(() => q.reduce((e, t) => e + t.reps * t.weight, 0), [q]), dt = K?.startedAt, ft = K?.completedAt, pt = l(() => {
112
- if (!dt || !ft) return;
113
- let e = new Date(dt).getTime(), t = new Date(ft).getTime();
112
+ }, [K]), pt = l(() => K.reduce((e, t) => e + t.reps * t.weight, 0), [K]), mt = G?.startedAt, ht = G?.completedAt, gt = l(() => {
113
+ if (!mt || !ht) return;
114
+ let e = new Date(mt).getTime(), t = new Date(ht).getTime();
114
115
  if (!(!Number.isFinite(e) || !Number.isFinite(t) || t < e)) return (t - e) / 1e3;
115
- }, [dt, ft]), Y = Xe.data ?? Ge, X = l(() => {
116
+ }, [mt, ht]), J = Qe.data ?? Ke, Y = l(() => {
116
117
  let e = /* @__PURE__ */ new Map();
117
- for (let t of J) e.set(t.name, t.sets.length);
118
+ for (let t of q) e.set(t.name, t.sets.length);
118
119
  return e;
119
- }, [J]), mt = l(() => {
120
- if (Y.length === 0) return 0;
121
- let e = Y.findIndex((e) => (X.get(e.name) ?? 0) < Math.max(e.sets, 1));
122
- return e === -1 ? Y.length - 1 : e;
123
- }, [Y, X]), Z = Math.min(at ?? mt, Math.max(Y.length - 1, 0)), Q = Y[Z], ht = Y.length > 0 && Y.every((e) => (X.get(e.name) ?? 0) >= Math.max(e.sets, 1));
124
- D.data?.workoutId !== ot && (st(D.data?.workoutId), H(null)), ve(() => {
125
- if (ct == null) return;
120
+ }, [q]), _t = l(() => {
121
+ if (J.length === 0) return 0;
122
+ let e = J.findIndex((e) => (Y.get(e.name) ?? 0) < Math.max(e.sets, 1));
123
+ return e === -1 ? J.length - 1 : e;
124
+ }, [J, Y]), X = Math.min(st ?? _t, Math.max(J.length - 1, 0)), Z = J[X], vt = J.length > 0 && J.every((e) => (Y.get(e.name) ?? 0) >= Math.max(e.sets, 1));
125
+ D.data?.workoutId !== lt && (ut(D.data?.workoutId), ct(null)), ye(() => {
126
+ if (dt == null) return;
126
127
  let e = window.setInterval(() => {
127
- let e = Math.max(0, Math.ceil((ct - Date.now()) / 1e3));
128
- W(e), e <= 0 && U(null);
128
+ let e = Math.max(0, Math.ceil((dt - Date.now()) / 1e3));
129
+ U(e), e <= 0 && H(null);
129
130
  }, 1e3);
130
131
  return () => window.clearInterval(e);
131
- }, [ct]);
132
- let gt = S(P.weight) ?? 0, _t = S(P.reps) ?? 0, vt = P.exerciseName.trim().length > 0 && Ke(gt, _t, G.data), yt = nt ? P.isPersonalRecord : vt;
132
+ }, [dt]);
133
+ let yt = S(P.weight) ?? 0, bt = S(P.reps) ?? 0, xt = P.exerciseName.trim().length > 0 && qe(yt, bt, W.data), Q = it ? P.isPersonalRecord : xt;
133
134
  if (!E) return /* @__PURE__ */ m(t, {
134
- title: "Workout session",
135
- children: /* @__PURE__ */ m(ae, {
136
- message: "No session was specified.",
137
- onRetry: () => w("train")
135
+ title: w("mybodyshield.pages.sessionDetail.title", "Workout session"),
136
+ children: /* @__PURE__ */ m(fe, {
137
+ message: w("mybodyshield.pages.sessionDetail.noSessionSpecified", "No session was specified."),
138
+ onRetry: () => Xe("train")
138
139
  })
139
140
  });
140
141
  if (D.isLoading) return /* @__PURE__ */ m(t, {
141
- title: "Workout session",
142
- children: /* @__PURE__ */ m(oe, { label: "Loading session…" })
142
+ title: w("mybodyshield.pages.sessionDetail.title", "Workout session"),
143
+ children: /* @__PURE__ */ m(pe, { label: w("mybodyshield.pages.sessionDetail.loading", "Loading session…") })
143
144
  });
144
- if (D.isError || !K) return /* @__PURE__ */ m(t, {
145
- title: "Workout session",
146
- children: /* @__PURE__ */ m(ae, {
147
- title: "Session not found",
148
- message: "This workout session may have been removed, or you don't have access to it.",
145
+ if (D.isError || !G) return /* @__PURE__ */ m(t, {
146
+ title: w("mybodyshield.pages.sessionDetail.title", "Workout session"),
147
+ children: /* @__PURE__ */ m(fe, {
148
+ title: w("mybodyshield.pages.sessionDetail.notFound", "Session not found"),
149
+ message: w("mybodyshield.pages.sessionDetail.notFoundDescription", "This workout session may have been removed, or you don't have access to it."),
149
150
  onRetry: () => D.refetch()
150
151
  })
151
152
  });
152
- let $ = K.status === "IN_PROGRESS", bt = K.completedAt ? `Completed ${a(K.completedAt)}` : K.startedAt ? `Started ${a(K.startedAt)}` : K.scheduledFor ? `Scheduled ${a(K.scheduledFor)}` : `Created ${a(K.createdAt)}`, xt = () => {
153
+ let $ = G.status === "IN_PROGRESS", St = G.completedAt ? w("mybodyshield.pages.sessionDetail.completedAgo", "Completed {{time}}", { time: o(G.completedAt) }) : G.startedAt ? w("mybodyshield.pages.sessionDetail.startedAgo", "Started {{time}}", { time: o(G.startedAt) }) : G.scheduledFor ? w("mybodyshield.pages.sessionDetail.scheduledAgo", "Scheduled {{time}}", { time: o(G.scheduledFor) }) : w("mybodyshield.pages.sessionDetail.createdAgo", "Created {{time}}", { time: o(G.createdAt) }), Ct = () => {
153
154
  F(C), I(null), L(!1), N(!0);
154
- }, St = (e) => {
155
- let t = X.get(e.name) ?? 0;
155
+ }, wt = (e) => {
156
+ let t = Y.get(e.name) ?? 0;
156
157
  F({
157
158
  ...C,
158
159
  exerciseName: e.name,
@@ -160,42 +161,116 @@ function w() {
160
161
  reps: e.reps > 0 ? String(e.reps) : "",
161
162
  weight: e.targetWeight > 0 ? String(e.targetWeight) : ""
162
163
  }), I(null), L(!1), N(!0);
163
- };
164
+ }, Tt = async () => {
165
+ I(null);
166
+ let e = P.exerciseName.trim();
167
+ if (!e) {
168
+ I(w("mybodyshield.pages.sessionDetail.exerciseNameRequired", "Exercise name is required."));
169
+ return;
170
+ }
171
+ let t = {
172
+ exerciseName: e,
173
+ setNumber: S(P.setNumber),
174
+ reps: S(P.reps),
175
+ weight: S(P.weight),
176
+ distanceM: S(P.distanceM),
177
+ durationSec: S(P.durationSec),
178
+ isPersonalRecord: Q
179
+ }, n = (t) => {
180
+ F({
181
+ ...C,
182
+ exerciseName: e,
183
+ setNumber: String(t)
184
+ }), L(!1);
185
+ let n = Z && Z.name === e && Z.restSeconds > 0 ? Z.restSeconds : Ge;
186
+ H(Date.now() + n * 1e3), U(n);
187
+ };
188
+ if (!A.isOnline) {
189
+ await A.enqueueLogSet(E, t), M(), n((S(P.setNumber) ?? K.length) + 1);
190
+ return;
191
+ }
192
+ try {
193
+ n((await O.mutateAsync({
194
+ sessionId: E,
195
+ ...t
196
+ })).setNumber + 1);
197
+ } catch (e) {
198
+ if (Ue(e)) {
199
+ await A.enqueueLogSet(E, t), M(), n((S(P.setNumber) ?? K.length) + 1);
200
+ return;
201
+ }
202
+ I(e instanceof Error ? e.message : w("mybodyshield.pages.sessionDetail.failedToLogSet", "Failed to log the set."));
203
+ }
204
+ }, Et = () => {
205
+ B(Ye), V(null), R(!0);
206
+ }, Dt = async () => {
207
+ V(null);
208
+ let e = {
209
+ caloriesBurned: S(z.caloriesBurned),
210
+ perceivedExertion: S(z.perceivedExertion),
211
+ notes: z.notes.trim() ? z.notes.trim() : void 0
212
+ };
213
+ if (!A.isOnline) {
214
+ await A.enqueueCompleteSession(E, e), M(), R(!1);
215
+ return;
216
+ }
217
+ try {
218
+ await k.mutateAsync({
219
+ id: E,
220
+ input: e
221
+ }), R(!1);
222
+ } catch (t) {
223
+ if (Ue(t)) {
224
+ await A.enqueueCompleteSession(E, e), M(), R(!1);
225
+ return;
226
+ }
227
+ V(t instanceof Error ? t.message : w("mybodyshield.pages.sessionDetail.failedToComplete", "Failed to complete the session."));
228
+ }
229
+ }, Ot = $ ? /* @__PURE__ */ h(Pe, { children: [/* @__PURE__ */ h(g, {
230
+ variant: "outline",
231
+ onClick: Ct,
232
+ children: [
233
+ /* @__PURE__ */ m(f, { className: "h-4 w-4" }),
234
+ " ",
235
+ w("mybodyshield.pages.sessionDetail.logSet", "Log set")
236
+ ]
237
+ }), /* @__PURE__ */ h(g, {
238
+ onClick: Et,
239
+ disabled: tt,
240
+ children: [
241
+ /* @__PURE__ */ m(Se, { className: "h-4 w-4" }),
242
+ " ",
243
+ tt ? w("mybodyshield.pages.sessionDetail.pendingSync", "Pending sync…") : w("mybodyshield.pages.sessionDetail.complete", "Complete")
244
+ ]
245
+ })] }) : void 0;
164
246
  return /* @__PURE__ */ h(t, {
165
- title: "Workout session",
166
- description: bt,
167
- actions: $ ? /* @__PURE__ */ h(Ne, { children: [/* @__PURE__ */ h(g, {
168
- variant: "outline",
169
- onClick: xt,
170
- children: [/* @__PURE__ */ m(f, { className: "h-4 w-4" }), " Log set"]
171
- }), /* @__PURE__ */ h(g, {
172
- onClick: () => {
173
- B(Je), V(null), R(!0);
174
- },
175
- disabled: $e,
176
- children: [
177
- /* @__PURE__ */ m(xe, { className: "h-4 w-4" }),
178
- " ",
179
- $e ? "Pending sync…" : "Complete"
180
- ]
181
- })] }) : void 0,
247
+ title: w("mybodyshield.pages.sessionDetail.title", "Workout session"),
248
+ description: St,
249
+ actions: Ot,
182
250
  children: [
183
251
  /* @__PURE__ */ h("button", {
184
252
  type: "button",
185
- onClick: () => w("train"),
253
+ onClick: () => Xe("train"),
186
254
  className: "mb-4 inline-flex items-center gap-1.5 text-sm font-medium text-text-secondary hover:text-text-primary",
187
- children: [/* @__PURE__ */ m(be, { className: "h-4 w-4" }), " Back to sessions"]
255
+ children: [
256
+ /* @__PURE__ */ m(xe, { className: "h-4 w-4" }),
257
+ " ",
258
+ w("mybodyshield.pages.sessionDetail.backToSessions", "Back to sessions")
259
+ ]
188
260
  }),
189
261
  (!A.isOnline || j.length > 0) && /* @__PURE__ */ h("div", {
190
262
  className: "mb-4 flex items-center gap-2 rounded-xl border border-status-warning-text/40 bg-status-warning-bg-subtle px-4 py-2.5 text-sm text-text-primary",
191
263
  children: [
192
- /* @__PURE__ */ m(Ae, { className: "h-4 w-4 shrink-0 text-status-warning-text" }),
193
- /* @__PURE__ */ m("span", { children: A.isOnline ? `Syncing ${j.length} queued ${j.length === 1 ? "action" : "actions"}…` : `You're offline — logged sets and completion will sync automatically once you're back online${j.length > 0 ? ` (${j.length} queued)` : ""}.` }),
264
+ /* @__PURE__ */ m(je, { className: "h-4 w-4 shrink-0 text-status-warning-text" }),
265
+ /* @__PURE__ */ m("span", { children: A.isOnline ? w("mybodyshield.pages.sessionDetail.syncingBanner", "Syncing {{count}} queued {{actions}}…", {
266
+ count: j.length,
267
+ actions: w(j.length === 1 ? "mybodyshield.pages.sessionDetail.action" : "mybodyshield.pages.sessionDetail.actions", j.length === 1 ? "action" : "actions")
268
+ }) : w("mybodyshield.pages.sessionDetail.offlineBanner", "You're offline — logged sets and completion will sync automatically once you're back online{{queue}}.", { queue: j.length > 0 ? ` (${j.length} ${w("mybodyshield.pages.sessionDetail.queued", "queued")})` : "" }) }),
194
269
  A.isOnline && j.length > 0 && /* @__PURE__ */ m(g, {
195
270
  variant: "ghost",
196
271
  onClick: A.syncNow,
197
272
  className: "ml-auto h-7 px-2 text-xs",
198
- children: "Retry now"
273
+ children: w("mybodyshield.pages.sessionDetail.retryNow", "Retry now")
199
274
  })
200
275
  ]
201
276
  }),
@@ -222,71 +297,71 @@ function w() {
222
297
  children: /* @__PURE__ */ h("div", {
223
298
  className: "flex items-center gap-3",
224
299
  children: [/* @__PURE__ */ m(c, {
225
- icon: m($ ? we : d, { className: "h-5 w-5" }),
300
+ icon: m($ ? Te : d, { className: "h-5 w-5" }),
226
301
  tint: $ ? "var(--color-accent-teal)" : "var(--color-accent-primary)"
227
302
  }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("div", {
228
303
  className: "flex items-center gap-2",
229
- children: /* @__PURE__ */ m(re, { status: K.status })
304
+ children: /* @__PURE__ */ m(re, { status: G.status })
230
305
  }), /* @__PURE__ */ m("p", {
231
306
  className: "mt-1 text-sm text-text-secondary",
232
- children: bt
307
+ children: St
233
308
  })] })]
234
309
  })
235
310
  }),
236
311
  /* @__PURE__ */ h("div", {
237
312
  className: "mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
238
313
  children: [
239
- K.scheduledFor && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
314
+ G.scheduledFor && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
240
315
  className: "text-xs text-text-tertiary",
241
- children: "Scheduled for"
316
+ children: w("mybodyshield.pages.sessionDetail.scheduledFor", "Scheduled for")
242
317
  }), /* @__PURE__ */ m("p", {
243
318
  className: "mt-0.5 text-sm font-medium text-text-primary",
244
- children: ee(K.scheduledFor)
319
+ children: r(G.scheduledFor)
245
320
  })] }),
246
- K.startedAt && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
321
+ G.startedAt && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
247
322
  className: "text-xs text-text-tertiary",
248
- children: "Started"
323
+ children: w("mybodyshield.pages.sessionDetail.started", "Started")
249
324
  }), /* @__PURE__ */ m("p", {
250
325
  className: "mt-0.5 text-sm font-medium text-text-primary",
251
- children: ee(K.startedAt)
326
+ children: r(G.startedAt)
252
327
  })] }),
253
- K.completedAt && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
328
+ G.completedAt && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
254
329
  className: "text-xs text-text-tertiary",
255
- children: "Completed"
330
+ children: w("mybodyshield.pages.sessionDetail.completed", "Completed")
256
331
  }), /* @__PURE__ */ m("p", {
257
332
  className: "mt-0.5 text-sm font-medium text-text-primary",
258
- children: ee(K.completedAt)
333
+ children: r(G.completedAt)
259
334
  })] }),
260
- K.perceivedExertion != null && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
335
+ G.perceivedExertion != null && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
261
336
  className: "text-xs text-text-tertiary",
262
- children: "Perceived exertion"
263
- }), /* @__PURE__ */ h("p", {
337
+ children: w("mybodyshield.pages.sessionDetail.perceivedExertion", "Perceived exertion")
338
+ }), /* @__PURE__ */ m("p", {
264
339
  className: "mt-0.5 text-sm font-medium tabular-nums text-text-primary",
265
- children: [K.perceivedExertion, "/10 RPE"]
340
+ children: w("mybodyshield.pages.sessionDetail.rpeValue", "{{rpe}}/10 RPE", { rpe: G.perceivedExertion })
266
341
  })] }),
267
- K.caloriesBurned > 0 && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
342
+ G.caloriesBurned > 0 && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
268
343
  className: "text-xs text-text-tertiary",
269
- children: "Calories burned"
344
+ children: w("mybodyshield.pages.sessionDetail.caloriesBurned", "Calories burned")
270
345
  }), /* @__PURE__ */ m("p", {
271
346
  className: "mt-0.5 text-sm font-medium tabular-nums text-text-primary",
272
- children: ne(K.caloriesBurned)
347
+ children: te(G.caloriesBurned)
273
348
  })] })
274
349
  ]
275
350
  }),
276
- K.notes && /* @__PURE__ */ h("div", {
351
+ G.notes && /* @__PURE__ */ h("div", {
277
352
  className: "mt-5 rounded-xl bg-bg-sunken/60 p-4",
278
353
  children: [/* @__PURE__ */ m("p", {
279
354
  className: "text-xs text-text-tertiary",
280
- children: "Notes"
355
+ children: w("mybodyshield.common.notes", "Notes")
281
356
  }), /* @__PURE__ */ m("p", {
282
357
  className: "mt-1 whitespace-pre-wrap text-sm text-text-secondary",
283
- children: K.notes
358
+ children: G.notes
284
359
  })]
285
360
  })
286
361
  ]
287
362
  })
288
363
  }),
289
- $ && lt > 0 && /* @__PURE__ */ m(s.div, {
364
+ $ && ft > 0 && /* @__PURE__ */ m(s.div, {
290
365
  initial: T ? !1 : {
291
366
  opacity: 0,
292
367
  y: -6
@@ -310,10 +385,10 @@ function w() {
310
385
  tint: "var(--color-accent-teal)"
311
386
  }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
312
387
  className: "text-sm font-semibold text-text-primary",
313
- children: "Resting"
314
- }), /* @__PURE__ */ h("p", {
388
+ children: w("mybodyshield.pages.sessionDetail.resting", "Resting")
389
+ }), /* @__PURE__ */ m("p", {
315
390
  className: "text-xs tabular-nums text-text-secondary",
316
- children: [r(lt), " remaining"]
391
+ children: w("mybodyshield.pages.sessionDetail.remaining", "{{time}} remaining", { time: i(ft) })
317
392
  })] })]
318
393
  }), /* @__PURE__ */ h("div", {
319
394
  className: "flex items-center gap-2",
@@ -321,21 +396,25 @@ function w() {
321
396
  variant: "outline",
322
397
  size: "sm",
323
398
  onClick: () => {
324
- U((e) => e && e + 15e3), W((e) => e + 15);
399
+ H((e) => e && e + 15e3), U((e) => e + 15);
325
400
  },
326
- children: "+15s"
401
+ children: w("mybodyshield.pages.sessionDetail.add15s", "+15s")
327
402
  }), /* @__PURE__ */ h(g, {
328
403
  variant: "ghost",
329
404
  size: "sm",
330
405
  onClick: () => {
331
- U(null), W(0);
406
+ H(null), U(0);
332
407
  },
333
- children: [/* @__PURE__ */ m(je, { className: "h-4 w-4" }), " Skip"]
408
+ children: [
409
+ /* @__PURE__ */ m(Me, { className: "h-4 w-4" }),
410
+ " ",
411
+ w("mybodyshield.pages.sessionDetail.skipRest", "Skip")
412
+ ]
334
413
  })]
335
414
  })]
336
415
  })
337
416
  }),
338
- $ && Y.length > 0 && /* @__PURE__ */ m(s.div, {
417
+ $ && J.length > 0 && /* @__PURE__ */ m(s.div, {
339
418
  initial: T ? !1 : {
340
419
  opacity: 0,
341
420
  y: 10
@@ -357,73 +436,83 @@ function w() {
357
436
  className: "mb-3 flex items-center justify-between gap-2",
358
437
  children: [/* @__PURE__ */ h("div", {
359
438
  className: "flex items-center gap-2.5",
360
- children: [/* @__PURE__ */ m(c, { icon: /* @__PURE__ */ m(Ee, { className: "h-4 w-4" }) }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h3", {
439
+ children: [/* @__PURE__ */ m(c, { icon: /* @__PURE__ */ m(De, { className: "h-4 w-4" }) }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h3", {
361
440
  className: "text-sm font-semibold text-text-primary",
362
- children: "Guided workout"
441
+ children: w("mybodyshield.pages.sessionDetail.guidedWorkout", "Guided workout")
363
442
  }), /* @__PURE__ */ m("p", {
364
443
  className: "text-xs text-text-secondary",
365
- children: ht ? "All planned exercises logged — nice work." : `Exercise ${Z + 1} of ${Y.length}`
444
+ children: vt ? w("mybodyshield.pages.sessionDetail.allExercisesDone", "All planned exercises logged — nice work.") : w("mybodyshield.pages.sessionDetail.exerciseProgress", "Exercise {{current}} of {{total}}", {
445
+ current: X + 1,
446
+ total: J.length
447
+ })
366
448
  })] })]
367
449
  }), /* @__PURE__ */ h("div", {
368
450
  className: "flex items-center gap-1.5",
369
451
  children: [/* @__PURE__ */ m(g, {
370
452
  variant: "outline",
371
453
  size: "sm",
372
- onClick: () => H(Math.max(Z - 1, 0)),
373
- disabled: Z === 0,
374
- "aria-label": "Previous exercise",
375
- children: /* @__PURE__ */ m(Se, { className: "h-4 w-4" })
454
+ onClick: () => ct(Math.max(X - 1, 0)),
455
+ disabled: X === 0,
456
+ "aria-label": w("mybodyshield.pages.sessionDetail.previousExercise", "Previous exercise"),
457
+ children: /* @__PURE__ */ m(Ce, { className: "h-4 w-4" })
376
458
  }), /* @__PURE__ */ m(g, {
377
459
  variant: "outline",
378
460
  size: "sm",
379
- onClick: () => H(Math.min(Z + 1, Y.length - 1)),
380
- disabled: Z >= Y.length - 1,
381
- "aria-label": "Next exercise",
382
- children: /* @__PURE__ */ m(Ce, { className: "h-4 w-4" })
461
+ onClick: () => ct(Math.min(X + 1, J.length - 1)),
462
+ disabled: X >= J.length - 1,
463
+ "aria-label": w("mybodyshield.pages.sessionDetail.nextExercise", "Next exercise"),
464
+ children: /* @__PURE__ */ m(we, { className: "h-4 w-4" })
383
465
  })]
384
466
  })]
385
- }), Q && /* @__PURE__ */ h("div", {
467
+ }), Z && /* @__PURE__ */ h("div", {
386
468
  className: "flex flex-wrap items-center justify-between gap-3 rounded-xl bg-bg-sunken/60 p-3",
387
469
  children: [/* @__PURE__ */ h("div", { children: [
388
470
  /* @__PURE__ */ m("p", {
389
471
  className: "text-sm font-semibold text-text-primary",
390
- children: Q.name
472
+ children: Z.name
391
473
  }),
392
474
  /* @__PURE__ */ h("p", {
393
475
  className: "mt-0.5 text-xs text-text-secondary",
394
476
  children: [
395
- te(Q.muscleGroup),
477
+ ee(Z.muscleGroup),
396
478
  " · ",
397
- Q.sets,
479
+ Z.sets,
398
480
  " ×",
399
481
  " ",
400
- Q.reps,
401
- " reps",
402
- Q.targetWeight > 0 ? ` @ ${o(Q.targetWeight)}` : "",
403
- Q.restSeconds > 0 ? ` · ${r(Q.restSeconds)} rest` : ""
482
+ Z.reps,
483
+ " ",
484
+ w("mybodyshield.pages.sessionDetail.reps", "reps"),
485
+ Z.targetWeight > 0 ? ` @ ${ne(Z.targetWeight)}` : "",
486
+ Z.restSeconds > 0 ? ` · ${i(Z.restSeconds)} ${w("mybodyshield.pages.sessionDetail.rest", "rest")}` : ""
404
487
  ]
405
488
  }),
406
489
  /* @__PURE__ */ h("p", {
407
490
  className: "mt-0.5 text-xs tabular-nums text-text-tertiary",
408
491
  children: [
409
- X.get(Q.name) ?? 0,
410
- " of",
492
+ Y.get(Z.name) ?? 0,
411
493
  " ",
412
- Math.max(Q.sets, 1),
413
- " sets logged"
494
+ w("mybodyshield.pages.sessionDetail.ofSets", "of"),
495
+ " ",
496
+ Math.max(Z.sets, 1),
497
+ " ",
498
+ w("mybodyshield.pages.sessionDetail.setsLogged", "sets logged")
414
499
  ]
415
500
  })
416
501
  ] }), /* @__PURE__ */ h(g, {
417
502
  size: "sm",
418
- onClick: () => St(Q),
419
- children: [/* @__PURE__ */ m(f, { className: "h-4 w-4" }), " Log this exercise"]
503
+ onClick: () => wt(Z),
504
+ children: [
505
+ /* @__PURE__ */ m(f, { className: "h-4 w-4" }),
506
+ " ",
507
+ w("mybodyshield.pages.sessionDetail.logThisExercise", "Log this exercise")
508
+ ]
420
509
  })]
421
510
  })]
422
511
  })
423
512
  }),
424
513
  /* @__PURE__ */ h(s.div, {
425
514
  className: "mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
426
- variants: T ? void 0 : qe,
515
+ variants: T ? void 0 : Je,
427
516
  initial: T ? !1 : "hidden",
428
517
  animate: "show",
429
518
  children: [
@@ -434,8 +523,8 @@ function w() {
434
523
  className: "text-action-primary-bg",
435
524
  children: /* @__PURE__ */ m(d, { className: "h-5 w-5" })
436
525
  }),
437
- value: i(q.length),
438
- label: "Total sets"
526
+ value: a(K.length),
527
+ label: w(K.length === 1 ? "mybodyshield.pages.sessionDetail.totalSet" : "mybodyshield.pages.sessionDetail.totalSets", K.length === 1 ? "Total set" : "Total sets")
439
528
  })
440
529
  }),
441
530
  /* @__PURE__ */ m(s.div, {
@@ -443,10 +532,10 @@ function w() {
443
532
  children: /* @__PURE__ */ m(n, {
444
533
  icon: /* @__PURE__ */ m("span", {
445
534
  className: "text-action-primary-bg",
446
- children: /* @__PURE__ */ m(ke, { className: "h-5 w-5" })
535
+ children: /* @__PURE__ */ m(Ae, { className: "h-5 w-5" })
447
536
  }),
448
- value: `${i(ut)} kg`,
449
- label: "Total volume"
537
+ value: w("mybodyshield.pages.sessionDetail.volumeKg", "{{volume}} kg", { volume: a(pt) }),
538
+ label: w("mybodyshield.pages.sessionDetail.totalVolume", "Total volume")
450
539
  })
451
540
  }),
452
541
  /* @__PURE__ */ m(s.div, {
@@ -456,8 +545,8 @@ function w() {
456
545
  className: "text-action-primary-bg",
457
546
  children: /* @__PURE__ */ m(p, { className: "h-5 w-5" })
458
547
  }),
459
- value: pt == null ? "—" : r(pt),
460
- label: "Duration"
548
+ value: gt == null ? "—" : i(gt),
549
+ label: w("mybodyshield.pages.sessionDetail.duration", "Duration")
461
550
  })
462
551
  }),
463
552
  /* @__PURE__ */ m(s.div, {
@@ -465,10 +554,10 @@ function w() {
465
554
  children: /* @__PURE__ */ m(n, {
466
555
  icon: /* @__PURE__ */ m("span", {
467
556
  className: "text-action-primary-bg",
468
- children: /* @__PURE__ */ m(we, { className: "h-5 w-5" })
557
+ children: /* @__PURE__ */ m(Te, { className: "h-5 w-5" })
469
558
  }),
470
- value: K.caloriesBurned > 0 ? ne(K.caloriesBurned) : "—",
471
- label: "Calories burned"
559
+ value: G.caloriesBurned > 0 ? te(G.caloriesBurned) : "—",
560
+ label: w("mybodyshield.pages.sessionDetail.caloriesBurned", "Calories burned")
472
561
  })
473
562
  })
474
563
  ]
@@ -479,32 +568,40 @@ function w() {
479
568
  className: "mb-3 flex items-end justify-between gap-3",
480
569
  children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h2", {
481
570
  className: "text-base font-semibold text-text-primary",
482
- children: "Logged sets"
571
+ children: w("mybodyshield.pages.sessionDetail.loggedSets", "Logged sets")
483
572
  }), /* @__PURE__ */ m("p", {
484
573
  className: "mt-0.5 text-sm text-text-secondary",
485
- children: "Every set recorded during this session, grouped by exercise."
574
+ children: w("mybodyshield.pages.sessionDetail.loggedSetsDescription", "Every set recorded during this session, grouped by exercise.")
486
575
  })] }), $ && /* @__PURE__ */ h(g, {
487
576
  variant: "outline",
488
577
  size: "sm",
489
- onClick: xt,
578
+ onClick: Ct,
490
579
  className: "shrink-0",
491
- children: [/* @__PURE__ */ m(f, { className: "h-4 w-4" }), " Log set"]
580
+ children: [
581
+ /* @__PURE__ */ m(f, { className: "h-4 w-4" }),
582
+ " ",
583
+ w("mybodyshield.pages.sessionDetail.logSet", "Log set")
584
+ ]
492
585
  })]
493
- }), J.length === 0 ? /* @__PURE__ */ m(ie, {
586
+ }), q.length === 0 ? /* @__PURE__ */ m(ie, {
494
587
  illustration: "empty-data",
495
588
  icon: /* @__PURE__ */ m(d, { className: "h-10 w-10" }),
496
- title: "No sets logged yet",
497
- description: $ ? "Log your first set to start tracking this workout." : "No sets were recorded for this session.",
589
+ title: w("mybodyshield.pages.sessionDetail.noSetsLogged", "No sets logged yet"),
590
+ description: w($ ? "mybodyshield.pages.sessionDetail.noSetsLoggedLive" : "mybodyshield.pages.sessionDetail.noSetsLoggedReadonly", $ ? "Log your first set to start tracking this workout." : "No sets were recorded for this session."),
498
591
  action: $ ? /* @__PURE__ */ h(g, {
499
- onClick: xt,
500
- children: [/* @__PURE__ */ m(f, { className: "h-4 w-4" }), " Log set"]
592
+ onClick: Ct,
593
+ children: [
594
+ /* @__PURE__ */ m(f, { className: "h-4 w-4" }),
595
+ " ",
596
+ w("mybodyshield.pages.sessionDetail.logSet", "Log set")
597
+ ]
501
598
  }) : void 0
502
599
  }) : /* @__PURE__ */ m(s.div, {
503
600
  className: "space-y-4",
504
- variants: T ? void 0 : qe,
601
+ variants: T ? void 0 : Je,
505
602
  initial: T ? !1 : "hidden",
506
603
  animate: "show",
507
- children: J.map((e) => {
604
+ children: q.map((e) => {
508
605
  let t = e.sets.filter((e) => e.isPersonalRecord).length;
509
606
  return /* @__PURE__ */ m(s.div, {
510
607
  variants: T ? void 0 : x,
@@ -525,17 +622,17 @@ function w() {
525
622
  className: "inline-flex items-center rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-[11px] font-semibold text-status-success-text shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-status-success-text)_14%,transparent)]",
526
623
  children: [
527
624
  t,
528
- " PR",
529
- t === 1 ? "" : "s"
625
+ " ",
626
+ w(t === 1 ? "mybodyshield.pages.sessionDetail.prSingular" : "mybodyshield.pages.sessionDetail.prPlural", t === 1 ? "PR" : "PRs")
530
627
  ]
531
628
  })
532
629
  ]
533
630
  }), /* @__PURE__ */ h("span", {
534
631
  className: "shrink-0 text-xs tabular-nums text-text-tertiary",
535
632
  children: [
536
- i(e.sets.length),
633
+ a(e.sets.length),
537
634
  " ",
538
- e.sets.length === 1 ? "set" : "sets"
635
+ w(e.sets.length === 1 ? "mybodyshield.pages.sessionDetail.set" : "mybodyshield.pages.sessionDetail.sets", e.sets.length === 1 ? "set" : "sets")
539
636
  ]
540
637
  })]
541
638
  }), /* @__PURE__ */ m("ul", {
@@ -546,17 +643,13 @@ function w() {
546
643
  className: "flex flex-wrap items-center justify-between gap-2 rounded-lg px-2 py-2 transition-colors" + (e.isPersonalRecord ? " bg-[color-mix(in_oklab,var(--color-status-success-text)_9%,transparent)]" : " hover:bg-bg-sunken/40"),
547
644
  children: [/* @__PURE__ */ h("div", {
548
645
  className: "flex items-center gap-2",
549
- children: [/* @__PURE__ */ h("span", {
646
+ children: [/* @__PURE__ */ m("span", {
550
647
  className: "text-sm font-medium text-text-primary tabular-nums",
551
- children: [
552
- "Set ",
553
- e.setNumber,
554
- ": ",
555
- i(e.reps),
556
- " ×",
557
- " ",
558
- o(e.weight)
559
- ]
648
+ children: w("mybodyshield.pages.sessionDetail.setRow", "Set {{number}}: {{reps}} × {{weight}}", {
649
+ number: e.setNumber,
650
+ reps: a(e.reps),
651
+ weight: ne(e.weight)
652
+ })
560
653
  }), e.isPersonalRecord && /* @__PURE__ */ m("span", {
561
654
  className: "inline-flex rounded-full shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-status-success-text)_16%,transparent)]",
562
655
  children: /* @__PURE__ */ m(re, { status: "PR" })
@@ -565,14 +658,10 @@ function w() {
565
658
  className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-text-secondary",
566
659
  children: [t && e.durationSec > 0 && /* @__PURE__ */ h("span", {
567
660
  className: "inline-flex items-center gap-1 tabular-nums",
568
- children: [/* @__PURE__ */ m(p, { className: "h-3.5 w-3.5 text-accent" }), r(e.durationSec)]
661
+ children: [/* @__PURE__ */ m(p, { className: "h-3.5 w-3.5 text-accent" }), i(e.durationSec)]
569
662
  }), t && e.distanceM > 0 && /* @__PURE__ */ h("span", {
570
663
  className: "inline-flex items-center gap-1 tabular-nums",
571
- children: [
572
- /* @__PURE__ */ m(De, { className: "h-3.5 w-3.5 text-accent" }),
573
- i(e.distanceM),
574
- " m"
575
- ]
664
+ children: [/* @__PURE__ */ m(Oe, { className: "h-3.5 w-3.5 text-accent" }), w("mybodyshield.pages.sessionDetail.distanceM", "{{distance}} m", { distance: a(e.distanceM) })]
576
665
  })]
577
666
  })]
578
667
  }, e.id);
@@ -585,18 +674,18 @@ function w() {
585
674
  }),
586
675
  /* @__PURE__ */ m("div", {
587
676
  className: "mt-8",
588
- children: /* @__PURE__ */ m(pe, {
677
+ children: /* @__PURE__ */ m(me, {
589
678
  entityType: "mybodyshield-session",
590
- entityId: K.id,
591
- title: "Coach feedback",
592
- description: "Discuss form, cues and this session's results with your coach and team."
679
+ entityId: G.id,
680
+ title: w("mybodyshield.pages.sessionDetail.coachFeedback", "Coach feedback"),
681
+ description: w("mybodyshield.pages.sessionDetail.coachFeedbackDescription", "Discuss form, cues and this session's results with your coach and team.")
593
682
  })
594
683
  }),
595
- /* @__PURE__ */ m(Pe, {
596
- open: et,
684
+ /* @__PURE__ */ m(Fe, {
685
+ open: nt,
597
686
  onOpenChange: N,
598
- children: /* @__PURE__ */ h(Fe, { children: [
599
- /* @__PURE__ */ h(Re, { children: [/* @__PURE__ */ m(ze, { children: "Log a set" }), /* @__PURE__ */ m(Ie, { children: "Record reps and load for strength work, or duration and distance for cardio. The dialog stays open so you can log sets back-to-back." })] }),
687
+ children: /* @__PURE__ */ h(Ie, { children: [
688
+ /* @__PURE__ */ h(ze, { children: [/* @__PURE__ */ m(Be, { children: w("mybodyshield.pages.sessionDetail.logSetDialogTitle", "Log a set") }), /* @__PURE__ */ m(Le, { children: w("mybodyshield.pages.sessionDetail.logSetDialogDescription", "Record reps and load for strength work, or duration and distance for cardio. The dialog stays open so you can log sets back-to-back.") })] }),
600
689
  /* @__PURE__ */ h("div", {
601
690
  className: "space-y-4 px-1",
602
691
  children: [
@@ -604,7 +693,7 @@ function w() {
604
693
  className: "space-y-1.5",
605
694
  children: [/* @__PURE__ */ m(y, {
606
695
  htmlFor: "myb-set-exercise",
607
- children: "Exercise"
696
+ children: w("mybodyshield.pages.sessionDetail.exerciseLabel", "Exercise")
608
697
  }), /* @__PURE__ */ m(v, {
609
698
  id: "myb-set-exercise",
610
699
  value: P.exerciseName,
@@ -615,7 +704,7 @@ function w() {
615
704
  exerciseName: t
616
705
  })), L(!1);
617
706
  },
618
- placeholder: "e.g. Back Squat"
707
+ placeholder: w("mybodyshield.pages.sessionDetail.exercisePlaceholder", "e.g. Back Squat")
619
708
  })]
620
709
  }),
621
710
  /* @__PURE__ */ h("div", {
@@ -625,7 +714,7 @@ function w() {
625
714
  className: "space-y-1.5",
626
715
  children: [/* @__PURE__ */ m(y, {
627
716
  htmlFor: "myb-set-number",
628
- children: "Set number"
717
+ children: w("mybodyshield.pages.sessionDetail.setNumberLabel", "Set number")
629
718
  }), /* @__PURE__ */ m(v, {
630
719
  id: "myb-set-number",
631
720
  type: "number",
@@ -636,14 +725,14 @@ function w() {
636
725
  ...t,
637
726
  setNumber: e.target.value
638
727
  })),
639
- placeholder: "1"
728
+ placeholder: w("mybodyshield.pages.sessionDetail.setNumberPlaceholder", "1")
640
729
  })]
641
730
  }),
642
731
  /* @__PURE__ */ h("div", {
643
732
  className: "space-y-1.5",
644
733
  children: [/* @__PURE__ */ m(y, {
645
734
  htmlFor: "myb-set-reps",
646
- children: "Reps"
735
+ children: w("mybodyshield.pages.sessionDetail.repsLabel", "Reps")
647
736
  }), /* @__PURE__ */ m(v, {
648
737
  id: "myb-set-reps",
649
738
  type: "number",
@@ -654,14 +743,14 @@ function w() {
654
743
  ...t,
655
744
  reps: e.target.value
656
745
  })),
657
- placeholder: "8"
746
+ placeholder: w("mybodyshield.pages.sessionDetail.repsPlaceholder", "8")
658
747
  })]
659
748
  }),
660
749
  /* @__PURE__ */ h("div", {
661
750
  className: "space-y-1.5",
662
751
  children: [/* @__PURE__ */ m(y, {
663
752
  htmlFor: "myb-set-weight",
664
- children: "Weight (kg)"
753
+ children: w("mybodyshield.pages.sessionDetail.weightLabel", "Weight (kg)")
665
754
  }), /* @__PURE__ */ m(v, {
666
755
  id: "myb-set-weight",
667
756
  type: "number",
@@ -673,14 +762,14 @@ function w() {
673
762
  ...t,
674
763
  weight: e.target.value
675
764
  })),
676
- placeholder: "60"
765
+ placeholder: w("mybodyshield.pages.sessionDetail.weightPlaceholder", "60")
677
766
  })]
678
767
  }),
679
768
  /* @__PURE__ */ h("div", {
680
769
  className: "space-y-1.5",
681
770
  children: [/* @__PURE__ */ m(y, {
682
771
  htmlFor: "myb-set-distance",
683
- children: "Distance (m)"
772
+ children: w("mybodyshield.pages.sessionDetail.distanceLabel", "Distance (m)")
684
773
  }), /* @__PURE__ */ m(v, {
685
774
  id: "myb-set-distance",
686
775
  type: "number",
@@ -691,14 +780,14 @@ function w() {
691
780
  ...t,
692
781
  distanceM: e.target.value
693
782
  })),
694
- placeholder: "Optional"
783
+ placeholder: w("mybodyshield.pages.sessionDetail.optionalPlaceholder", "Optional")
695
784
  })]
696
785
  }),
697
786
  /* @__PURE__ */ h("div", {
698
787
  className: "space-y-1.5",
699
788
  children: [/* @__PURE__ */ m(y, {
700
789
  htmlFor: "myb-set-duration",
701
- children: "Duration (sec)"
790
+ children: w("mybodyshield.pages.sessionDetail.durationLabel", "Duration (sec)")
702
791
  }), /* @__PURE__ */ m(v, {
703
792
  id: "myb-set-duration",
704
793
  type: "number",
@@ -709,7 +798,7 @@ function w() {
709
798
  ...t,
710
799
  durationSec: e.target.value
711
800
  })),
712
- placeholder: "Optional"
801
+ placeholder: w("mybodyshield.pages.sessionDetail.optionalPlaceholder", "Optional")
713
802
  })]
714
803
  })
715
804
  ]
@@ -718,17 +807,20 @@ function w() {
718
807
  className: "flex items-center justify-between gap-3 rounded-xl bg-bg-sunken/60 p-3",
719
808
  children: [/* @__PURE__ */ h("div", {
720
809
  className: "flex items-center gap-2",
721
- children: [yt ? /* @__PURE__ */ m(Oe, { className: "h-4 w-4 text-status-success-text" }) : /* @__PURE__ */ m(Te, { className: "h-4 w-4 text-accent" }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m(y, {
810
+ children: [Q ? /* @__PURE__ */ m(ke, { className: "h-4 w-4 text-status-success-text" }) : /* @__PURE__ */ m(Ee, { className: "h-4 w-4 text-accent" }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m(y, {
722
811
  htmlFor: "myb-set-pr",
723
812
  className: "cursor-pointer",
724
- children: "Personal record"
813
+ children: w("mybodyshield.pages.sessionDetail.personalRecord", "Personal record")
725
814
  }), /* @__PURE__ */ m("p", {
726
815
  className: "text-xs text-text-tertiary",
727
- children: G.data ? `Auto-detected against your best: ${i(G.data.reps)} × ${o(G.data.weight)}.` : P.exerciseName.trim() ? "First time logging this exercise — nothing to compare yet." : "Flag this set as a new PR."
816
+ children: W.data ? w("mybodyshield.pages.sessionDetail.prAutoDetected", "Auto-detected against your best: {{reps}} × {{weight}}.", {
817
+ reps: a(W.data.reps),
818
+ weight: ne(W.data.weight)
819
+ }) : P.exerciseName.trim() ? w("mybodyshield.pages.sessionDetail.prFirstTime", "First time logging this exercise — nothing to compare yet.") : w("mybodyshield.pages.sessionDetail.prFlagHint", "Flag this set as a new PR.")
728
820
  })] })]
729
- }), /* @__PURE__ */ m(Be, {
821
+ }), /* @__PURE__ */ m(Ve, {
730
822
  id: "myb-set-pr",
731
- checked: yt,
823
+ checked: Q,
732
824
  onCheckedChange: (e) => {
733
825
  L(!0), F((t) => ({
734
826
  ...t,
@@ -737,79 +829,43 @@ function w() {
737
829
  }
738
830
  })]
739
831
  }),
740
- tt && /* @__PURE__ */ m("p", {
832
+ rt && /* @__PURE__ */ m("p", {
741
833
  className: "text-sm text-status-error-text",
742
- children: tt
834
+ children: rt
743
835
  })
744
836
  ]
745
837
  }),
746
- /* @__PURE__ */ h(Le, { children: [/* @__PURE__ */ m(g, {
838
+ /* @__PURE__ */ h(Re, { children: [/* @__PURE__ */ m(g, {
747
839
  variant: "outline",
748
840
  onClick: () => N(!1),
749
- children: "Done"
841
+ children: w("mybodyshield.common.close", "Close")
750
842
  }), /* @__PURE__ */ m(g, {
751
- onClick: async () => {
752
- I(null);
753
- let e = P.exerciseName.trim();
754
- if (!e) {
755
- I("Exercise name is required.");
756
- return;
757
- }
758
- let t = {
759
- exerciseName: e,
760
- setNumber: S(P.setNumber),
761
- reps: S(P.reps),
762
- weight: S(P.weight),
763
- distanceM: S(P.distanceM),
764
- durationSec: S(P.durationSec),
765
- isPersonalRecord: yt
766
- }, n = (t) => {
767
- F({
768
- ...C,
769
- exerciseName: e,
770
- setNumber: String(t)
771
- }), L(!1);
772
- let n = Q && Q.name === e && Q.restSeconds > 0 ? Q.restSeconds : We;
773
- U(Date.now() + n * 1e3), W(n);
774
- };
775
- if (!A.isOnline) {
776
- await A.enqueueLogSet(E, t), M(), n((S(P.setNumber) ?? q.length) + 1);
777
- return;
778
- }
779
- try {
780
- n((await O.mutateAsync({
781
- sessionId: E,
782
- ...t
783
- })).setNumber + 1);
784
- } catch (e) {
785
- if (He(e)) {
786
- await A.enqueueLogSet(E, t), M(), n((S(P.setNumber) ?? q.length) + 1);
787
- return;
788
- }
789
- I(e instanceof Error ? e.message : "Failed to log the set.");
790
- }
791
- },
843
+ onClick: Tt,
792
844
  disabled: O.isPending,
793
- children: O.isPending ? "Logging…" : "Log set"
845
+ children: O.isPending ? w("mybodyshield.common.logging", "Logging…") : w("mybodyshield.pages.sessionDetail.logSet", "Log set")
794
846
  })] })
795
847
  ] })
796
848
  }),
797
- /* @__PURE__ */ m(Pe, {
798
- open: rt,
849
+ /* @__PURE__ */ m(Fe, {
850
+ open: at,
799
851
  onOpenChange: R,
800
- children: /* @__PURE__ */ h(Fe, { children: [
801
- /* @__PURE__ */ h(Re, { children: [/* @__PURE__ */ m(ze, { children: "Complete session" }), /* @__PURE__ */ m(Ie, { children: "Wrap up this workout and record how it went." })] }),
852
+ children: /* @__PURE__ */ h(Ie, { children: [
853
+ /* @__PURE__ */ h(ze, { children: [/* @__PURE__ */ m(Be, { children: w("mybodyshield.pages.sessionDetail.completeDialogTitle", "Complete session") }), /* @__PURE__ */ m(Le, { children: w("mybodyshield.pages.sessionDetail.completeDialogDescription", "Wrap up this workout and record how it went.") })] }),
802
854
  /* @__PURE__ */ h("div", {
803
855
  className: "space-y-4 px-1",
804
856
  children: [
805
- q.length === 0 && /* @__PURE__ */ h("div", {
857
+ K.length === 0 && /* @__PURE__ */ h("div", {
806
858
  className: "flex items-start gap-2.5 rounded-xl border border-status-warning-text/40 bg-status-warning-bg-subtle p-3",
807
- children: [/* @__PURE__ */ m(ye, { className: "mt-0.5 h-4 w-4 shrink-0 text-status-warning-text" }), /* @__PURE__ */ h("p", {
859
+ children: [/* @__PURE__ */ m(be, { className: "mt-0.5 h-4 w-4 shrink-0 text-status-warning-text" }), /* @__PURE__ */ h("p", {
808
860
  className: "text-sm text-text-secondary",
809
- children: [/* @__PURE__ */ m("span", {
810
- className: "font-medium text-text-primary",
811
- children: "No sets logged."
812
- }), " You can still complete this session, but nothing was recorded for it."]
861
+ children: [
862
+ /* @__PURE__ */ m("span", {
863
+ className: "font-medium text-text-primary",
864
+ children: w("mybodyshield.pages.sessionDetail.noSetsWarning", "No sets logged.")
865
+ }),
866
+ " ",
867
+ w("mybodyshield.pages.sessionDetail.noSetsWarningDetail", "You can still complete this session, but nothing was recorded for it.")
868
+ ]
813
869
  })]
814
870
  }),
815
871
  /* @__PURE__ */ h("div", {
@@ -818,7 +874,7 @@ function w() {
818
874
  className: "space-y-1.5",
819
875
  children: [/* @__PURE__ */ m(y, {
820
876
  htmlFor: "myb-complete-calories",
821
- children: "Calories burned"
877
+ children: w("mybodyshield.pages.sessionDetail.caloriesBurned", "Calories burned")
822
878
  }), /* @__PURE__ */ m(v, {
823
879
  id: "myb-complete-calories",
824
880
  type: "number",
@@ -829,13 +885,13 @@ function w() {
829
885
  ...t,
830
886
  caloriesBurned: e.target.value
831
887
  })),
832
- placeholder: "Optional"
888
+ placeholder: w("mybodyshield.pages.sessionDetail.optionalPlaceholder", "Optional")
833
889
  })]
834
890
  }), /* @__PURE__ */ h("div", {
835
891
  className: "space-y-1.5",
836
892
  children: [/* @__PURE__ */ m(y, {
837
893
  htmlFor: "myb-complete-rpe",
838
- children: "Perceived exertion (1–10)"
894
+ children: w("mybodyshield.pages.sessionDetail.rpeLabel", "Perceived exertion (1–10)")
839
895
  }), /* @__PURE__ */ m(v, {
840
896
  id: "myb-complete-rpe",
841
897
  type: "number",
@@ -847,7 +903,7 @@ function w() {
847
903
  ...t,
848
904
  perceivedExertion: e.target.value
849
905
  })),
850
- placeholder: "Optional"
906
+ placeholder: w("mybodyshield.pages.sessionDetail.optionalPlaceholder", "Optional")
851
907
  })]
852
908
  })]
853
909
  }),
@@ -855,8 +911,8 @@ function w() {
855
911
  className: "space-y-1.5",
856
912
  children: [/* @__PURE__ */ m(y, {
857
913
  htmlFor: "myb-complete-notes",
858
- children: "Notes"
859
- }), /* @__PURE__ */ m(Ve, {
914
+ children: w("mybodyshield.common.notes", "Notes")
915
+ }), /* @__PURE__ */ m(He, {
860
916
  id: "myb-complete-notes",
861
917
  rows: 3,
862
918
  value: z.notes,
@@ -864,46 +920,23 @@ function w() {
864
920
  ...t,
865
921
  notes: e.target.value
866
922
  })),
867
- placeholder: "How did the session feel?"
923
+ placeholder: w("mybodyshield.pages.sessionDetail.completeNotesPlaceholder", "How did the session feel?")
868
924
  })]
869
925
  }),
870
- it && /* @__PURE__ */ m("p", {
926
+ ot && /* @__PURE__ */ m("p", {
871
927
  className: "text-sm text-status-error-text",
872
- children: it
928
+ children: ot
873
929
  })
874
930
  ]
875
931
  }),
876
- /* @__PURE__ */ h(Le, { children: [/* @__PURE__ */ m(g, {
932
+ /* @__PURE__ */ h(Re, { children: [/* @__PURE__ */ m(g, {
877
933
  variant: "outline",
878
934
  onClick: () => R(!1),
879
- children: "Cancel"
935
+ children: w("mybodyshield.common.cancel", "Cancel")
880
936
  }), /* @__PURE__ */ m(g, {
881
- onClick: async () => {
882
- V(null);
883
- let e = {
884
- caloriesBurned: S(z.caloriesBurned),
885
- perceivedExertion: S(z.perceivedExertion),
886
- notes: z.notes.trim() ? z.notes.trim() : void 0
887
- };
888
- if (!A.isOnline) {
889
- await A.enqueueCompleteSession(E, e), M(), R(!1);
890
- return;
891
- }
892
- try {
893
- await k.mutateAsync({
894
- id: E,
895
- input: e
896
- }), R(!1);
897
- } catch (t) {
898
- if (He(t)) {
899
- await A.enqueueCompleteSession(E, e), M(), R(!1);
900
- return;
901
- }
902
- V(t instanceof Error ? t.message : "Failed to complete the session.");
903
- }
904
- },
937
+ onClick: Dt,
905
938
  disabled: k.isPending,
906
- children: k.isPending ? "Completing…" : "Complete session"
939
+ children: k.isPending ? w("mybodyshield.common.completing", "Completing…") : w("mybodyshield.pages.sessionDetail.completeSession", "Complete session")
907
940
  })] })
908
941
  ] })
909
942
  })