@byline/host-tanstack-start 2.5.1 → 2.6.0

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 (123) hide show
  1. package/dist/admin-shell/admin-roles/container.js +38 -24
  2. package/dist/admin-shell/admin-roles/delete.js +9 -7
  3. package/dist/admin-shell/admin-roles/list.js +20 -16
  4. package/dist/admin-shell/admin-users/container.js +79 -56
  5. package/dist/admin-shell/admin-users/delete.js +10 -8
  6. package/dist/admin-shell/admin-users/list.js +27 -18
  7. package/dist/admin-shell/chrome/admin-app-bar.js +5 -2
  8. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs.js +3 -1
  9. package/dist/admin-shell/chrome/dashboard.js +13 -11
  10. package/dist/admin-shell/chrome/hamburger.js +3 -1
  11. package/dist/admin-shell/chrome/menu-drawer.js +7 -5
  12. package/dist/admin-shell/chrome/preview-toggle.js +5 -3
  13. package/dist/admin-shell/chrome/route-error.d.ts +3 -2
  14. package/dist/admin-shell/chrome/route-error.js +29 -22
  15. package/dist/admin-shell/chrome/sign-in-page.d.ts +16 -4
  16. package/dist/admin-shell/chrome/sign-in-page.js +38 -13
  17. package/dist/admin-shell/chrome/sign-in-page.module.js +1 -0
  18. package/dist/admin-shell/chrome/sign-in-page_module.css +8 -1
  19. package/dist/admin-shell/collections/api.js +6 -5
  20. package/dist/admin-shell/collections/create.js +12 -4
  21. package/dist/admin-shell/collections/edit.js +112 -37
  22. package/dist/admin-shell/collections/history.js +17 -12
  23. package/dist/admin-shell/collections/list.js +18 -13
  24. package/dist/admin-shell/collections/preview-link.d.ts +1 -10
  25. package/dist/admin-shell/collections/preview-link.js +9 -11
  26. package/dist/admin-shell/collections/resolve-preview-url.d.ts +34 -0
  27. package/dist/admin-shell/collections/resolve-preview-url.js +17 -0
  28. package/dist/admin-shell/collections/restore-version-modal.js +13 -14
  29. package/dist/admin-shell/collections/tanstack-navigation-guard.d.ts +1 -1
  30. package/dist/admin-shell/collections/view-menu.js +7 -5
  31. package/dist/i18n/index.d.ts +19 -0
  32. package/dist/i18n/index.js +4 -0
  33. package/dist/i18n/locale-cookie.d.ts +17 -0
  34. package/dist/i18n/locale-cookie.js +26 -0
  35. package/dist/i18n/locale-definitions.d.ts +29 -0
  36. package/dist/i18n/locale-definitions.js +27 -0
  37. package/dist/i18n/resolve-locale.d.ts +20 -0
  38. package/dist/i18n/resolve-locale.js +43 -0
  39. package/dist/i18n/server-translator.d.ts +33 -0
  40. package/dist/i18n/server-translator.js +19 -0
  41. package/dist/integrations/byline-admin-services.js +2 -0
  42. package/dist/integrations/byline-field-services.d.ts +3 -3
  43. package/dist/routes/create-admin-account-route.js +6 -3
  44. package/dist/routes/create-admin-dashboard-route.js +3 -1
  45. package/dist/routes/create-admin-layout-route.js +48 -25
  46. package/dist/routes/create-admin-permissions-route.js +4 -2
  47. package/dist/routes/create-admin-role-edit-route.js +5 -3
  48. package/dist/routes/create-admin-roles-list-route.js +4 -2
  49. package/dist/routes/create-admin-user-edit-route.js +5 -3
  50. package/dist/routes/create-admin-users-list-route.js +4 -2
  51. package/dist/routes/create-collection-api-route.js +5 -3
  52. package/dist/routes/create-collection-create-route.js +4 -2
  53. package/dist/routes/create-collection-edit-route.js +4 -2
  54. package/dist/routes/create-collection-history-route.js +5 -3
  55. package/dist/routes/create-collection-list-route.js +11 -5
  56. package/dist/routes/create-sign-in-route.js +10 -1
  57. package/dist/server-fns/admin-account/change-password.d.ts +1 -0
  58. package/dist/server-fns/admin-account/get.d.ts +1 -0
  59. package/dist/server-fns/admin-account/update.d.ts +1 -0
  60. package/dist/server-fns/admin-users/create.d.ts +1 -0
  61. package/dist/server-fns/admin-users/get.d.ts +1 -0
  62. package/dist/server-fns/admin-users/list.d.ts +1 -0
  63. package/dist/server-fns/admin-users/set-password.d.ts +1 -0
  64. package/dist/server-fns/admin-users/update.d.ts +1 -0
  65. package/dist/server-fns/auth/sign-in.js +18 -0
  66. package/dist/server-fns/i18n/get-active-locale.d.ts +8 -0
  67. package/dist/server-fns/i18n/get-active-locale.js +6 -0
  68. package/dist/server-fns/i18n/index.d.ts +10 -0
  69. package/dist/server-fns/i18n/index.js +2 -0
  70. package/dist/server-fns/i18n/set-locale.d.ts +25 -0
  71. package/dist/server-fns/i18n/set-locale.js +42 -0
  72. package/package.json +16 -7
  73. package/src/admin-shell/admin-roles/container.tsx +41 -31
  74. package/src/admin-shell/admin-roles/delete.tsx +10 -11
  75. package/src/admin-shell/admin-roles/list.tsx +29 -16
  76. package/src/admin-shell/admin-users/container.tsx +77 -50
  77. package/src/admin-shell/admin-users/delete.tsx +11 -12
  78. package/src/admin-shell/admin-users/list.tsx +39 -18
  79. package/src/admin-shell/chrome/admin-app-bar.tsx +5 -2
  80. package/src/admin-shell/chrome/breadcrumbs/breadcrumbs.tsx +3 -1
  81. package/src/admin-shell/chrome/dashboard.tsx +9 -3
  82. package/src/admin-shell/chrome/hamburger.tsx +3 -1
  83. package/src/admin-shell/chrome/menu-drawer.tsx +7 -5
  84. package/src/admin-shell/chrome/preview-toggle.tsx +6 -4
  85. package/src/admin-shell/chrome/route-error.tsx +39 -26
  86. package/src/admin-shell/chrome/sign-in-page.module.css +10 -1
  87. package/src/admin-shell/chrome/sign-in-page.tsx +46 -12
  88. package/src/admin-shell/collections/api.tsx +5 -1
  89. package/src/admin-shell/collections/create.tsx +10 -4
  90. package/src/admin-shell/collections/edit.tsx +79 -72
  91. package/src/admin-shell/collections/history.tsx +18 -12
  92. package/src/admin-shell/collections/list.tsx +25 -14
  93. package/src/admin-shell/collections/preview-link.tsx +20 -33
  94. package/src/admin-shell/collections/resolve-preview-url.test.node.ts +167 -0
  95. package/src/admin-shell/collections/resolve-preview-url.ts +67 -0
  96. package/src/admin-shell/collections/restore-version-modal.tsx +11 -12
  97. package/src/admin-shell/collections/tanstack-navigation-guard.ts +1 -1
  98. package/src/admin-shell/collections/view-menu.tsx +9 -5
  99. package/src/i18n/index.ts +26 -0
  100. package/src/i18n/locale-cookie.ts +68 -0
  101. package/src/i18n/locale-definitions.ts +48 -0
  102. package/src/i18n/resolve-locale.ts +96 -0
  103. package/src/i18n/server-translator.ts +60 -0
  104. package/src/integrations/byline-admin-services.ts +2 -0
  105. package/src/integrations/byline-field-services.ts +7 -3
  106. package/src/routes/create-admin-account-route.tsx +6 -4
  107. package/src/routes/create-admin-dashboard-route.tsx +5 -1
  108. package/src/routes/create-admin-layout-route.tsx +53 -20
  109. package/src/routes/create-admin-permissions-route.tsx +4 -2
  110. package/src/routes/create-admin-role-edit-route.tsx +5 -3
  111. package/src/routes/create-admin-roles-list-route.tsx +5 -2
  112. package/src/routes/create-admin-user-edit-route.tsx +5 -3
  113. package/src/routes/create-admin-users-list-route.tsx +4 -2
  114. package/src/routes/create-collection-api-route.tsx +5 -3
  115. package/src/routes/create-collection-create-route.tsx +7 -2
  116. package/src/routes/create-collection-edit-route.tsx +4 -2
  117. package/src/routes/create-collection-history-route.tsx +5 -3
  118. package/src/routes/create-collection-list-route.tsx +8 -10
  119. package/src/routes/create-sign-in-route.tsx +14 -1
  120. package/src/server-fns/auth/sign-in.ts +45 -0
  121. package/src/server-fns/i18n/get-active-locale.ts +26 -0
  122. package/src/server-fns/i18n/index.ts +11 -0
  123. package/src/server-fns/i18n/set-locale.ts +103 -0
@@ -5,38 +5,40 @@ import { useRouter } from "@tanstack/react-router";
5
5
  import { UserRoles } from "@byline/admin/admin-users/components/roles";
6
6
  import { SetPassword } from "@byline/admin/admin-users/components/set-password";
7
7
  import { UpdateUser } from "@byline/admin/admin-users/components/update";
8
- import { Button, CloseIcon, Drawer, EditIcon, IconButton, LocalDateTime, Modal, useToastManager } from "@byline/ui/react";
8
+ import { LocalDateTime } from "@byline/admin/react";
9
+ import { useTranslation } from "@byline/i18n/react";
10
+ import { Button, CloseIcon, Drawer, EditIcon, IconButton, Modal, useToastManager } from "@byline/ui/react";
9
11
  import classnames from "classnames";
10
12
  import container_module from "./container.module.js";
11
13
  import { DeleteUser } from "./delete.js";
12
- const panels = {
14
+ const panelMeta = {
13
15
  update: {
14
- title: 'Account Details',
15
16
  drawerWidth: 'medium',
16
- component: UpdateUser
17
+ component: UpdateUser,
18
+ titleKey: 'adminUsers.detail.panels.update'
17
19
  },
18
20
  set_password: {
19
- title: 'Set Password',
20
21
  drawerWidth: 'medium',
21
- component: SetPassword
22
+ component: SetPassword,
23
+ titleKey: 'adminUsers.detail.panels.setPassword'
22
24
  },
23
25
  delete_user: {
24
- title: 'Delete Admin User',
25
26
  drawerWidth: 'medium',
26
- component: DeleteUser
27
+ component: DeleteUser,
28
+ titleKey: 'adminUsers.detail.panels.delete'
27
29
  },
28
30
  roles: {
29
- title: 'User Roles',
30
31
  drawerWidth: 'medium',
31
- component: ()=>null
32
+ component: ()=>null,
33
+ titleKey: 'adminUsers.detail.panels.roles'
32
34
  },
33
35
  empty: {
34
- title: '',
35
36
  drawerWidth: 'medium',
36
- component: ()=>null
37
+ component: ()=>null,
38
+ titleKey: ''
37
39
  }
38
40
  };
39
- function ContainerSection({ title, onEdit, children }) {
41
+ function ContainerSection({ title, onEdit, editAriaLabel, children }) {
40
42
  return /*#__PURE__*/ jsxs("div", {
41
43
  className: classnames('byline-admin-user-section', container_module.section),
42
44
  children: [
@@ -49,7 +51,7 @@ function ContainerSection({ title, onEdit, children }) {
49
51
  onEdit ? /*#__PURE__*/ jsx(IconButton, {
50
52
  variant: "text",
51
53
  onClick: onEdit,
52
- "aria-label": `Edit ${title}`,
54
+ "aria-label": editAriaLabel ?? title,
53
55
  children: /*#__PURE__*/ jsx(EditIcon, {
54
56
  width: "20px",
55
57
  height: "20px"
@@ -73,6 +75,7 @@ function RoleBadge({ role }) {
73
75
  function AccountContainer({ user, allRoles, initialUserRoles }) {
74
76
  const router = useRouter();
75
77
  const toastManager = useToastManager();
78
+ const { t } = useTranslation('byline-admin');
76
79
  const [currentUser, setCurrentUser] = useState(user);
77
80
  const [currentUserRoles, setCurrentUserRoles] = useState(initialUserRoles);
78
81
  const [current, setCurrent] = useState('empty');
@@ -101,14 +104,22 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
101
104
  setCurrentUserRoles(response.roles);
102
105
  router.invalidate();
103
106
  toastManager.add({
104
- title: 'Roles saved',
105
- description: `${response.roles.length} role${1 === response.roles.length ? '' : 's'} assigned to ${currentUser.email}.`,
107
+ title: t('adminUsers.detail.rolesSavedToast'),
108
+ description: t("adminUsers.detail.rolesAssignedDescription", {
109
+ count: response.roles.length,
110
+ email: currentUser.email
111
+ }),
106
112
  data: {
107
113
  intent: 'success'
108
114
  }
109
115
  });
110
116
  };
111
- const Panel = panels[current].component;
117
+ const currentMeta = panelMeta[current];
118
+ const Panel = currentMeta.component;
119
+ const currentTitle = currentMeta.titleKey ? t(currentMeta.titleKey) : '';
120
+ const editAriaFor = (section)=>t('account.editAriaLabel', {
121
+ section
122
+ });
112
123
  return /*#__PURE__*/ jsxs(Fragment, {
113
124
  children: [
114
125
  /*#__PURE__*/ jsxs("div", {
@@ -117,15 +128,16 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
117
128
  /*#__PURE__*/ jsx("div", {
118
129
  className: classnames('byline-admin-user-column', container_module.column),
119
130
  children: /*#__PURE__*/ jsxs(ContainerSection, {
120
- title: "Account Details",
131
+ title: t('adminUsers.detail.sections.account'),
121
132
  onEdit: openDrawer('update'),
133
+ editAriaLabel: editAriaFor(t('adminUsers.detail.sections.account')),
122
134
  children: [
123
135
  /*#__PURE__*/ jsxs("p", {
124
136
  className: classnames('byline-admin-user-line', container_module.line),
125
137
  children: [
126
138
  /*#__PURE__*/ jsx("span", {
127
139
  className: "muted",
128
- children: "Email:"
140
+ children: t('account.profile.emailColon')
129
141
  }),
130
142
  " ",
131
143
  currentUser.email
@@ -136,12 +148,12 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
136
148
  children: [
137
149
  /*#__PURE__*/ jsx("span", {
138
150
  className: "muted",
139
- children: "Given name:"
151
+ children: t('account.profile.givenName')
140
152
  }),
141
153
  ' ',
142
154
  currentUser.given_name ?? /*#__PURE__*/ jsx("span", {
143
155
  className: classnames('muted byline-admin-user-not-set', container_module.notSet),
144
- children: "Not set"
156
+ children: t('common.notSet')
145
157
  })
146
158
  ]
147
159
  }),
@@ -150,12 +162,12 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
150
162
  children: [
151
163
  /*#__PURE__*/ jsx("span", {
152
164
  className: "muted",
153
- children: "Family name:"
165
+ children: t('account.profile.familyName')
154
166
  }),
155
167
  ' ',
156
168
  currentUser.family_name ?? /*#__PURE__*/ jsx("span", {
157
169
  className: classnames('muted byline-admin-user-not-set', container_module.notSet),
158
- children: "Not set"
170
+ children: t('common.notSet')
159
171
  })
160
172
  ]
161
173
  }),
@@ -164,12 +176,12 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
164
176
  children: [
165
177
  /*#__PURE__*/ jsx("span", {
166
178
  className: "muted",
167
- children: "Username:"
179
+ children: t('account.profile.username')
168
180
  }),
169
181
  ' ',
170
182
  currentUser.username ?? /*#__PURE__*/ jsx("span", {
171
183
  className: classnames('muted byline-admin-user-not-set', container_module.notSet),
172
- children: "Not set"
184
+ children: t('common.notSet')
173
185
  })
174
186
  ]
175
187
  }),
@@ -178,10 +190,10 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
178
190
  children: [
179
191
  /*#__PURE__*/ jsx("span", {
180
192
  className: "muted",
181
- children: "Super admin:"
193
+ children: t('account.status.superAdmin')
182
194
  }),
183
195
  ' ',
184
- currentUser.is_super_admin ? 'Yes' : 'No'
196
+ currentUser.is_super_admin ? t('common.boolean.yes') : t('common.boolean.no')
185
197
  ]
186
198
  }),
187
199
  /*#__PURE__*/ jsxs("p", {
@@ -189,10 +201,10 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
189
201
  children: [
190
202
  /*#__PURE__*/ jsx("span", {
191
203
  className: "muted",
192
- children: "Email verified:"
204
+ children: t('account.status.emailVerified')
193
205
  }),
194
206
  ' ',
195
- currentUser.is_email_verified ? 'Yes' : 'No'
207
+ currentUser.is_email_verified ? t('common.boolean.yes') : t('common.boolean.no')
196
208
  ]
197
209
  }),
198
210
  /*#__PURE__*/ jsxs("p", {
@@ -200,7 +212,7 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
200
212
  children: [
201
213
  /*#__PURE__*/ jsx("span", {
202
214
  className: "muted",
203
- children: "Status:"
215
+ children: t('account.status.status')
204
216
  }),
205
217
  ' ',
206
218
  /*#__PURE__*/ jsx("span", {
@@ -210,23 +222,26 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
210
222
  'byline-admin-user-status-off': !currentUser.is_enabled,
211
223
  [container_module.statusOff]: !currentUser.is_enabled
212
224
  }),
213
- children: currentUser.is_enabled ? 'Enabled' : 'Disabled'
225
+ children: currentUser.is_enabled ? t('account.status.enabled') : t('account.status.disabled')
214
226
  })
215
227
  ]
216
228
  }),
217
229
  /*#__PURE__*/ jsx(Button, {
218
230
  size: "sm",
219
231
  onClick: openDrawer('update'),
220
- children: "Update Details"
232
+ children: t('adminUsers.detail.updateButton')
221
233
  }),
222
234
  /*#__PURE__*/ jsxs("div", {
223
235
  className: classnames('muted byline-admin-user-meta', container_module.meta),
224
236
  children: [
225
237
  /*#__PURE__*/ jsxs("p", {
226
238
  children: [
227
- /*#__PURE__*/ jsx("span", {
239
+ /*#__PURE__*/ jsxs("span", {
228
240
  className: "font-bold",
229
- children: "Created:\xa0"
241
+ children: [
242
+ t('account.profile.created'),
243
+ "\xa0"
244
+ ]
230
245
  }),
231
246
  /*#__PURE__*/ jsx(LocalDateTime, {
232
247
  value: currentUser.created_at
@@ -235,9 +250,12 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
235
250
  }),
236
251
  /*#__PURE__*/ jsxs("p", {
237
252
  children: [
238
- /*#__PURE__*/ jsx("span", {
253
+ /*#__PURE__*/ jsxs("span", {
239
254
  className: "font-bold",
240
- children: "Updated:\xa0"
255
+ children: [
256
+ t('account.profile.updated'),
257
+ "\xa0"
258
+ ]
241
259
  }),
242
260
  /*#__PURE__*/ jsx(LocalDateTime, {
243
261
  value: currentUser.updated_at
@@ -247,13 +265,16 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
247
265
  /*#__PURE__*/ jsxs("p", {
248
266
  className: classnames('byline-admin-user-line', container_module.line),
249
267
  children: [
250
- /*#__PURE__*/ jsx("span", {
268
+ /*#__PURE__*/ jsxs("span", {
251
269
  className: "font-bold",
252
- children: "Last login:\xa0"
270
+ children: [
271
+ t('account.profile.lastLogin'),
272
+ "\xa0"
273
+ ]
253
274
  }),
254
275
  /*#__PURE__*/ jsx(LocalDateTime, {
255
276
  value: currentUser.last_login,
256
- fallback: "Never"
277
+ fallback: t('common.never')
257
278
  })
258
279
  ]
259
280
  })
@@ -266,12 +287,13 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
266
287
  className: classnames('byline-admin-user-column', container_module.column),
267
288
  children: [
268
289
  /*#__PURE__*/ jsxs(ContainerSection, {
269
- title: "Roles",
290
+ title: t('adminUsers.detail.sections.roles'),
270
291
  onEdit: openDrawer('roles'),
292
+ editAriaLabel: editAriaFor(t('adminUsers.detail.sections.roles')),
271
293
  children: [
272
294
  0 === currentUserRoles.length ? /*#__PURE__*/ jsx("p", {
273
295
  className: classnames('muted byline-admin-user-role-empty', container_module.roleEmpty),
274
- children: "No roles assigned."
296
+ children: t('adminUsers.detail.rolesEmpty')
275
297
  }) : /*#__PURE__*/ jsx("div", {
276
298
  className: classnames('byline-admin-user-role-list', container_module.roleList),
277
299
  children: currentUserRoles.map((role)=>/*#__PURE__*/ jsx(RoleBadge, {
@@ -281,37 +303,38 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
281
303
  /*#__PURE__*/ jsx(Button, {
282
304
  size: "sm",
283
305
  onClick: openDrawer('roles'),
284
- children: "Edit Roles"
306
+ children: t('adminUsers.detail.editRolesButton')
285
307
  })
286
308
  ]
287
309
  }),
288
310
  /*#__PURE__*/ jsxs(ContainerSection, {
289
- title: "Password",
311
+ title: t('adminUsers.detail.sections.password'),
290
312
  onEdit: openDrawer('set_password'),
313
+ editAriaLabel: editAriaFor(t('adminUsers.detail.sections.password')),
291
314
  children: [
292
315
  /*#__PURE__*/ jsx("p", {
293
316
  className: classnames('byline-admin-user-line-spaced', container_module.lineSpaced),
294
- children: "Set a new password for this user."
317
+ children: t('adminUsers.detail.password.intro')
295
318
  }),
296
319
  /*#__PURE__*/ jsx(Button, {
297
320
  size: "sm",
298
321
  onClick: openDrawer('set_password'),
299
- children: "Set Password"
322
+ children: t('adminUsers.detail.password.setButton')
300
323
  })
301
324
  ]
302
325
  }),
303
326
  /*#__PURE__*/ jsxs(ContainerSection, {
304
- title: "Delete Admin User",
327
+ title: t('adminUsers.detail.sections.delete'),
305
328
  children: [
306
329
  /*#__PURE__*/ jsx("p", {
307
330
  className: classnames('byline-admin-user-line-spaced', container_module.lineSpaced),
308
- children: "Permanently delete this admin user."
331
+ children: t('adminUsers.detail.delete.intro')
309
332
  }),
310
333
  /*#__PURE__*/ jsx(Button, {
311
334
  size: "sm",
312
335
  intent: "danger",
313
336
  onClick: openModal('delete_user'),
314
- children: "Delete Admin User"
337
+ children: t('adminUsers.detail.delete.button')
315
338
  })
316
339
  ]
317
340
  })
@@ -327,10 +350,10 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
327
350
  isOpen: isDrawerOpen,
328
351
  onDismiss: closeDrawer,
329
352
  className: classnames({
330
- 'byline-admin-user-drawer-large': 'large' === panels[current].drawerWidth,
331
- [container_module.drawerLarge]: 'large' === panels[current].drawerWidth,
332
- 'byline-admin-user-drawer': 'large' !== panels[current].drawerWidth,
333
- [container_module.drawer]: 'large' !== panels[current].drawerWidth
353
+ 'byline-admin-user-drawer-large': 'large' === currentMeta.drawerWidth,
354
+ [container_module.drawerLarge]: 'large' === currentMeta.drawerWidth,
355
+ 'byline-admin-user-drawer': 'large' !== currentMeta.drawerWidth,
356
+ [container_module.drawer]: 'large' !== currentMeta.drawerWidth
334
357
  }),
335
358
  children: /*#__PURE__*/ jsxs(Drawer.Container, {
336
359
  "aria-hidden": !isDrawerOpen,
@@ -345,7 +368,7 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
345
368
  children: "no action"
346
369
  }),
347
370
  /*#__PURE__*/ jsx(IconButton, {
348
- "aria-label": "Close",
371
+ "aria-label": t('common.actions.close'),
349
372
  size: "sm",
350
373
  onClick: closeDrawer,
351
374
  children: /*#__PURE__*/ jsx(CloseIcon, {
@@ -358,7 +381,7 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
358
381
  }),
359
382
  /*#__PURE__*/ jsx(Drawer.Header, {
360
383
  children: /*#__PURE__*/ jsx("h2", {
361
- children: panels[current].title
384
+ children: currentTitle
362
385
  })
363
386
  }),
364
387
  /*#__PURE__*/ jsx(Drawer.Content, {
@@ -392,10 +415,10 @@ function AccountContainer({ user, allRoles, initialUserRoles }) {
392
415
  children: [
393
416
  /*#__PURE__*/ jsx("h3", {
394
417
  className: "m-0",
395
- children: panels[current].title
418
+ children: currentTitle
396
419
  }),
397
420
  /*#__PURE__*/ jsx(IconButton, {
398
- "aria-label": "Close",
421
+ "aria-label": t('common.actions.close'),
399
422
  size: "sm",
400
423
  onClick: closeModal,
401
424
  children: /*#__PURE__*/ jsx(CloseIcon, {
@@ -2,6 +2,7 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
4
  import { useRouter } from "@tanstack/react-router";
5
+ import { useTranslation } from "@byline/i18n/react";
5
6
  import { Alert, Button, LoaderEllipsis, Modal } from "@byline/ui/react";
6
7
  import classnames from "classnames";
7
8
  import { deleteAdminUser } from "../../server-fns/admin-users/index.js";
@@ -17,6 +18,7 @@ function displayNameFor(user) {
17
18
  function DeleteUser({ user, onClose }) {
18
19
  const navigate = useNavigate();
19
20
  const router = useRouter();
21
+ const { t } = useTranslation('byline-admin');
20
22
  const [error, setError] = useState(null);
21
23
  const [pending, setPending] = useState(false);
22
24
  async function handleDelete() {
@@ -37,9 +39,9 @@ function DeleteUser({ user, onClose }) {
37
39
  });
38
40
  } catch (err) {
39
41
  const code = getErrorCode(err);
40
- if ('admin.users.selfDeleteForbidden' === code) setError('You cannot delete your own admin account.');
41
- else if ('admin.users.versionConflict' === code) setError('This user has been modified elsewhere since you opened this dialog. Close and reload before trying again.');
42
- else 'admin.users.notFound' === code ? setError('This user has already been deleted.') : setError('Could not delete this admin user. Please try again.');
42
+ if ('admin.users.selfDeleteForbidden' === code) setError(t('adminUsers.delete.errors.selfDelete'));
43
+ else if ('admin.users.versionConflict' === code) setError(t('adminUsers.delete.errors.versionConflict'));
44
+ else 'admin.users.notFound' === code ? setError(t('adminUsers.delete.errors.notFound')) : setError(t('adminUsers.delete.errors.fallback'));
43
45
  setPending(false);
44
46
  }
45
47
  }
@@ -59,7 +61,7 @@ function DeleteUser({ user, onClose }) {
59
61
  children: [
60
62
  /*#__PURE__*/ jsx("span", {
61
63
  className: "muted",
62
- children: "User:"
64
+ children: t('adminUsers.delete.userLabel')
63
65
  }),
64
66
  " ",
65
67
  displayNameFor(user)
@@ -70,7 +72,7 @@ function DeleteUser({ user, onClose }) {
70
72
  children: [
71
73
  /*#__PURE__*/ jsx("span", {
72
74
  className: "muted",
73
- children: "Email:"
75
+ children: t('adminUsers.delete.emailLabel')
74
76
  }),
75
77
  " ",
76
78
  user.email
@@ -78,7 +80,7 @@ function DeleteUser({ user, onClose }) {
78
80
  }),
79
81
  /*#__PURE__*/ jsx("p", {
80
82
  className: classnames('byline-admin-user-delete-warning', delete_module.warning),
81
- children: "This will permanently delete the admin user. The action cannot be undone. Any active sessions will be invalidated at the next refresh."
83
+ children: t('adminUsers.delete.warning')
82
84
  })
83
85
  ]
84
86
  }),
@@ -92,7 +94,7 @@ function DeleteUser({ user, onClose }) {
92
94
  onClick: onClose,
93
95
  disabled: pending,
94
96
  className: classnames('byline-admin-user-delete-button', delete_module.button),
95
- children: "Cancel"
97
+ children: t('common.actions.cancel')
96
98
  }),
97
99
  /*#__PURE__*/ jsx(Button, {
98
100
  size: "sm",
@@ -102,7 +104,7 @@ function DeleteUser({ user, onClose }) {
102
104
  className: classnames('byline-admin-user-delete-button', delete_module.button),
103
105
  children: true === pending ? /*#__PURE__*/ jsx(LoaderEllipsis, {
104
106
  size: 42
105
- }) : 'Delete User'
107
+ }) : t('adminUsers.delete.confirmButton')
106
108
  })
107
109
  ]
108
110
  })
@@ -1,19 +1,21 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useState } from "react";
3
+ import { useMemo, useState } from "react";
4
4
  import { useRouter, useRouterState } from "@tanstack/react-router";
5
5
  import { CreateAdminUser } from "@byline/admin/admin-users/components/create";
6
- import { CloseIcon, Container, Drawer, IconButton, LocalDateTime, PlusIcon, Search, Section, Select, Table, useToastManager } from "@byline/ui/react";
6
+ import { LocalDateTime } from "@byline/admin/react";
7
+ import { useTranslation } from "@byline/i18n/react";
8
+ import { CloseIcon, Container, Drawer, IconButton, PlusIcon, Search, Section, Select, Table, useToastManager } from "@byline/ui/react";
7
9
  import classnames from "classnames";
8
10
  import { Link, useNavigate } from "../chrome/loose-router.js";
9
11
  import { RouterPager } from "../chrome/router-pager.js";
10
12
  import { TableHeadingCellSortable } from "../chrome/th-sortable.js";
11
13
  import { formatNumber } from "../chrome/utils.js";
12
14
  import list_module from "./list.module.js";
13
- const tableColumnDefs = [
15
+ const columnTemplates = [
14
16
  {
15
17
  fieldName: 'given_name',
16
- label: 'Given Name',
18
+ labelKey: 'adminUsers.list.columns.givenName',
17
19
  path: '/admin/users',
18
20
  sortable: true,
19
21
  scope: 'col',
@@ -22,7 +24,7 @@ const tableColumnDefs = [
22
24
  },
23
25
  {
24
26
  fieldName: 'family_name',
25
- label: 'Family Name',
27
+ labelKey: 'adminUsers.list.columns.familyName',
26
28
  path: '/admin/users',
27
29
  sortable: true,
28
30
  scope: 'col',
@@ -31,7 +33,7 @@ const tableColumnDefs = [
31
33
  },
32
34
  {
33
35
  fieldName: 'email',
34
- label: 'Email',
36
+ labelKey: 'adminUsers.list.columns.email',
35
37
  path: '/admin/users',
36
38
  sortable: true,
37
39
  scope: 'col',
@@ -40,7 +42,7 @@ const tableColumnDefs = [
40
42
  },
41
43
  {
42
44
  fieldName: 'updated_at',
43
- label: 'Updated',
45
+ labelKey: 'adminUsers.list.columns.updated',
44
46
  path: '/admin/users',
45
47
  sortable: true,
46
48
  scope: 'col',
@@ -49,7 +51,7 @@ const tableColumnDefs = [
49
51
  },
50
52
  {
51
53
  fieldName: 'created_at',
52
- label: 'Created',
54
+ labelKey: 'adminUsers.list.columns.created',
53
55
  path: '/admin/users',
54
56
  sortable: true,
55
57
  scope: 'col',
@@ -78,14 +80,21 @@ function AdminUsersListView({ data }) {
78
80
  const pathname = useRouterState({
79
81
  select: (s)=>s.location.pathname
80
82
  });
83
+ const { t } = useTranslation('byline-admin');
81
84
  const [isCreateDrawerOpen, setIsCreateDrawerOpen] = useState(false);
85
+ const tableColumnDefs = useMemo(()=>columnTemplates.map(({ labelKey, ...rest })=>({
86
+ ...rest,
87
+ label: t(labelKey)
88
+ })), [
89
+ t
90
+ ]);
82
91
  const openCreateDrawer = ()=>setIsCreateDrawerOpen(true);
83
92
  const closeCreateDrawer = ()=>setIsCreateDrawerOpen(false);
84
93
  const handleCreateSuccess = (created)=>{
85
94
  setIsCreateDrawerOpen(false);
86
95
  router.invalidate();
87
96
  toastManager.add({
88
- title: 'Admin user created',
97
+ title: t('adminUsers.list.createdToastTitle'),
89
98
  description: created.email,
90
99
  data: {
91
100
  intent: 'success'
@@ -134,13 +143,13 @@ function AdminUsersListView({ data }) {
134
143
  children: [
135
144
  /*#__PURE__*/ jsx("h1", {
136
145
  className: classnames('byline-admin-users-list-title', list_module.title),
137
- children: "Admin Users"
146
+ children: t('adminUsers.list.title')
138
147
  }),
139
148
  /*#__PURE__*/ jsx(Stats, {
140
149
  total: data.meta.total
141
150
  }),
142
151
  /*#__PURE__*/ jsx(IconButton, {
143
- "aria-label": "Create New Admin User",
152
+ "aria-label": t('adminUsers.list.createAriaLabel'),
144
153
  onClick: openCreateDrawer,
145
154
  children: /*#__PURE__*/ jsx(PlusIcon, {
146
155
  height: "18px",
@@ -157,7 +166,7 @@ function AdminUsersListView({ data }) {
157
166
  onSearch: handleOnSearch,
158
167
  onClear: handleOnClear,
159
168
  inputSize: "sm",
160
- placeholder: "Search by name or email",
169
+ placeholder: t('adminUsers.list.searchPlaceholder'),
161
170
  className: classnames('byline-admin-users-list-search', list_module.search)
162
171
  }),
163
172
  /*#__PURE__*/ jsx(RouterPager, {
@@ -166,7 +175,7 @@ function AdminUsersListView({ data }) {
166
175
  showFirstButton: true,
167
176
  showLastButton: true,
168
177
  componentName: "pagerTop",
169
- "aria-label": "Top Pager"
178
+ "aria-label": t('adminUsers.list.pagerTopAriaLabel')
170
179
  })
171
180
  ]
172
181
  }),
@@ -198,14 +207,14 @@ function AdminUsersListView({ data }) {
198
207
  },
199
208
  children: user.given_name ?? /*#__PURE__*/ jsx("span", {
200
209
  className: classnames('muted byline-admin-users-list-not-set', list_module.notSet),
201
- children: "Not set"
210
+ children: t('common.notSet')
202
211
  })
203
212
  })
204
213
  }),
205
214
  /*#__PURE__*/ jsx(Table.Cell, {
206
215
  children: user.family_name ?? /*#__PURE__*/ jsx("span", {
207
216
  className: classnames('muted byline-admin-users-list-not-set', list_module.notSet),
208
- children: "Not set"
217
+ children: t('common.notSet')
209
218
  })
210
219
  }),
211
220
  /*#__PURE__*/ jsx(Table.Cell, {
@@ -267,7 +276,7 @@ function AdminUsersListView({ data }) {
267
276
  showFirstButton: true,
268
277
  showLastButton: true,
269
278
  componentName: "pagerBottom",
270
- "aria-label": "Bottom Pager"
279
+ "aria-label": t('adminUsers.list.pagerBottomAriaLabel')
271
280
  })
272
281
  ]
273
282
  })
@@ -294,7 +303,7 @@ function AdminUsersListView({ data }) {
294
303
  children: "no action"
295
304
  }),
296
305
  /*#__PURE__*/ jsx(IconButton, {
297
- "aria-label": "Close",
306
+ "aria-label": t('common.actions.close'),
298
307
  size: "sm",
299
308
  onClick: closeCreateDrawer,
300
309
  children: /*#__PURE__*/ jsx(CloseIcon, {
@@ -307,7 +316,7 @@ function AdminUsersListView({ data }) {
307
316
  }),
308
317
  /*#__PURE__*/ jsx(Drawer.Header, {
309
318
  children: /*#__PURE__*/ jsx("h2", {
310
- children: "New Admin User"
319
+ children: t('adminUsers.list.newDrawerTitle')
311
320
  })
312
321
  }),
313
322
  /*#__PURE__*/ jsx(Drawer.Content, {
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
+ import { LanguageMenu, useTranslation } from "@byline/i18n/react";
4
5
  import { Button } from "@byline/ui/react";
5
6
  import classnames from "classnames";
6
7
  import { adminSignOut } from "../../server-fns/auth/index.js";
@@ -17,6 +18,7 @@ function displayNameFor(user) {
17
18
  }
18
19
  function AdminAppBar({ user }) {
19
20
  const { breadCrumbSettings } = useBreadcrumbs();
21
+ const { t } = useTranslation('byline-admin');
20
22
  const [signingOut, setSigningOut] = useState(false);
21
23
  async function handleSignOut() {
22
24
  if (signingOut) return;
@@ -45,10 +47,11 @@ function AdminAppBar({ user }) {
45
47
  /*#__PURE__*/ jsxs("div", {
46
48
  className: classnames('byline-admin-app-bar-right', admin_app_bar_module.right),
47
49
  children: [
50
+ /*#__PURE__*/ jsx(LanguageMenu, {}),
48
51
  /*#__PURE__*/ jsxs("span", {
49
52
  className: classnames('byline-admin-app-bar-user', admin_app_bar_module.user),
50
53
  children: [
51
- "Signed in as",
54
+ t('chrome.appBar.signedInAs'),
52
55
  ' ',
53
56
  /*#__PURE__*/ jsx("span", {
54
57
  className: classnames('byline-admin-app-bar-user-name', admin_app_bar_module.userName),
@@ -61,7 +64,7 @@ function AdminAppBar({ user }) {
61
64
  intent: "secondary",
62
65
  onClick: handleSignOut,
63
66
  disabled: signingOut,
64
- children: signingOut ? 'Signing out…' : 'Sign out'
67
+ children: signingOut ? t('common.actions.signingOut') : t('common.actions.signOut')
65
68
  })
66
69
  ]
67
70
  })