@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.
- 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 +255 -266
- 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 +321 -301
- 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 +290 -284
- 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,148 +1,146 @@
|
|
|
1
1
|
import { directoryUserName as e, useMybUserSearch as t } from "../hooks/useMybUsers.js";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { useTr as n } from "../hooks/useTr.js";
|
|
3
|
+
import "../hooks/index.js";
|
|
4
|
+
import { useState as r } from "react";
|
|
5
|
+
import { Check as i, Loader2 as a, Search as o, User as s, X as c } from "lucide-react";
|
|
6
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
7
|
+
import { Input as d, Label as f } from "@burdenoff/fe-libs/ui";
|
|
6
8
|
//#region src/mybodyshield/components/UserSearchSelect.tsx
|
|
7
|
-
function
|
|
8
|
-
let [
|
|
9
|
-
|
|
9
|
+
function p({ label: p, userId: m, displayName: h, onSelect: g, required: _ = !1, htmlId: v = "myb-user-id" }) {
|
|
10
|
+
let y = n(), [b, x] = r(""), [S, C] = r(!1), w = t(b), T = w.data ?? [], E = b.trim().length >= 2, D = w.isError, O = (t) => {
|
|
11
|
+
g({
|
|
10
12
|
userId: t.id,
|
|
11
13
|
displayName: e(t)
|
|
12
|
-
}),
|
|
14
|
+
}), x("");
|
|
13
15
|
};
|
|
14
|
-
return
|
|
16
|
+
return S || D ? /* @__PURE__ */ u("div", {
|
|
15
17
|
className: "grid gap-1.5",
|
|
16
18
|
children: [
|
|
17
|
-
/* @__PURE__ */
|
|
18
|
-
htmlFor:
|
|
19
|
+
/* @__PURE__ */ u(f, {
|
|
20
|
+
htmlFor: v,
|
|
19
21
|
children: [
|
|
20
|
-
|
|
22
|
+
p,
|
|
21
23
|
" ",
|
|
22
|
-
|
|
24
|
+
_ && /* @__PURE__ */ l("span", {
|
|
23
25
|
className: "text-status-error-text",
|
|
24
26
|
children: "*"
|
|
25
27
|
})
|
|
26
28
|
]
|
|
27
29
|
}),
|
|
28
|
-
/* @__PURE__ */
|
|
29
|
-
id:
|
|
30
|
-
value:
|
|
31
|
-
onChange: (e) =>
|
|
30
|
+
/* @__PURE__ */ l(d, {
|
|
31
|
+
id: v,
|
|
32
|
+
value: m,
|
|
33
|
+
onChange: (e) => g({
|
|
32
34
|
userId: e.target.value,
|
|
33
|
-
displayName:
|
|
35
|
+
displayName: h
|
|
34
36
|
}),
|
|
35
|
-
placeholder: "user-uuid"
|
|
37
|
+
placeholder: y("mybodyshield.components.userSearch.manualPlaceholder", "user-uuid")
|
|
36
38
|
}),
|
|
37
|
-
/* @__PURE__ */
|
|
39
|
+
/* @__PURE__ */ l("p", {
|
|
38
40
|
className: "text-xs text-text-tertiary",
|
|
39
|
-
children:
|
|
41
|
+
children: D ? y("mybodyshield.components.userSearch.searchUnavailable", "User search is unavailable here — paste the user id.") : y("mybodyshield.components.userSearch.pasteHint", "Paste the user id.")
|
|
40
42
|
}),
|
|
41
|
-
!
|
|
43
|
+
!D && /* @__PURE__ */ l("button", {
|
|
42
44
|
type: "button",
|
|
43
|
-
onClick: () =>
|
|
45
|
+
onClick: () => C(!1),
|
|
44
46
|
className: "self-start text-xs font-medium text-accent hover:underline",
|
|
45
|
-
children: "Search the directory instead"
|
|
47
|
+
children: y("mybodyshield.components.userSearch.searchDirectory", "Search the directory instead")
|
|
46
48
|
})
|
|
47
49
|
]
|
|
48
|
-
}) : /* @__PURE__ */
|
|
50
|
+
}) : /* @__PURE__ */ u("div", {
|
|
49
51
|
className: "grid gap-1.5",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
51
|
-
|
|
52
|
+
children: [/* @__PURE__ */ u(f, { children: [
|
|
53
|
+
p,
|
|
52
54
|
" ",
|
|
53
|
-
|
|
55
|
+
_ && /* @__PURE__ */ l("span", {
|
|
54
56
|
className: "text-status-error-text",
|
|
55
57
|
children: "*"
|
|
56
58
|
})
|
|
57
|
-
] }),
|
|
59
|
+
] }), m ? /* @__PURE__ */ u("div", {
|
|
58
60
|
className: "flex items-center gap-2 rounded-lg border border-border-seam bg-bg-surface px-3 py-2",
|
|
59
61
|
children: [
|
|
60
|
-
/* @__PURE__ */
|
|
62
|
+
/* @__PURE__ */ l("span", {
|
|
61
63
|
className: "flex size-7 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-text-secondary",
|
|
62
|
-
children: /* @__PURE__ */
|
|
64
|
+
children: /* @__PURE__ */ l(s, { className: "h-4 w-4" })
|
|
63
65
|
}),
|
|
64
|
-
/* @__PURE__ */
|
|
66
|
+
/* @__PURE__ */ u("div", {
|
|
65
67
|
className: "min-w-0 flex-1",
|
|
66
|
-
children: [/* @__PURE__ */
|
|
68
|
+
children: [/* @__PURE__ */ l("p", {
|
|
67
69
|
className: "truncate text-sm font-medium text-text-primary",
|
|
68
|
-
children:
|
|
69
|
-
}), /* @__PURE__ */
|
|
70
|
+
children: h || y("mybodyshield.components.userSearch.selectedUser", "Selected user")
|
|
71
|
+
}), /* @__PURE__ */ l("p", {
|
|
70
72
|
className: "truncate text-xs text-text-tertiary",
|
|
71
|
-
children:
|
|
73
|
+
children: m
|
|
72
74
|
})]
|
|
73
75
|
}),
|
|
74
|
-
/* @__PURE__ */
|
|
76
|
+
/* @__PURE__ */ l("button", {
|
|
75
77
|
type: "button",
|
|
76
|
-
"aria-label": `Clear selected ${
|
|
77
|
-
onClick: () =>
|
|
78
|
+
"aria-label": `Clear selected ${p.toLowerCase()}`,
|
|
79
|
+
onClick: () => g({
|
|
78
80
|
userId: "",
|
|
79
81
|
displayName: ""
|
|
80
82
|
}),
|
|
81
83
|
className: "rounded-md p-1 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary",
|
|
82
|
-
children: /* @__PURE__ */ c
|
|
84
|
+
children: /* @__PURE__ */ l(c, { className: "h-4 w-4" })
|
|
83
85
|
})
|
|
84
86
|
]
|
|
85
|
-
}) : /* @__PURE__ */
|
|
87
|
+
}) : /* @__PURE__ */ u("div", {
|
|
86
88
|
className: "space-y-2",
|
|
87
89
|
children: [
|
|
88
|
-
/* @__PURE__ */
|
|
90
|
+
/* @__PURE__ */ u("div", {
|
|
89
91
|
className: "relative",
|
|
90
92
|
children: [
|
|
91
|
-
/* @__PURE__ */
|
|
92
|
-
/* @__PURE__ */
|
|
93
|
-
value:
|
|
94
|
-
onChange: (e) =>
|
|
95
|
-
placeholder: "Search by name or email…",
|
|
96
|
-
"aria-label":
|
|
93
|
+
/* @__PURE__ */ l(o, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }),
|
|
94
|
+
/* @__PURE__ */ l(d, {
|
|
95
|
+
value: b,
|
|
96
|
+
onChange: (e) => x(e.target.value),
|
|
97
|
+
placeholder: y("mybodyshield.components.userSearch.searchPlaceholder", "Search by name or email…"),
|
|
98
|
+
"aria-label": y("mybodyshield.components.userSearch.searchAria", "Search {{label}} by name or email", { label: p.toLowerCase() }),
|
|
97
99
|
className: "pl-9"
|
|
98
100
|
}),
|
|
99
|
-
|
|
101
|
+
w.isFetching && /* @__PURE__ */ l(a, { className: "absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-text-tertiary" })
|
|
100
102
|
]
|
|
101
103
|
}),
|
|
102
|
-
|
|
104
|
+
E && !w.isFetching && T.length === 0 && /* @__PURE__ */ l("p", {
|
|
103
105
|
className: "text-xs text-text-tertiary",
|
|
104
|
-
children:
|
|
105
|
-
"No users match “",
|
|
106
|
-
v.trim(),
|
|
107
|
-
"”."
|
|
108
|
-
]
|
|
106
|
+
children: y("mybodyshield.components.userSearch.noResults", "No users match “{{term}}”.", { term: b.trim() })
|
|
109
107
|
}),
|
|
110
|
-
|
|
108
|
+
T.length > 0 && /* @__PURE__ */ l("ul", {
|
|
111
109
|
className: "max-h-56 divide-y divide-border-seam overflow-auto rounded-lg border border-border-seam bg-bg-surface",
|
|
112
|
-
children:
|
|
110
|
+
children: T.map((t) => /* @__PURE__ */ l("li", { children: /* @__PURE__ */ u("button", {
|
|
113
111
|
type: "button",
|
|
114
|
-
onClick: () =>
|
|
112
|
+
onClick: () => O(t),
|
|
115
113
|
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-bg-sunken",
|
|
116
114
|
children: [
|
|
117
|
-
/* @__PURE__ */
|
|
115
|
+
/* @__PURE__ */ l("span", {
|
|
118
116
|
className: "flex size-7 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-text-secondary",
|
|
119
|
-
children: /* @__PURE__ */
|
|
117
|
+
children: /* @__PURE__ */ l(s, { className: "h-4 w-4" })
|
|
120
118
|
}),
|
|
121
|
-
/* @__PURE__ */
|
|
119
|
+
/* @__PURE__ */ u("span", {
|
|
122
120
|
className: "min-w-0 flex-1",
|
|
123
|
-
children: [/* @__PURE__ */
|
|
121
|
+
children: [/* @__PURE__ */ l("span", {
|
|
124
122
|
className: "block truncate text-sm font-medium text-text-primary",
|
|
125
123
|
children: e(t)
|
|
126
|
-
}), /* @__PURE__ */
|
|
124
|
+
}), /* @__PURE__ */ l("span", {
|
|
127
125
|
className: "block truncate text-xs text-text-tertiary",
|
|
128
126
|
children: t.email
|
|
129
127
|
})]
|
|
130
128
|
}),
|
|
131
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ l(i, { className: "h-4 w-4 shrink-0 text-text-tertiary opacity-0" })
|
|
132
130
|
]
|
|
133
131
|
}) }, t.id))
|
|
134
132
|
}),
|
|
135
|
-
/* @__PURE__ */
|
|
133
|
+
/* @__PURE__ */ l("button", {
|
|
136
134
|
type: "button",
|
|
137
|
-
onClick: () =>
|
|
135
|
+
onClick: () => C(!0),
|
|
138
136
|
className: "text-xs font-medium text-accent hover:underline",
|
|
139
|
-
children: "Enter a user ID manually"
|
|
137
|
+
children: y("mybodyshield.components.userSearch.enterManually", "Enter a user ID manually")
|
|
140
138
|
})
|
|
141
139
|
]
|
|
142
140
|
})]
|
|
143
141
|
});
|
|
144
142
|
}
|
|
145
143
|
//#endregion
|
|
146
|
-
export {
|
|
144
|
+
export { p as UserSearchSelect };
|
|
147
145
|
|
|
148
146
|
//# sourceMappingURL=UserSearchSelect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserSearchSelect.js","names":[],"sources":["../../../src/mybodyshield/components/UserSearchSelect.tsx"],"sourcesContent":["/**\n * User picker (identity reuse)\n * @module mybodyshield/components\n *\n * Resolves a real user by name or email from the global user directory so a\n * coach/member can be chosen without pasting a raw UUID. Degrades gracefully:\n * if the directory is unavailable (RBAC), the user can still paste an id.\n * Semantic tokens only.\n */\n\nimport { useState } from 'react';\nimport { Check, Loader2, Search, User as UserIcon, X } from 'lucide-react';\nimport { Input, Label } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\nimport { directoryUserName, useMybUserSearch, type DirectoryUser } from '../hooks/useMybUsers';\n\nexport interface UserSelectValue {\n userId: string;\n displayName: string;\n}\n\ninterface UserSearchSelectProps {\n /** Field label (e.g. \"Coach\", \"Member\"). */\n label: string;\n /** Currently selected user id. */\n userId: string;\n /** Display name currently chosen (echoed back so the parent can prefill). */\n displayName: string;\n onSelect: (value: UserSelectValue) => void;\n required?: boolean;\n /** Optional id for the label/input association in manual mode. */\n htmlId?: string;\n}\n\nexport function UserSearchSelect({\n label,\n userId,\n displayName,\n onSelect,\n required = false,\n htmlId = 'myb-user-id',\n}: UserSearchSelectProps) {\n const [term, setTerm] = useState('');\n const [manual, setManual] = useState(false);\n\n const search = useMybUserSearch(term);\n const results = search.data ?? [];\n const active = term.trim().length >= 2;\n const searchUnavailable = search.isError;\n\n const pick = (user: DirectoryUser) => {\n onSelect({ userId: user.id, displayName: directoryUserName(user) });\n setTerm('');\n };\n\n if (manual || searchUnavailable) {\n return (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={htmlId}>\n {label} {required && <span className=\"text-status-error-text\">*</span>}\n </Label>\n <Input\n id={htmlId}\n value={userId}\n onChange={(e) => onSelect({ userId: e.target.value, displayName })}\n placeholder
|
|
1
|
+
{"version":3,"file":"UserSearchSelect.js","names":[],"sources":["../../../src/mybodyshield/components/UserSearchSelect.tsx"],"sourcesContent":["/**\n * User picker (identity reuse)\n * @module mybodyshield/components\n *\n * Resolves a real user by name or email from the global user directory so a\n * coach/member can be chosen without pasting a raw UUID. Degrades gracefully:\n * if the directory is unavailable (RBAC), the user can still paste an id.\n * Semantic tokens only.\n */\n\nimport { useState } from 'react';\nimport { Check, Loader2, Search, User as UserIcon, X } from 'lucide-react';\nimport { Input, Label } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\nimport { directoryUserName, useMybUserSearch, type DirectoryUser } from '../hooks/useMybUsers';\nimport { useTr } from '../hooks';\n\nexport interface UserSelectValue {\n userId: string;\n displayName: string;\n}\n\ninterface UserSearchSelectProps {\n /** Field label (e.g. \"Coach\", \"Member\"). */\n label: string;\n /** Currently selected user id. */\n userId: string;\n /** Display name currently chosen (echoed back so the parent can prefill). */\n displayName: string;\n onSelect: (value: UserSelectValue) => void;\n required?: boolean;\n /** Optional id for the label/input association in manual mode. */\n htmlId?: string;\n}\n\nexport function UserSearchSelect({\n label,\n userId,\n displayName,\n onSelect,\n required = false,\n htmlId = 'myb-user-id',\n}: UserSearchSelectProps) {\n const t = useTr();\n const [term, setTerm] = useState('');\n const [manual, setManual] = useState(false);\n\n const search = useMybUserSearch(term);\n const results = search.data ?? [];\n const active = term.trim().length >= 2;\n const searchUnavailable = search.isError;\n\n const pick = (user: DirectoryUser) => {\n onSelect({ userId: user.id, displayName: directoryUserName(user) });\n setTerm('');\n };\n\n if (manual || searchUnavailable) {\n return (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={htmlId}>\n {label} {required && <span className=\"text-status-error-text\">*</span>}\n </Label>\n <Input\n id={htmlId}\n value={userId}\n onChange={(e) => onSelect({ userId: e.target.value, displayName })}\n placeholder={t('mybodyshield.components.userSearch.manualPlaceholder', 'user-uuid')}\n />\n <p className=\"text-xs text-text-tertiary\">\n {searchUnavailable\n ? t(\n 'mybodyshield.components.userSearch.searchUnavailable',\n 'User search is unavailable here — paste the user id.'\n )\n : t('mybodyshield.components.userSearch.pasteHint', 'Paste the user id.')}\n </p>\n {!searchUnavailable && (\n <button\n type=\"button\"\n onClick={() => setManual(false)}\n className=\"self-start text-xs font-medium text-accent hover:underline\"\n >\n {t(\n 'mybodyshield.components.userSearch.searchDirectory',\n 'Search the directory instead'\n )}\n </button>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"grid gap-1.5\">\n <Label>\n {label} {required && <span className=\"text-status-error-text\">*</span>}\n </Label>\n {userId ? (\n <div className=\"flex items-center gap-2 rounded-lg border border-border-seam bg-bg-surface px-3 py-2\">\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n <UserIcon className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {displayName || t('mybodyshield.components.userSearch.selectedUser', 'Selected user')}\n </p>\n <p className=\"truncate text-xs text-text-tertiary\">{userId}</p>\n </div>\n <button\n type=\"button\"\n aria-label={`Clear selected ${label.toLowerCase()}`}\n onClick={() => onSelect({ userId: '', displayName: '' })}\n className=\"rounded-md p-1 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary\" />\n <Input\n value={term}\n onChange={(e) => setTerm(e.target.value)}\n placeholder={t(\n 'mybodyshield.components.userSearch.searchPlaceholder',\n 'Search by name or email…'\n )}\n aria-label={t(\n 'mybodyshield.components.userSearch.searchAria',\n 'Search {{label}} by name or email',\n { label: label.toLowerCase() }\n )}\n className=\"pl-9\"\n />\n {search.isFetching && (\n <Loader2 className=\"absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-text-tertiary\" />\n )}\n </div>\n\n {active && !search.isFetching && results.length === 0 && (\n <p className=\"text-xs text-text-tertiary\">\n {t('mybodyshield.components.userSearch.noResults', 'No users match “{{term}}”.', {\n term: term.trim(),\n })}\n </p>\n )}\n\n {results.length > 0 && (\n <ul className=\"max-h-56 divide-y divide-border-seam overflow-auto rounded-lg border border-border-seam bg-bg-surface\">\n {results.map((user) => (\n <li key={user.id}>\n <button\n type=\"button\"\n onClick={() => pick(user)}\n className=\"flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-bg-sunken\"\n >\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-text-secondary\">\n <UserIcon className=\"h-4 w-4\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-text-primary\">\n {directoryUserName(user)}\n </span>\n <span className=\"block truncate text-xs text-text-tertiary\">\n {user.email}\n </span>\n </span>\n <Check className=\"h-4 w-4 shrink-0 text-text-tertiary opacity-0\" />\n </button>\n </li>\n ))}\n </ul>\n )}\n\n <button\n type=\"button\"\n onClick={() => setManual(true)}\n className=\"text-xs font-medium text-accent hover:underline\"\n >\n {t('mybodyshield.components.userSearch.enterManually', 'Enter a user ID manually')}\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mybodyshield/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mybodyshield/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTr.d.ts","sourceRoot":"","sources":["../../../src/mybodyshield/hooks/useTr.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,iBAAiB,KAAK,MAAM,CAAC;AAEvF,wBAAgB,KAAK,IAAI,EAAE,CAQ1B"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { tWithFallback as e } from "../utils/i18n.js";
|
|
2
|
+
import { useCallback as t } from "react";
|
|
3
|
+
import { useI18n as n } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
4
|
+
//#region src/mybodyshield/hooks/useTr.ts
|
|
5
|
+
function r() {
|
|
6
|
+
let { t: r } = n();
|
|
7
|
+
return t((t, n, i) => e(r, t, n, i), [r]);
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { r as useTr };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=useTr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTr.js","names":[],"sources":["../../../src/mybodyshield/hooks/useTr.ts"],"sourcesContent":["/**\n * MyBodyShield i18n hook\n * @module mybodyshield/hooks\n *\n * Thin wrapper around the shell I18nProvider that returns a `t` helper with\n * fallback-string and interpolation support. Keeps MFE components free of\n * `useI18n` boilerplate and guarantees a stable API even if the shell provider\n * changes shape.\n */\n\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport type { TranslationParams } from '../utils/i18n';\n\nexport type Tr = (key: string, fallback: string, params?: TranslationParams) => string;\n\nexport function useTr(): Tr {\n const { t: translate } = useI18n();\n\n return useCallback(\n (key: string, fallback: string, params?: TranslationParams): string =>\n tWithFallback(translate, key, fallback, params),\n [translate]\n );\n}\n"],"mappings":";;;;AAiBA,SAAgB,IAAY;CAC1B,IAAM,EAAE,GAAG,MAAc,GAAS;AAElC,QAAO,GACJ,GAAa,GAAkB,MAC9B,EAAc,GAAW,GAAK,GAAU,EAAO,EACjD,CAAC,EAAU,CACZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../../src/mybodyshield/pages/DashboardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../../src/mybodyshield/pages/DashboardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyGH,wBAAgB,aAAa,gCAsqB5B"}
|