@burdenoff/microfe-mybodyshield 2026.821.2 → 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.
- package/dist/mybodyshield/MyBodyShieldRoot.d.ts.map +1 -1
- package/dist/mybodyshield/MyBodyShieldRoot.js +54 -56
- package/dist/mybodyshield/MyBodyShieldRoot.js.map +1 -1
- package/dist/mybodyshield/MyBodyShieldRoutes.d.ts.map +1 -1
- package/dist/mybodyshield/MyBodyShieldRoutes.js +121 -62
- package/dist/mybodyshield/MyBodyShieldRoutes.js.map +1 -1
- package/dist/mybodyshield/components/EvidenceUpload.d.ts.map +1 -1
- package/dist/mybodyshield/components/EvidenceUpload.js +46 -45
- package/dist/mybodyshield/components/EvidenceUpload.js.map +1 -1
- package/dist/mybodyshield/components/FileLink.d.ts.map +1 -1
- package/dist/mybodyshield/components/FileLink.js +27 -18
- package/dist/mybodyshield/components/FileLink.js.map +1 -1
- package/dist/mybodyshield/components/MybDiscussion.d.ts +1 -1
- package/dist/mybodyshield/components/MybDiscussion.d.ts.map +1 -1
- package/dist/mybodyshield/components/MybDiscussion.js +59 -58
- package/dist/mybodyshield/components/MybDiscussion.js.map +1 -1
- package/dist/mybodyshield/components/MybTags.d.ts +1 -1
- package/dist/mybodyshield/components/MybTags.d.ts.map +1 -1
- package/dist/mybodyshield/components/MybTags.js +83 -74
- package/dist/mybodyshield/components/MybTags.js.map +1 -1
- package/dist/mybodyshield/components/PageDisabled.d.ts.map +1 -1
- package/dist/mybodyshield/components/PageDisabled.js +16 -11
- package/dist/mybodyshield/components/PageDisabled.js.map +1 -1
- package/dist/mybodyshield/components/Pagination.d.ts.map +1 -1
- package/dist/mybodyshield/components/Pagination.js +36 -27
- package/dist/mybodyshield/components/Pagination.js.map +1 -1
- package/dist/mybodyshield/components/StateViews.d.ts.map +1 -1
- package/dist/mybodyshield/components/StateViews.js +42 -34
- package/dist/mybodyshield/components/StateViews.js.map +1 -1
- package/dist/mybodyshield/components/UserSearchSelect.d.ts.map +1 -1
- package/dist/mybodyshield/components/UserSearchSelect.js +66 -68
- package/dist/mybodyshield/components/UserSearchSelect.js.map +1 -1
- package/dist/mybodyshield/hooks/index.d.ts +1 -0
- package/dist/mybodyshield/hooks/index.d.ts.map +1 -1
- package/dist/mybodyshield/hooks/index.js +1 -0
- package/dist/mybodyshield/hooks/useTr.d.ts +5 -0
- package/dist/mybodyshield/hooks/useTr.d.ts.map +1 -0
- package/dist/mybodyshield/hooks/useTr.js +12 -0
- package/dist/mybodyshield/hooks/useTr.js.map +1 -0
- package/dist/mybodyshield/pages/DashboardPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/DashboardPage.js +157 -136
- package/dist/mybodyshield/pages/DashboardPage.js.map +1 -1
- package/dist/mybodyshield/pages/SettingsPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/SettingsPage.js +50 -59
- package/dist/mybodyshield/pages/SettingsPage.js.map +1 -1
- package/dist/mybodyshield/pages/_shared/visuals.d.ts +2 -1
- package/dist/mybodyshield/pages/_shared/visuals.d.ts.map +1 -1
- package/dist/mybodyshield/pages/_shared/visuals.js +91 -81
- package/dist/mybodyshield/pages/_shared/visuals.js.map +1 -1
- package/dist/mybodyshield/pages/ai/AiControlsPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/ai/AiControlsPage.js +279 -231
- package/dist/mybodyshield/pages/ai/AiControlsPage.js.map +1 -1
- package/dist/mybodyshield/pages/coaching/CoachingPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/coaching/CoachingPage.js +349 -258
- package/dist/mybodyshield/pages/coaching/CoachingPage.js.map +1 -1
- package/dist/mybodyshield/pages/goals/GoalsPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/goals/GoalsPage.js +247 -251
- package/dist/mybodyshield/pages/goals/GoalsPage.js.map +1 -1
- package/dist/mybodyshield/pages/insights/InsightsCharts.d.ts.map +1 -1
- package/dist/mybodyshield/pages/insights/InsightsCharts.js +216 -213
- package/dist/mybodyshield/pages/insights/InsightsCharts.js.map +1 -1
- package/dist/mybodyshield/pages/insights/InsightsPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/insights/InsightsPage.js +327 -220
- package/dist/mybodyshield/pages/insights/InsightsPage.js.map +1 -1
- package/dist/mybodyshield/pages/nutrition/NutritionPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/nutrition/NutritionPage.js +575 -529
- package/dist/mybodyshield/pages/nutrition/NutritionPage.js.map +1 -1
- package/dist/mybodyshield/pages/programs/ProgramDetailPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/programs/ProgramDetailPage.js +333 -275
- package/dist/mybodyshield/pages/programs/ProgramDetailPage.js.map +1 -1
- package/dist/mybodyshield/pages/programs/ProgramsPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/programs/ProgramsPage.js +258 -253
- package/dist/mybodyshield/pages/programs/ProgramsPage.js.map +1 -1
- package/dist/mybodyshield/pages/progress/ProgressPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/progress/ProgressPage.js +271 -254
- package/dist/mybodyshield/pages/progress/ProgressPage.js.map +1 -1
- package/dist/mybodyshield/pages/recovery/RecoveryPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/recovery/RecoveryPage.js +206 -200
- package/dist/mybodyshield/pages/recovery/RecoveryPage.js.map +1 -1
- package/dist/mybodyshield/pages/train/SessionDetailPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/train/SessionDetailPage.js +327 -294
- package/dist/mybodyshield/pages/train/SessionDetailPage.js.map +1 -1
- package/dist/mybodyshield/pages/train/SessionsPage.d.ts.map +1 -1
- package/dist/mybodyshield/pages/train/SessionsPage.js +180 -163
- package/dist/mybodyshield/pages/train/SessionsPage.js.map +1 -1
- package/dist/mybodyshield/utils/i18n.d.ts +1 -2
- package/dist/mybodyshield/utils/i18n.d.ts.map +1 -1
- package/dist/mybodyshield/utils/i18n.js +15 -0
- package/dist/mybodyshield/utils/i18n.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,338 +1,386 @@
|
|
|
1
1
|
import { PageLayout as e } from "../../components/PageLayout.js";
|
|
2
2
|
import { MetricsCard as t } from "../../components/MetricsCard.js";
|
|
3
3
|
import { formatDateTime as n, formatEnumLabel as r, formatRelativeTime as i } from "../../utils/formatters.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { useMybAiOperationLogs as l, useMybAiSettings as u, useMybUpdateAiSettings as d } from "../../hooks/useMyBodyShieldApi.js";
|
|
4
|
+
import { useMybAiOperationLogs as a, useMybAiProcessingConsent as o, useMybAiSettings as s, useMybSetAiProcessingConsent as c, useMybUpdateAiSettings as l } from "../../hooks/useMyBodyShieldApi.js";
|
|
5
|
+
import { useTr as u } from "../../hooks/useTr.js";
|
|
7
6
|
import "../../hooks/index.js";
|
|
7
|
+
import { ErrorView as d, LoadingView as f, Section as p } from "../../components/StateViews.js";
|
|
8
|
+
import { DataTable as m } from "../../components/DataTable.js";
|
|
8
9
|
import "../../components/index.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
10
|
+
import { IconChip as h } from "../_shared/visuals.js";
|
|
11
|
+
import { useMemo as g, useState as _ } from "react";
|
|
12
|
+
import { Activity as v, Bot as y, KeyRound as b, Save as x, ShieldCheck as S, ShieldOff as C, Sparkles as w } from "lucide-react";
|
|
13
|
+
import { jsx as T, jsxs as E } from "react/jsx-runtime";
|
|
14
|
+
import { Button as D, GlassCard as O, Input as k, Label as A, Select as j, SelectContent as M, SelectItem as N, SelectTrigger as P, SelectValue as F, Spinner as I, Switch as L } from "@burdenoff/fe-libs/ui";
|
|
13
15
|
//#region src/mybodyshield/pages/ai/AiControlsPage.tsx
|
|
14
|
-
var
|
|
16
|
+
var R = [
|
|
15
17
|
"GEMINI",
|
|
16
18
|
"OPENAI",
|
|
17
19
|
"ANTHROPIC"
|
|
18
|
-
],
|
|
20
|
+
], z = {
|
|
19
21
|
GEMINI: "Google Gemini",
|
|
20
22
|
OPENAI: "OpenAI",
|
|
21
23
|
ANTHROPIC: "Anthropic"
|
|
22
|
-
},
|
|
24
|
+
}, B = {
|
|
23
25
|
GEMINI: "gemini-2.5-flash",
|
|
24
26
|
OPENAI: "gpt-4o-mini",
|
|
25
27
|
ANTHROPIC: "claude-3-5-haiku-latest"
|
|
26
|
-
},
|
|
28
|
+
}, V = (e) => ({
|
|
27
29
|
provider: e.provider,
|
|
28
30
|
modelName: e.modelName,
|
|
29
31
|
dailyAllowance: String(e.dailyAllowance),
|
|
30
32
|
providerKey: "",
|
|
31
33
|
clearKey: !1
|
|
32
34
|
});
|
|
33
|
-
function
|
|
34
|
-
let
|
|
35
|
-
|
|
35
|
+
function H() {
|
|
36
|
+
let e = u(), t = o(), n = c();
|
|
37
|
+
if (t.isLoading) return /* @__PURE__ */ T(f, { label: e("mybodyshield.pages.aiControls.loadingConsent", "Loading AI-processing consent…") });
|
|
38
|
+
if (t.isError) return /* @__PURE__ */ T(d, {
|
|
39
|
+
message: e("mybodyshield.pages.aiControls.consentError", "We couldn't load your AI-processing consent."),
|
|
40
|
+
onRetry: () => t.refetch()
|
|
41
|
+
});
|
|
42
|
+
let r = t.data?.enabled ?? !1;
|
|
43
|
+
return /* @__PURE__ */ T(O, {
|
|
44
|
+
treatment: "plain",
|
|
45
|
+
className: "p-5",
|
|
46
|
+
children: /* @__PURE__ */ E("div", {
|
|
47
|
+
className: "flex flex-wrap items-start justify-between gap-4",
|
|
48
|
+
children: [/* @__PURE__ */ E("div", {
|
|
49
|
+
className: "flex min-w-0 items-start gap-3",
|
|
50
|
+
children: [/* @__PURE__ */ T(h, { icon: T(r ? S : C, { className: "h-5 w-5" }) }), /* @__PURE__ */ E("div", {
|
|
51
|
+
className: "min-w-0",
|
|
52
|
+
children: [
|
|
53
|
+
/* @__PURE__ */ T("p", {
|
|
54
|
+
className: "text-sm font-medium text-text-primary",
|
|
55
|
+
children: r ? e("mybodyshield.pages.aiControls.aiMayReadData", "AI may read your health data") : e("mybodyshield.pages.aiControls.aiWithdrawn", "AI processing is withdrawn — summaries will not run")
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ T("p", {
|
|
58
|
+
className: "mt-0.5 text-sm text-text-secondary",
|
|
59
|
+
children: r ? e("mybodyshield.pages.aiControls.aiEnabledDescription", "The provider and model below are used to turn your logged training, nutrition, recovery and body-metric data into plain-language summaries.") : e("mybodyshield.pages.aiControls.aiWithdrawnDescription", "The provider and model below are saved, but no AI summary is generated while consent is withdrawn. Rule-based guidance and every manual logging path keep working.")
|
|
60
|
+
}),
|
|
61
|
+
t.data?.withdrawnAt && !r && /* @__PURE__ */ T("p", {
|
|
62
|
+
className: "mt-1 text-xs text-text-tertiary",
|
|
63
|
+
children: e("mybodyshield.pages.aiControls.withdrawnAgo", "Withdrawn {{time}}.", { time: i(t.data.withdrawnAt) })
|
|
64
|
+
}),
|
|
65
|
+
t.data?.acceptedAt && r && /* @__PURE__ */ T("p", {
|
|
66
|
+
className: "mt-1 text-xs text-text-tertiary",
|
|
67
|
+
children: e("mybodyshield.pages.aiControls.consentGivenAgo", "Consent given {{time}}.", { time: i(t.data.acceptedAt) })
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
})]
|
|
71
|
+
}), /* @__PURE__ */ T(L, {
|
|
72
|
+
checked: r,
|
|
73
|
+
onCheckedChange: (e) => n.mutate(e),
|
|
74
|
+
disabled: n.isPending,
|
|
75
|
+
"aria-label": e("mybodyshield.pages.aiControls.allowAiData", "Allow AI to read my health data")
|
|
76
|
+
})]
|
|
77
|
+
})
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function U({ settings: a, logsQuery: o }) {
|
|
81
|
+
let s = u(), c = l(), [h, S] = _(() => V(a)), [C, L] = _(null), [U, W] = _(!1), G = g(() => {
|
|
82
|
+
let { dailyAllowance: e, dailyAllowanceUsed: t } = a;
|
|
36
83
|
return e <= 0 ? 0 : Math.min(100, Math.round(t / e * 100));
|
|
37
|
-
}, [
|
|
38
|
-
|
|
84
|
+
}, [a]), K = a.dailyAllowanceUsed >= a.dailyAllowance, q = (e) => {
|
|
85
|
+
S((t) => ({
|
|
39
86
|
...t,
|
|
40
87
|
provider: e,
|
|
41
|
-
modelName: t.modelName ===
|
|
88
|
+
modelName: t.modelName === B[t.provider] ? B[e] : t.modelName
|
|
42
89
|
}));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
90
|
+
}, J = async () => {
|
|
91
|
+
L(null), W(!1);
|
|
92
|
+
let e = Number(h.dailyAllowance);
|
|
93
|
+
if (!Number.isInteger(e) || e < 0 || e > 1e4) {
|
|
94
|
+
L(s("mybodyshield.pages.aiControls.allowanceRange", "Daily allowance must be an integer between 0 and 10,000."));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (!h.modelName.trim()) {
|
|
98
|
+
L(s("mybodyshield.pages.aiControls.modelRequired", "Model name is required."));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
let t = {
|
|
102
|
+
provider: h.provider,
|
|
103
|
+
modelName: h.modelName.trim(),
|
|
104
|
+
dailyAllowance: e
|
|
105
|
+
};
|
|
106
|
+
h.clearKey ? t.providerKey = "" : h.providerKey.trim() && (t.providerKey = h.providerKey.trim());
|
|
107
|
+
try {
|
|
108
|
+
await c.mutateAsync(t), W(!0), S((e) => ({
|
|
109
|
+
...e,
|
|
110
|
+
providerKey: "",
|
|
111
|
+
clearKey: !1
|
|
112
|
+
}));
|
|
113
|
+
} catch (e) {
|
|
114
|
+
L(e instanceof Error ? e.message : s("mybodyshield.pages.aiControls.failedToSave", "Failed to save AI settings."));
|
|
115
|
+
}
|
|
116
|
+
}, Y = [
|
|
117
|
+
{
|
|
118
|
+
key: "createdAt",
|
|
119
|
+
header: s("mybodyshield.pages.aiControls.time", "Time"),
|
|
120
|
+
sortValue: (e) => new Date(e.createdAt).getTime(),
|
|
121
|
+
render: (e) => /* @__PURE__ */ E("div", {
|
|
122
|
+
className: "text-text-primary",
|
|
123
|
+
children: [/* @__PURE__ */ T("span", {
|
|
124
|
+
className: "block text-sm",
|
|
125
|
+
children: n(e.createdAt)
|
|
126
|
+
}), /* @__PURE__ */ T("span", {
|
|
127
|
+
className: "text-xs text-text-tertiary",
|
|
128
|
+
children: i(e.createdAt)
|
|
129
|
+
})]
|
|
130
|
+
})
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: "operationType",
|
|
134
|
+
header: s("mybodyshield.pages.aiControls.operation", "Operation"),
|
|
135
|
+
render: (e) => /* @__PURE__ */ T("span", {
|
|
136
|
+
className: "text-text-secondary",
|
|
137
|
+
children: r(e.operationType)
|
|
138
|
+
})
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
key: "provider",
|
|
142
|
+
header: s("mybodyshield.pages.aiControls.providerModel", "Provider / Model"),
|
|
143
|
+
render: (e) => /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("span", {
|
|
144
|
+
className: "block text-sm text-text-primary",
|
|
145
|
+
children: z[e.provider]
|
|
146
|
+
}), /* @__PURE__ */ T("span", {
|
|
147
|
+
className: "text-xs text-text-tertiary",
|
|
148
|
+
children: e.modelName
|
|
149
|
+
})] })
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
key: "tokens",
|
|
153
|
+
header: s("mybodyshield.pages.aiControls.tokens", "Tokens"),
|
|
154
|
+
align: "right",
|
|
155
|
+
render: (e) => /* @__PURE__ */ E("span", {
|
|
156
|
+
className: "tabular-nums text-text-secondary",
|
|
157
|
+
children: [
|
|
158
|
+
e.inputTokens ?? "—",
|
|
159
|
+
" / ",
|
|
160
|
+
e.outputTokens ?? "—"
|
|
161
|
+
]
|
|
162
|
+
})
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
key: "status",
|
|
166
|
+
header: s("mybodyshield.pages.aiControls.status", "Status"),
|
|
167
|
+
render: (e) => /* @__PURE__ */ T("span", {
|
|
168
|
+
className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${e.status === "SUCCESS" ? "bg-status-success-bg text-status-success-text" : "bg-status-error-bg text-status-error-text"}`,
|
|
169
|
+
children: r(e.status)
|
|
170
|
+
})
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
key: "error",
|
|
174
|
+
header: s("mybodyshield.pages.aiControls.errorColumn", "Error"),
|
|
175
|
+
hideOnMobile: !0,
|
|
176
|
+
render: (e) => e.errorMessage ? /* @__PURE__ */ T("span", {
|
|
177
|
+
className: "text-xs text-status-error-text",
|
|
178
|
+
children: e.errorMessage
|
|
179
|
+
}) : /* @__PURE__ */ T("span", {
|
|
180
|
+
className: "text-text-tertiary",
|
|
181
|
+
children: "—"
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
];
|
|
185
|
+
return /* @__PURE__ */ E(e, {
|
|
186
|
+
title: s("mybodyshield.pages.aiControls.title", "AI controls"),
|
|
187
|
+
description: s("mybodyshield.pages.aiControls.description", "Choose your AI provider, model and daily allowance."),
|
|
188
|
+
actions: /* @__PURE__ */ E(D, {
|
|
48
189
|
className: "gap-2",
|
|
49
|
-
onClick:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (!Number.isInteger(e) || e < 0 || e > 1e4) {
|
|
53
|
-
z("Daily allowance must be an integer between 0 and 10,000.");
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (!I.modelName.trim()) {
|
|
57
|
-
z("Model name is required.");
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
let t = {
|
|
61
|
-
provider: I.provider,
|
|
62
|
-
modelName: I.modelName.trim(),
|
|
63
|
-
dailyAllowance: e
|
|
64
|
-
};
|
|
65
|
-
I.clearKey ? t.providerKey = "" : I.providerKey.trim() && (t.providerKey = I.providerKey.trim());
|
|
66
|
-
try {
|
|
67
|
-
await F.mutateAsync(t), V(!0), L((e) => ({
|
|
68
|
-
...e,
|
|
69
|
-
providerKey: "",
|
|
70
|
-
clearKey: !1
|
|
71
|
-
}));
|
|
72
|
-
} catch (e) {
|
|
73
|
-
z(e instanceof Error ? e.message : "Failed to save AI settings.");
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
disabled: F.isPending,
|
|
77
|
-
children: [F.isPending ? /* @__PURE__ */ y(A, { size: "sm" }) : /* @__PURE__ */ y(_, { className: "h-4 w-4" }), "Save settings"]
|
|
190
|
+
onClick: J,
|
|
191
|
+
disabled: c.isPending,
|
|
192
|
+
children: [c.isPending ? /* @__PURE__ */ T(I, { size: "sm" }) : /* @__PURE__ */ T(x, { className: "h-4 w-4" }), s("mybodyshield.pages.aiControls.saveSettings", "Save settings")]
|
|
78
193
|
}),
|
|
79
194
|
children: [
|
|
80
|
-
/* @__PURE__ */
|
|
195
|
+
/* @__PURE__ */ T(p, {
|
|
196
|
+
title: s("mybodyshield.pages.aiControls.consentTitle", "AI-processing consent"),
|
|
197
|
+
description: s("mybodyshield.pages.aiControls.consentDescription", "AI summaries only run while you allow AI to read your health data."),
|
|
198
|
+
children: /* @__PURE__ */ T(H, {})
|
|
199
|
+
}),
|
|
200
|
+
/* @__PURE__ */ E("div", {
|
|
81
201
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
|
|
82
202
|
children: [
|
|
83
|
-
/* @__PURE__ */
|
|
84
|
-
icon: /* @__PURE__ */
|
|
85
|
-
value:
|
|
86
|
-
label: "Current provider"
|
|
203
|
+
/* @__PURE__ */ T(t, {
|
|
204
|
+
icon: /* @__PURE__ */ T(w, { className: "h-5 w-5" }),
|
|
205
|
+
value: a.provider,
|
|
206
|
+
label: s("mybodyshield.pages.aiControls.currentProvider", "Current provider")
|
|
87
207
|
}),
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
-
icon: /* @__PURE__ */ y
|
|
90
|
-
value:
|
|
91
|
-
label: "Current model"
|
|
208
|
+
/* @__PURE__ */ T(t, {
|
|
209
|
+
icon: /* @__PURE__ */ T(y, { className: "h-5 w-5" }),
|
|
210
|
+
value: a.modelName,
|
|
211
|
+
label: s("mybodyshield.pages.aiControls.currentModel", "Current model")
|
|
92
212
|
}),
|
|
93
|
-
/* @__PURE__ */
|
|
94
|
-
icon: /* @__PURE__ */
|
|
95
|
-
value: `${
|
|
96
|
-
label: "Daily allowance used",
|
|
97
|
-
accent:
|
|
98
|
-
footer: /* @__PURE__ */
|
|
213
|
+
/* @__PURE__ */ T(t, {
|
|
214
|
+
icon: /* @__PURE__ */ T(v, { className: "h-5 w-5" }),
|
|
215
|
+
value: `${a.dailyAllowanceUsed} / ${a.dailyAllowance}`,
|
|
216
|
+
label: s("mybodyshield.pages.aiControls.dailyAllowanceUsed", "Daily allowance used"),
|
|
217
|
+
accent: K ? "error" : G >= 80 ? "warning" : "success",
|
|
218
|
+
footer: /* @__PURE__ */ T("p", {
|
|
99
219
|
className: "text-xs text-text-tertiary",
|
|
100
|
-
children:
|
|
220
|
+
children: s("mybodyshield.pages.aiControls.resets", "Resets {{time}}", { time: i(a.allowanceResetAt) })
|
|
101
221
|
})
|
|
102
222
|
})
|
|
103
223
|
]
|
|
104
224
|
}),
|
|
105
|
-
/* @__PURE__ */
|
|
106
|
-
title: "Configuration",
|
|
107
|
-
description: "Changes apply to your account only.",
|
|
108
|
-
children: /* @__PURE__ */
|
|
225
|
+
/* @__PURE__ */ T(p, {
|
|
226
|
+
title: s("mybodyshield.pages.aiControls.configuration", "Configuration"),
|
|
227
|
+
description: s("mybodyshield.pages.aiControls.configurationDescription", "Changes apply to your account only."),
|
|
228
|
+
children: /* @__PURE__ */ E(O, {
|
|
109
229
|
treatment: "plain",
|
|
110
230
|
className: "p-6",
|
|
111
231
|
children: [
|
|
112
|
-
/* @__PURE__ */
|
|
232
|
+
/* @__PURE__ */ E("div", {
|
|
113
233
|
className: "grid gap-6 md:grid-cols-2",
|
|
114
234
|
children: [
|
|
115
|
-
/* @__PURE__ */
|
|
235
|
+
/* @__PURE__ */ E("div", {
|
|
116
236
|
className: "space-y-1.5",
|
|
117
237
|
children: [
|
|
118
|
-
/* @__PURE__ */
|
|
238
|
+
/* @__PURE__ */ T(A, {
|
|
119
239
|
htmlFor: "myb-ai-provider",
|
|
120
|
-
children: "AI provider"
|
|
240
|
+
children: s("mybodyshield.pages.aiControls.aiProvider", "AI provider")
|
|
121
241
|
}),
|
|
122
|
-
/* @__PURE__ */
|
|
123
|
-
value:
|
|
124
|
-
onValueChange: (e) =>
|
|
125
|
-
children: [/* @__PURE__ */
|
|
242
|
+
/* @__PURE__ */ E(j, {
|
|
243
|
+
value: h.provider,
|
|
244
|
+
onValueChange: (e) => q(e),
|
|
245
|
+
children: [/* @__PURE__ */ T(P, {
|
|
126
246
|
id: "myb-ai-provider",
|
|
127
|
-
children: /* @__PURE__ */
|
|
128
|
-
}), /* @__PURE__ */
|
|
247
|
+
children: /* @__PURE__ */ T(F, {})
|
|
248
|
+
}), /* @__PURE__ */ T(M, { children: R.map((e) => /* @__PURE__ */ T(N, {
|
|
129
249
|
value: e,
|
|
130
|
-
children:
|
|
250
|
+
children: z[e]
|
|
131
251
|
}, e)) })]
|
|
132
252
|
}),
|
|
133
|
-
/* @__PURE__ */
|
|
253
|
+
/* @__PURE__ */ T("p", {
|
|
134
254
|
className: "text-xs text-text-tertiary",
|
|
135
|
-
children: "The provider used for AI-generated guidance summaries."
|
|
255
|
+
children: s("mybodyshield.pages.aiControls.providerDescription", "The provider used for AI-generated guidance summaries.")
|
|
136
256
|
})
|
|
137
257
|
]
|
|
138
258
|
}),
|
|
139
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ E("div", {
|
|
140
260
|
className: "space-y-1.5",
|
|
141
261
|
children: [
|
|
142
|
-
/* @__PURE__ */
|
|
262
|
+
/* @__PURE__ */ T(A, {
|
|
143
263
|
htmlFor: "myb-ai-model",
|
|
144
|
-
children: "Model name"
|
|
264
|
+
children: s("mybodyshield.pages.aiControls.modelName", "Model name")
|
|
145
265
|
}),
|
|
146
|
-
/* @__PURE__ */
|
|
266
|
+
/* @__PURE__ */ T(k, {
|
|
147
267
|
id: "myb-ai-model",
|
|
148
|
-
value:
|
|
149
|
-
onChange: (e) =>
|
|
268
|
+
value: h.modelName,
|
|
269
|
+
onChange: (e) => S((t) => ({
|
|
150
270
|
...t,
|
|
151
271
|
modelName: e.target.value
|
|
152
272
|
})),
|
|
153
|
-
placeholder:
|
|
273
|
+
placeholder: s("mybodyshield.pages.aiControls.modelPlaceholder", "e.g. {{model}}", { model: B[h.provider] })
|
|
154
274
|
}),
|
|
155
|
-
/* @__PURE__ */
|
|
275
|
+
/* @__PURE__ */ T("p", {
|
|
156
276
|
className: "text-xs text-text-tertiary",
|
|
157
|
-
children:
|
|
158
|
-
"e.g. ",
|
|
159
|
-
N[I.provider],
|
|
160
|
-
". Must be valid for the chosen provider."
|
|
161
|
-
]
|
|
277
|
+
children: s("mybodyshield.pages.aiControls.modelHint", "Must be valid for the chosen provider.")
|
|
162
278
|
})
|
|
163
279
|
]
|
|
164
280
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
281
|
+
/* @__PURE__ */ E("div", {
|
|
166
282
|
className: "space-y-1.5",
|
|
167
283
|
children: [
|
|
168
|
-
/* @__PURE__ */
|
|
284
|
+
/* @__PURE__ */ T(A, {
|
|
169
285
|
htmlFor: "myb-ai-allowance",
|
|
170
|
-
children: "Daily allowance"
|
|
286
|
+
children: s("mybodyshield.pages.aiControls.dailyAllowance", "Daily allowance")
|
|
171
287
|
}),
|
|
172
|
-
/* @__PURE__ */
|
|
288
|
+
/* @__PURE__ */ T(k, {
|
|
173
289
|
id: "myb-ai-allowance",
|
|
174
290
|
type: "number",
|
|
175
291
|
min: 0,
|
|
176
292
|
max: 1e4,
|
|
177
293
|
step: 1,
|
|
178
|
-
value:
|
|
179
|
-
onChange: (e) =>
|
|
294
|
+
value: h.dailyAllowance,
|
|
295
|
+
onChange: (e) => S((t) => ({
|
|
180
296
|
...t,
|
|
181
297
|
dailyAllowance: e.target.value
|
|
182
298
|
}))
|
|
183
299
|
}),
|
|
184
|
-
/* @__PURE__ */
|
|
300
|
+
/* @__PURE__ */ T("p", {
|
|
185
301
|
className: "text-xs text-text-tertiary",
|
|
186
|
-
children: "Maximum AI operations counted against your account per UTC day."
|
|
302
|
+
children: s("mybodyshield.pages.aiControls.dailyAllowanceHint", "Maximum AI operations counted against your account per UTC day.")
|
|
187
303
|
})
|
|
188
304
|
]
|
|
189
305
|
}),
|
|
190
|
-
/* @__PURE__ */
|
|
306
|
+
/* @__PURE__ */ E("div", {
|
|
191
307
|
className: "space-y-1.5",
|
|
192
308
|
children: [
|
|
193
|
-
/* @__PURE__ */
|
|
309
|
+
/* @__PURE__ */ T(A, {
|
|
194
310
|
htmlFor: "myb-ai-key",
|
|
195
|
-
children: /* @__PURE__ */
|
|
311
|
+
children: /* @__PURE__ */ E("span", {
|
|
196
312
|
className: "inline-flex items-center gap-1.5",
|
|
197
|
-
children: [/* @__PURE__ */
|
|
313
|
+
children: [/* @__PURE__ */ T(b, { className: "h-3.5 w-3.5" }), s("mybodyshield.pages.aiControls.providerApiKey", "Provider API key")]
|
|
198
314
|
})
|
|
199
315
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
316
|
+
/* @__PURE__ */ T(k, {
|
|
201
317
|
id: "myb-ai-key",
|
|
202
318
|
type: "password",
|
|
203
|
-
value:
|
|
204
|
-
onChange: (e) =>
|
|
319
|
+
value: h.providerKey,
|
|
320
|
+
onChange: (e) => S((t) => ({
|
|
205
321
|
...t,
|
|
206
322
|
providerKey: e.target.value,
|
|
207
323
|
clearKey: !1
|
|
208
324
|
})),
|
|
209
|
-
placeholder:
|
|
210
|
-
disabled:
|
|
325
|
+
placeholder: a.hasProviderKey ? s("mybodyshield.pages.aiControls.providerKeySaved", "•••••••• (saved)") : s("mybodyshield.pages.aiControls.providerKeyPlaceholder", "Optional"),
|
|
326
|
+
disabled: h.clearKey
|
|
211
327
|
}),
|
|
212
|
-
/* @__PURE__ */
|
|
328
|
+
/* @__PURE__ */ E("div", {
|
|
213
329
|
className: "flex items-center gap-2",
|
|
214
|
-
children: [/* @__PURE__ */
|
|
330
|
+
children: [/* @__PURE__ */ T("input", {
|
|
215
331
|
id: "myb-ai-clear-key",
|
|
216
332
|
type: "checkbox",
|
|
217
|
-
checked:
|
|
218
|
-
onChange: (e) =>
|
|
333
|
+
checked: h.clearKey,
|
|
334
|
+
onChange: (e) => S((t) => ({
|
|
219
335
|
...t,
|
|
220
336
|
clearKey: e.target.checked,
|
|
221
337
|
providerKey: ""
|
|
222
338
|
})),
|
|
223
339
|
className: "h-4 w-4 rounded border-border-seam text-accent focus:ring-accent"
|
|
224
|
-
}), /* @__PURE__ */
|
|
340
|
+
}), /* @__PURE__ */ T(A, {
|
|
225
341
|
htmlFor: "myb-ai-clear-key",
|
|
226
342
|
className: "text-xs font-normal text-text-secondary",
|
|
227
|
-
children: "Clear saved key and fall back to the workspace default"
|
|
343
|
+
children: s("mybodyshield.pages.aiControls.clearKey", "Clear saved key and fall back to the workspace default")
|
|
228
344
|
})]
|
|
229
345
|
})
|
|
230
346
|
]
|
|
231
347
|
})
|
|
232
348
|
]
|
|
233
349
|
}),
|
|
234
|
-
|
|
350
|
+
U && /* @__PURE__ */ T("p", {
|
|
235
351
|
className: "mt-4 text-sm text-status-success-text",
|
|
236
|
-
children: "AI settings saved."
|
|
352
|
+
children: s("mybodyshield.pages.aiControls.settingsSaved", "AI settings saved.")
|
|
237
353
|
}),
|
|
238
|
-
|
|
354
|
+
C && /* @__PURE__ */ T("p", {
|
|
239
355
|
className: "mt-4 text-sm text-status-error-text",
|
|
240
|
-
children:
|
|
356
|
+
children: C
|
|
241
357
|
})
|
|
242
358
|
]
|
|
243
359
|
})
|
|
244
360
|
}),
|
|
245
|
-
/* @__PURE__ */
|
|
246
|
-
title: "Operation history",
|
|
247
|
-
description: "Redacted audit log of AI operations for your account.",
|
|
248
|
-
children:
|
|
249
|
-
message: "We couldn't load the operation log.",
|
|
250
|
-
onRetry: () =>
|
|
251
|
-
}) :
|
|
361
|
+
/* @__PURE__ */ T(p, {
|
|
362
|
+
title: s("mybodyshield.pages.aiControls.operationHistory", "Operation history"),
|
|
363
|
+
description: s("mybodyshield.pages.aiControls.operationHistoryDescription", "Redacted audit log of AI operations for your account."),
|
|
364
|
+
children: o.isLoading ? /* @__PURE__ */ T(f, { label: s("mybodyshield.pages.aiControls.loadingHistory", "Loading operation history…") }) : o.isError ? /* @__PURE__ */ T(d, {
|
|
365
|
+
message: s("mybodyshield.pages.aiControls.historyError", "We couldn't load the operation log."),
|
|
366
|
+
onRetry: () => o.refetch()
|
|
367
|
+
}) : o.data?.items.length === 0 ? /* @__PURE__ */ E(O, {
|
|
252
368
|
treatment: "plain",
|
|
253
369
|
className: "p-8 text-center",
|
|
254
370
|
children: [
|
|
255
|
-
/* @__PURE__ */
|
|
256
|
-
/* @__PURE__ */
|
|
371
|
+
/* @__PURE__ */ T(w, { className: "mx-auto h-8 w-8 text-text-tertiary" }),
|
|
372
|
+
/* @__PURE__ */ T("p", {
|
|
257
373
|
className: "mt-3 text-sm font-medium text-text-primary",
|
|
258
|
-
children: "No AI operations yet"
|
|
374
|
+
children: s("mybodyshield.pages.aiControls.noOperations", "No AI operations yet")
|
|
259
375
|
}),
|
|
260
|
-
/* @__PURE__ */
|
|
376
|
+
/* @__PURE__ */ T("p", {
|
|
261
377
|
className: "mt-1 text-xs text-text-tertiary",
|
|
262
|
-
children: "Operations appear here once AI-generated guidance runs."
|
|
378
|
+
children: s("mybodyshield.pages.aiControls.noOperationsDescription", "Operations appear here once AI-generated guidance runs.")
|
|
263
379
|
})
|
|
264
380
|
]
|
|
265
|
-
}) : /* @__PURE__ */
|
|
266
|
-
columns:
|
|
267
|
-
|
|
268
|
-
key: "createdAt",
|
|
269
|
-
header: "Time",
|
|
270
|
-
sortValue: (e) => new Date(e.createdAt).getTime(),
|
|
271
|
-
render: (e) => /* @__PURE__ */ b("div", {
|
|
272
|
-
className: "text-text-primary",
|
|
273
|
-
children: [/* @__PURE__ */ y("span", {
|
|
274
|
-
className: "block text-sm",
|
|
275
|
-
children: n(e.createdAt)
|
|
276
|
-
}), /* @__PURE__ */ y("span", {
|
|
277
|
-
className: "text-xs text-text-tertiary",
|
|
278
|
-
children: i(e.createdAt)
|
|
279
|
-
})]
|
|
280
|
-
})
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
key: "operationType",
|
|
284
|
-
header: "Operation",
|
|
285
|
-
render: (e) => /* @__PURE__ */ y("span", {
|
|
286
|
-
className: "text-text-secondary",
|
|
287
|
-
children: r(e.operationType)
|
|
288
|
-
})
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
key: "provider",
|
|
292
|
-
header: "Provider / Model",
|
|
293
|
-
render: (e) => /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("span", {
|
|
294
|
-
className: "block text-sm text-text-primary",
|
|
295
|
-
children: M[e.provider]
|
|
296
|
-
}), /* @__PURE__ */ y("span", {
|
|
297
|
-
className: "text-xs text-text-tertiary",
|
|
298
|
-
children: e.modelName
|
|
299
|
-
})] })
|
|
300
|
-
},
|
|
301
|
-
{
|
|
302
|
-
key: "tokens",
|
|
303
|
-
header: "Tokens",
|
|
304
|
-
align: "right",
|
|
305
|
-
render: (e) => /* @__PURE__ */ b("span", {
|
|
306
|
-
className: "tabular-nums text-text-secondary",
|
|
307
|
-
children: [
|
|
308
|
-
e.inputTokens ?? "—",
|
|
309
|
-
" / ",
|
|
310
|
-
e.outputTokens ?? "—"
|
|
311
|
-
]
|
|
312
|
-
})
|
|
313
|
-
},
|
|
314
|
-
{
|
|
315
|
-
key: "status",
|
|
316
|
-
header: "Status",
|
|
317
|
-
render: (e) => /* @__PURE__ */ y("span", {
|
|
318
|
-
className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${e.status === "SUCCESS" ? "bg-status-success-bg text-status-success-text" : "bg-status-error-bg text-status-error-text"}`,
|
|
319
|
-
children: r(e.status)
|
|
320
|
-
})
|
|
321
|
-
},
|
|
322
|
-
{
|
|
323
|
-
key: "error",
|
|
324
|
-
header: "Error",
|
|
325
|
-
hideOnMobile: !0,
|
|
326
|
-
render: (e) => e.errorMessage ? /* @__PURE__ */ y("span", {
|
|
327
|
-
className: "text-xs text-status-error-text",
|
|
328
|
-
children: e.errorMessage
|
|
329
|
-
}) : /* @__PURE__ */ y("span", {
|
|
330
|
-
className: "text-text-tertiary",
|
|
331
|
-
children: "—"
|
|
332
|
-
})
|
|
333
|
-
}
|
|
334
|
-
],
|
|
335
|
-
rows: u.data?.items ?? [],
|
|
381
|
+
}) : /* @__PURE__ */ T(m, {
|
|
382
|
+
columns: Y,
|
|
383
|
+
rows: o.data?.items ?? [],
|
|
336
384
|
rowKey: (e) => e.id,
|
|
337
385
|
defaultSort: {
|
|
338
386
|
key: "createdAt",
|
|
@@ -343,36 +391,36 @@ function F({ settings: l, logsQuery: u }) {
|
|
|
343
391
|
]
|
|
344
392
|
});
|
|
345
393
|
}
|
|
346
|
-
function
|
|
347
|
-
let t = u(), n =
|
|
348
|
-
if (
|
|
349
|
-
title: "AI controls",
|
|
350
|
-
children: /* @__PURE__ */
|
|
394
|
+
function W() {
|
|
395
|
+
let t = u(), n = s(), r = a();
|
|
396
|
+
if (n.isLoading) return /* @__PURE__ */ T(e, {
|
|
397
|
+
title: t("mybodyshield.pages.aiControls.title", "AI controls"),
|
|
398
|
+
children: /* @__PURE__ */ T(f, { label: t("mybodyshield.pages.aiControls.loadingSettings", "Loading AI settings…") })
|
|
351
399
|
});
|
|
352
|
-
if (
|
|
353
|
-
title: "AI controls",
|
|
354
|
-
children: /* @__PURE__ */
|
|
355
|
-
title: "Could not load AI settings",
|
|
356
|
-
message: "We couldn't fetch your AI configuration. Try again in a moment.",
|
|
357
|
-
onRetry: () =>
|
|
400
|
+
if (n.isError) return /* @__PURE__ */ T(e, {
|
|
401
|
+
title: t("mybodyshield.pages.aiControls.title", "AI controls"),
|
|
402
|
+
children: /* @__PURE__ */ T(d, {
|
|
403
|
+
title: t("mybodyshield.pages.aiControls.errorTitle", "Could not load AI settings"),
|
|
404
|
+
message: t("mybodyshield.pages.aiControls.error", "We couldn't fetch your AI configuration. Try again in a moment."),
|
|
405
|
+
onRetry: () => n.refetch()
|
|
358
406
|
})
|
|
359
407
|
});
|
|
360
|
-
let
|
|
361
|
-
if (!
|
|
362
|
-
title: "AI controls",
|
|
363
|
-
children: /* @__PURE__ */
|
|
364
|
-
title: "Could not load AI settings",
|
|
365
|
-
message: "We couldn't fetch your AI configuration. Try again in a moment.",
|
|
366
|
-
onRetry: () =>
|
|
408
|
+
let i = n.data;
|
|
409
|
+
if (!i) return /* @__PURE__ */ T(e, {
|
|
410
|
+
title: t("mybodyshield.pages.aiControls.title", "AI controls"),
|
|
411
|
+
children: /* @__PURE__ */ T(d, {
|
|
412
|
+
title: t("mybodyshield.pages.aiControls.errorTitle", "Could not load AI settings"),
|
|
413
|
+
message: t("mybodyshield.pages.aiControls.error", "We couldn't fetch your AI configuration. Try again in a moment."),
|
|
414
|
+
onRetry: () => n.refetch()
|
|
367
415
|
})
|
|
368
416
|
});
|
|
369
|
-
let
|
|
370
|
-
return /* @__PURE__ */
|
|
371
|
-
settings:
|
|
372
|
-
logsQuery:
|
|
373
|
-
},
|
|
417
|
+
let o = `${i.id}:${i.updatedAt}`;
|
|
418
|
+
return /* @__PURE__ */ T(U, {
|
|
419
|
+
settings: i,
|
|
420
|
+
logsQuery: r
|
|
421
|
+
}, o);
|
|
374
422
|
}
|
|
375
423
|
//#endregion
|
|
376
|
-
export {
|
|
424
|
+
export { W as AiControlsPage };
|
|
377
425
|
|
|
378
426
|
//# sourceMappingURL=AiControlsPage.js.map
|