@allbluecn/admin-app 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/package.json +8 -8
  2. package/src/components/admin/admin-user-menu.tsx +12 -6
  3. package/src/components/admin/developer-log.tsx +42 -44
  4. package/src/components/ai-provider/model-list-editor.tsx +5 -4
  5. package/src/components/ai-provider/provider-form.tsx +63 -64
  6. package/src/components/ai-provider/provider-table.tsx +35 -36
  7. package/src/components/auth/admin-login-form.tsx +23 -24
  8. package/src/components/auth/oauth-section.tsx +3 -5
  9. package/src/components/auth/password-input.tsx +2 -3
  10. package/src/components/common/placeholder-page.tsx +2 -4
  11. package/src/components/component/component-form-dialog.tsx +48 -49
  12. package/src/components/component/component-import-dialog.tsx +5 -5
  13. package/src/components/component/component-table.tsx +13 -14
  14. package/src/components/data-table/data-table-pagination.tsx +4 -6
  15. package/src/components/data-table/table-detail-layout.tsx +2 -3
  16. package/src/components/dependency/changelog-dialog.tsx +3 -4
  17. package/src/components/dependency/columns.tsx +32 -24
  18. package/src/components/dependency/dependency-table.tsx +37 -29
  19. package/src/components/dependency/edit-dialog.tsx +24 -25
  20. package/src/components/knowledge-public/bookmark-form-dialog.tsx +7 -7
  21. package/src/components/knowledge-public/compliance-form-dialog.tsx +13 -13
  22. package/src/components/knowledge-public/legal-form-dialog.tsx +51 -46
  23. package/src/components/layout/sidebar-02/app-sidebar.tsx +33 -34
  24. package/src/components/layout/sidebar-02/nav-main.tsx +1 -1
  25. package/src/components/market/columns.tsx +20 -21
  26. package/src/components/market/market-app-form.tsx +45 -38
  27. package/src/components/market/market-app-list.tsx +16 -17
  28. package/src/components/monitoring/error-list.tsx +18 -19
  29. package/src/components/monitoring/health-cards.tsx +11 -13
  30. package/src/components/monitoring/metrics-stats.tsx +11 -12
  31. package/src/components/monitoring/request-log-table.tsx +8 -9
  32. package/src/components/ui/pagination.tsx +0 -2
  33. package/src/components/ui/sidebar.tsx +1 -1
  34. package/src/components/user/columns.tsx +9 -9
  35. package/src/components/user/settings-activity-log.tsx +39 -29
  36. package/src/components/user/settings-profile.tsx +36 -36
  37. package/src/components/user/user-create-dialog.tsx +4 -4
  38. package/src/components/user/user-filters.tsx +16 -18
  39. package/src/lib/i18n/config.ts +0 -32
  40. package/src/providers/index.tsx +6 -16
  41. package/src/routeTree.gen.ts +1199 -0
  42. package/src/routes/__root.tsx +9 -23
  43. package/src/routes/_nav/apps/route.lazy.tsx +2 -3
  44. package/src/routes/_nav/audit/route.lazy.tsx +10 -11
  45. package/src/routes/_nav/billing/invoices/route.lazy.tsx +6 -7
  46. package/src/routes/_nav/billing/route.lazy.tsx +3 -4
  47. package/src/routes/_nav/billing/subscriptions/$subscriptionId/route.lazy.tsx +16 -17
  48. package/src/routes/_nav/billing/subscriptions/route.lazy.tsx +9 -10
  49. package/src/routes/_nav/compliance/route.lazy.tsx +34 -35
  50. package/src/routes/_nav/components/route.lazy.tsx +6 -6
  51. package/src/routes/_nav/dashboard/route.lazy.tsx +3 -5
  52. package/src/routes/_nav/dependencies/route.lazy.tsx +7 -8
  53. package/src/routes/_nav/docs/route.lazy.tsx +2 -3
  54. package/src/routes/_nav/knowledge-public/bookmarks/route.lazy.tsx +40 -41
  55. package/src/routes/_nav/knowledge-public/compliance/route.lazy.tsx +32 -33
  56. package/src/routes/_nav/knowledge-public/legal/route.lazy.tsx +32 -33
  57. package/src/routes/_nav/licenses/$licenseId/route.lazy.tsx +24 -31
  58. package/src/routes/_nav/licenses/new/route.lazy.tsx +25 -26
  59. package/src/routes/_nav/licenses/route.lazy.tsx +17 -18
  60. package/src/routes/_nav/monitoring/ai-usage/route.lazy.tsx +26 -27
  61. package/src/routes/_nav/monitoring/errors/route.lazy.tsx +11 -12
  62. package/src/routes/_nav/monitoring/health/route.lazy.tsx +18 -20
  63. package/src/routes/_nav/monitoring/logs/route.lazy.tsx +12 -13
  64. package/src/routes/_nav/monitoring/metrics/route.lazy.tsx +13 -15
  65. package/src/routes/_nav/monitoring/overview/route.lazy.tsx +12 -13
  66. package/src/routes/_nav/monitoring/route.lazy.tsx +8 -9
  67. package/src/routes/_nav/monitoring/sentry/route.lazy.tsx +55 -57
  68. package/src/routes/_nav/permissions/route.lazy.tsx +48 -50
  69. package/src/routes/_nav/settings/route.lazy.tsx +2 -3
  70. package/src/routes/_nav/sso/route.lazy.tsx +20 -18
  71. package/src/routes/_nav/users/$userId/route.lazy.tsx +86 -82
  72. package/src/routes/_nav/users/route.lazy.tsx +4 -5
  73. package/src/routes/setup/route.lazy.tsx +15 -16
  74. package/src/start.ts +2 -2
  75. package/src/lib/i18n/client.ts +0 -32
  76. package/src/lib/i18n/locales/en/admin-ai.json +0 -128
  77. package/src/lib/i18n/locales/en/admin-billing.json +0 -56
  78. package/src/lib/i18n/locales/en/admin-users.json +0 -88
  79. package/src/lib/i18n/locales/en/common.json +0 -877
  80. package/src/lib/i18n/locales/en/enterprise.json +0 -208
  81. package/src/lib/i18n/locales/zh/admin-ai.json +0 -128
  82. package/src/lib/i18n/locales/zh/admin-billing.json +0 -56
  83. package/src/lib/i18n/locales/zh/admin-users.json +0 -88
  84. package/src/lib/i18n/locales/zh/common.json +0 -877
  85. package/src/lib/i18n/locales/zh/enterprise.json +0 -208
  86. package/src/lib/i18n/server.ts +0 -18
  87. package/src/lib/i18n/types.ts +0 -5
@@ -16,7 +16,7 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { useState } from "react"
19
- import { useTranslation } from 'react-i18next'
19
+ import { m } from '@/paraglide/messages.js'
20
20
  import { createLazyFileRoute } from "@tanstack/react-router"
21
21
  import { Boxes, Info } from "lucide-react"
22
22
  import type { ThirdPartyDependencyRow } from "@allbluecn/kernel"
@@ -29,7 +29,6 @@ export const Route = createLazyFileRoute("/_nav/dependencies")({
29
29
  })
30
30
 
31
31
  function DependenciesPage() {
32
- const { t } = useTranslation('common')
33
32
  const ctx = Route.useRouteContext() as { dependencies?: ThirdPartyDependencyRow[] }
34
33
  const [data, setData] = useState<ThirdPartyDependencyRow[]>(ctx.dependencies ?? [])
35
34
 
@@ -45,19 +44,19 @@ function DependenciesPage() {
45
44
  return (
46
45
  <div className="p-6 space-y-5">
47
46
  <PageHeader
48
- title={t('dependencies.title')}
49
- description={t('dependencies.description')}
47
+ title={m.common_dependencies_title()}
48
+ description={m.common_dependencies_description()}
50
49
  icon={Boxes}
51
50
  />
52
51
  <div className="flex items-start gap-2 rounded-md border border-blue-500/20 bg-blue-500/5 p-3 text-xs text-muted-foreground">
53
52
  <Info className="mt-0.5 size-3.5 shrink-0 text-blue-500" />
54
53
  <div>
55
- {t('dependencies.hint.currentVersion')}
54
+ {m.common_dependencies_hint_currentVersion()}
56
55
  <code className="font-mono">apps/web</code>、
57
56
  <code className="font-mono">apps/admin</code>、
58
- <code className="font-mono">packages/*</code> {t('dependencies.hint.currentVersionSuffix')}
59
- {t('dependencies.hint.latestVersion')}
60
- {t('dependencies.hint.watchList')}
57
+ <code className="font-mono">packages/*</code> {m.common_dependencies_hint_currentVersionSuffix()}
58
+ {m.common_dependencies_hint_latestVersion()}
59
+ {m.common_dependencies_hint_watchList()}
61
60
  </div>
62
61
  </div>
63
62
  <DependencyTable data={data} onMutated={refetch} />
@@ -16,7 +16,7 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createLazyFileRoute } from '@tanstack/react-router'
19
- import { useTranslation } from 'react-i18next'
19
+ import { m } from '@/paraglide/messages.js'
20
20
  import { FileText } from 'lucide-react'
21
21
  import { PlaceholderPage } from '@/components/common/placeholder-page'
22
22
 
@@ -25,6 +25,5 @@ export const Route = createLazyFileRoute('/_nav/docs')({
25
25
  })
26
26
 
27
27
  function DocsPage() {
28
- const { t } = useTranslation('common')
29
- return <PlaceholderPage title={t('docs.title')} icon={FileText} />
28
+ return <PlaceholderPage title={m.common_docs_title()} icon={FileText} />
30
29
  }
@@ -16,8 +16,8 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createLazyFileRoute, useNavigate, useRouter } from '@tanstack/react-router'
19
+ import { m } from '@/paraglide/messages.js'
19
20
  import { useState, useTransition } from 'react'
20
- import { useTranslation } from 'react-i18next'
21
21
  import {
22
22
  PlusIcon,
23
23
  PencilIcon,
@@ -89,7 +89,6 @@ function FaviconCell({ faviconUrl, categoryIcon }: { faviconUrl: string | null;
89
89
  }
90
90
 
91
91
  function BookmarksPage() {
92
- const { t } = useTranslation('common')
93
92
  const { items: rawItems, total } = Route.useLoaderData()
94
93
  const items = rawItems as unknown as BookmarkRow[]
95
94
  const { search } = Route.useSearch()
@@ -127,11 +126,11 @@ function BookmarksPage() {
127
126
  startDelete(async () => {
128
127
  try {
129
128
  await adminDeleteBookmarkFn({ data: { id: deleting.id } })
130
- toast.success(t('knowledgePublic.bookmarks.deleted'))
129
+ toast.success(m.common_knowledgePublic_bookmarks_deleted())
131
130
  setDeleting(null)
132
131
  refresh()
133
132
  } catch (err) {
134
- toast.error(err instanceof Error ? err.message : t('common.deleteFailed'))
133
+ toast.error(err instanceof Error ? err.message : m.common_common_deleteFailed())
135
134
  }
136
135
  })
137
136
  }
@@ -141,11 +140,11 @@ function BookmarksPage() {
141
140
  try {
142
141
  const res = await adminSyncAllGithubFn({ data: { force: true } })
143
142
  toast.success(
144
- t('knowledgePublic.bookmarks.syncComplete', { total: res.total, success: res.success, failed: res.failed }),
143
+ m.common_knowledgePublic_bookmarks_syncComplete({ total: res.total, success: res.success, failed: res.failed }),
145
144
  )
146
145
  refresh()
147
146
  } catch (err) {
148
- toast.error(err instanceof Error ? err.message : t('knowledgePublic.bookmarks.syncFailed'))
147
+ toast.error(err instanceof Error ? err.message : m.common_knowledgePublic_bookmarks_syncFailed())
149
148
  }
150
149
  })
151
150
  }
@@ -153,8 +152,8 @@ function BookmarksPage() {
153
152
  const columns: AdminColumnDef<BookmarkRow>[] = [
154
153
  {
155
154
  accessorKey: 'title',
156
- header: t('knowledgePublic.bookmarks.columns.website'),
157
- cell: ({ row }) => {
155
+ header: m.common_knowledgePublic_bookmarks_columns_website(),
156
+ cell: ({ row }: any) => {
158
157
  const b = row.original
159
158
  return (
160
159
  <div className="flex min-w-[180px] items-center gap-2">
@@ -173,8 +172,8 @@ function BookmarksPage() {
173
172
  },
174
173
  {
175
174
  accessorKey: 'url',
176
- header: t('knowledgePublic.bookmarks.columns.url'),
177
- cell: ({ row }) => {
175
+ header: m.common_knowledgePublic_bookmarks_columns_url(),
176
+ cell: ({ row }: any) => {
178
177
  const url = row.original.url
179
178
  return (
180
179
  <a
@@ -191,8 +190,8 @@ function BookmarksPage() {
191
190
  },
192
191
  {
193
192
  accessorKey: 'categoryId',
194
- header: t('knowledgePublic.bookmarks.columns.category'),
195
- cell: ({ row }) =>
193
+ header: m.common_knowledgePublic_bookmarks_columns_category(),
194
+ cell: ({ row }: any) =>
196
195
  row.original.categoryId ? (
197
196
  <Badge variant="outline" className="font-mono text-xs">
198
197
  {row.original.categoryId}
@@ -204,7 +203,7 @@ function BookmarksPage() {
204
203
  {
205
204
  id: 'github',
206
205
  header: 'GitHub',
207
- cell: ({ row }) => {
206
+ cell: ({ row }: any) => {
208
207
  const b = row.original
209
208
  if (!b.isGithub) return <span className="text-muted-foreground">-</span>
210
209
  return (
@@ -224,13 +223,13 @@ function BookmarksPage() {
224
223
  },
225
224
  {
226
225
  accessorKey: 'tags',
227
- header: t('knowledgePublic.bookmarks.columns.tags'),
228
- cell: ({ row }) => (
226
+ header: m.common_knowledgePublic_bookmarks_columns_tags(),
227
+ cell: ({ row }: any) => (
229
228
  <div className="flex max-w-xs flex-wrap gap-1">
230
229
  {row.original.tags.length === 0 ? (
231
230
  <span className="text-muted-foreground">-</span>
232
231
  ) : (
233
- row.original.tags.map((tag) => (
232
+ row.original.tags.map((tag: string) => (
234
233
  <Badge key={tag} variant="secondary" className="font-normal">
235
234
  {tag}
236
235
  </Badge>
@@ -241,8 +240,8 @@ function BookmarksPage() {
241
240
  },
242
241
  {
243
242
  accessorKey: 'createdAt',
244
- header: t('knowledgePublic.bookmarks.columns.createdAt'),
245
- cell: ({ row }) => (
243
+ header: m.common_knowledgePublic_bookmarks_columns_createdAt(),
244
+ cell: ({ row }: any) => (
246
245
  <span className="text-muted-foreground">
247
246
  {new Date(row.original.createdAt).toLocaleDateString('zh-CN')}
248
247
  </span>
@@ -251,30 +250,30 @@ function BookmarksPage() {
251
250
  {
252
251
  id: 'actions',
253
252
  header: '',
254
- cell: ({ row }) => (
253
+ cell: ({ row }: any) => (
255
254
  <div className="flex items-center gap-1">
256
255
  <Button
257
256
  variant="ghost"
258
257
  size="sm"
259
- onClick={(e) => {
258
+ onClick={(e: React.MouseEvent) => {
260
259
  e.stopPropagation()
261
260
  openEdit(row.original)
262
261
  }}
263
262
  >
264
263
  <PencilIcon className="mr-1 size-3.5" />
265
- {t('common.edit')}
264
+ {m.common_common_edit()}
266
265
  </Button>
267
266
  <Button
268
267
  variant="ghost"
269
268
  size="sm"
270
269
  className="text-destructive hover:text-destructive"
271
- onClick={(e) => {
270
+ onClick={(e: React.MouseEvent) => {
272
271
  e.stopPropagation()
273
272
  setDeleting(row.original)
274
273
  }}
275
274
  >
276
275
  <Trash2Icon className="mr-1 size-3.5" />
277
- {t('common.delete')}
276
+ {m.common_common_delete()}
278
277
  </Button>
279
278
  </div>
280
279
  ),
@@ -285,17 +284,17 @@ function BookmarksPage() {
285
284
  <div className="space-y-4 p-6">
286
285
  <div className="flex items-center justify-between">
287
286
  <div>
288
- <h2 className="text-xl font-bold">{t('knowledgePublic.bookmarks.title')}</h2>
289
- <p className="text-sm text-muted-foreground">{t('knowledgePublic.bookmarks.subtitle', { total })}</p>
287
+ <h2 className="text-xl font-bold">{m.common_knowledgePublic_bookmarks_title()}</h2>
288
+ <p className="text-sm text-muted-foreground">{m.common_knowledgePublic_bookmarks_subtitle({ total })}</p>
290
289
  </div>
291
290
  <div className="flex items-center gap-2">
292
291
  <Button variant="outline" onClick={syncAllGithub} disabled={syncing}>
293
292
  <RefreshCwIcon className={`mr-1 size-4 ${syncing ? 'animate-spin' : ''}`} />
294
- {syncing ? t('knowledgePublic.bookmarks.syncing') : t('knowledgePublic.bookmarks.syncGithub')}
293
+ {syncing ? m.common_knowledgePublic_bookmarks_syncing() : m.common_knowledgePublic_bookmarks_syncGithub()}
295
294
  </Button>
296
295
  <Button onClick={openCreate}>
297
296
  <PlusIcon className="mr-1 size-4" />
298
- {t('common.create')}
297
+ {m.common_common_create()}
299
298
  </Button>
300
299
  </div>
301
300
  </div>
@@ -305,16 +304,16 @@ function BookmarksPage() {
305
304
  <SearchIcon className="absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground" />
306
305
  <Input
307
306
  value={searchInput}
308
- onChange={(e) => setSearchInput(e.target.value)}
309
- onKeyDown={(e) => {
307
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchInput(e.target.value)}
308
+ onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
310
309
  if (e.key === 'Enter') applySearch()
311
310
  }}
312
- placeholder={t('knowledgePublic.bookmarks.placeholder')}
311
+ placeholder={m.common_knowledgePublic_bookmarks_placeholder()}
313
312
  className="pl-8"
314
313
  />
315
314
  </div>
316
315
  <Button variant="outline" onClick={applySearch}>
317
- {t('common.search')}
316
+ {m.common_common_search()}
318
317
  </Button>
319
318
  </div>
320
319
 
@@ -327,25 +326,25 @@ function BookmarksPage() {
327
326
  onSuccess={refresh}
328
327
  />
329
328
 
330
- <AlertDialog open={!!deleting} onOpenChange={(o) => !o && setDeleting(null)}>
329
+ <AlertDialog open={!!deleting} onOpenChange={(o: boolean) => !o && setDeleting(null)}>
331
330
  <AlertDialogContent>
332
331
  <AlertDialogHeader>
333
- <AlertDialogTitle>{t('knowledgePublic.bookmarks.deleteConfirmTitle')}</AlertDialogTitle>
332
+ <AlertDialogTitle>{m.common_knowledgePublic_bookmarks_deleteConfirmTitle()}</AlertDialogTitle>
334
333
  <AlertDialogDescription>
335
- {t('knowledgePublic.bookmarks.deleteConfirmDesc', { title: deleting?.title })}
334
+ {m.common_knowledgePublic_bookmarks_deleteConfirmDesc({ title: deleting?.title ?? '' })}
336
335
  </AlertDialogDescription>
337
336
  </AlertDialogHeader>
338
337
  <AlertDialogFooter>
339
- <AlertDialogCancel disabled={deletePending}>{t('common.cancel')}</AlertDialogCancel>
338
+ <AlertDialogCancel disabled={deletePending}>{m.common_common_cancel()}</AlertDialogCancel>
340
339
  <AlertDialogAction
341
- onClick={(e) => {
342
- e.preventDefault()
343
- confirmDelete()
344
- }}
345
- disabled={deletePending}
340
+ onClick={(e: React.MouseEvent) => {
341
+ e.preventDefault()
342
+ confirmDelete()
343
+ }}
344
+ disabled={deletePending}
346
345
  className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
347
346
  >
348
- {deletePending ? t('common.deleting') : t('common.delete')}
347
+ {deletePending ? m.common_common_deleting() : m.common_common_delete()}
349
348
  </AlertDialogAction>
350
349
  </AlertDialogFooter>
351
350
  </AlertDialogContent>
@@ -16,8 +16,8 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createLazyFileRoute, useNavigate, useRouter } from '@tanstack/react-router'
19
+ import { m } from '@/paraglide/messages.js'
19
20
  import { useState, useTransition } from 'react'
20
- import { useTranslation } from 'react-i18next'
21
21
  import { PlusIcon, PencilIcon, Trash2Icon, SearchIcon } from 'lucide-react'
22
22
  import { DataTable, type AdminColumnDef } from '@/components/data-table/data-table'
23
23
  import { Button } from '@/components/ui/button'
@@ -50,7 +50,6 @@ export const Route = createLazyFileRoute('/_nav/knowledge-public/compliance')({
50
50
  })
51
51
 
52
52
  function CompliancePage() {
53
- const { t } = useTranslation('common')
54
53
  const { items: rawItems, total } = Route.useLoaderData()
55
54
  const items = rawItems as unknown as ComplianceRow[]
56
55
  const { search } = Route.useSearch()
@@ -87,11 +86,11 @@ function CompliancePage() {
87
86
  startDelete(async () => {
88
87
  try {
89
88
  await adminDeleteComplianceFn({ data: { id: deleting.id } })
90
- toast.success(t('knowledgePublic.compliance.deleted'))
89
+ toast.success(m.common_knowledgePublic_compliance_deleted())
91
90
  setDeleting(null)
92
91
  refresh()
93
92
  } catch (err) {
94
- toast.error(err instanceof Error ? err.message : t('common.deleteFailed'))
93
+ toast.error(err instanceof Error ? err.message : m.common_common_deleteFailed())
95
94
  }
96
95
  })
97
96
  }
@@ -99,20 +98,20 @@ function CompliancePage() {
99
98
  const columns: AdminColumnDef<ComplianceRow>[] = [
100
99
  {
101
100
  accessorKey: 'title',
102
- header: t('knowledgePublic.compliance.columns.title'),
103
- cell: ({ row }) => <span className="font-medium">{row.original.title}</span>,
101
+ header: m.common_knowledgePublic_compliance_columns_title(),
102
+ cell: ({ row }: any) => <span className="font-medium">{row.original.title}</span>,
104
103
  },
105
104
  {
106
105
  accessorKey: 'industry',
107
- header: t('knowledgePublic.compliance.columns.industry'),
108
- cell: ({ row }) => (
106
+ header: m.common_knowledgePublic_compliance_columns_industry(),
107
+ cell: ({ row }: any) => (
109
108
  <Badge variant="outline">{row.original.industry}</Badge>
110
109
  ),
111
110
  },
112
111
  {
113
112
  accessorKey: 'regulatoryBody',
114
- header: t('knowledgePublic.compliance.columns.regulatoryBody'),
115
- cell: ({ row }) => (
113
+ header: m.common_knowledgePublic_compliance_columns_regulatoryBody(),
114
+ cell: ({ row }: any) => (
116
115
  <span className="text-muted-foreground">
117
116
  {row.original.regulatoryBody ?? '-'}
118
117
  </span>
@@ -120,13 +119,13 @@ function CompliancePage() {
120
119
  },
121
120
  {
122
121
  accessorKey: 'tags',
123
- header: t('knowledgePublic.compliance.columns.tags'),
124
- cell: ({ row }) => (
122
+ header: m.common_knowledgePublic_compliance_columns_tags(),
123
+ cell: ({ row }: any) => (
125
124
  <div className="flex max-w-xs flex-wrap gap-1">
126
125
  {row.original.tags.length === 0 ? (
127
126
  <span className="text-muted-foreground">-</span>
128
127
  ) : (
129
- row.original.tags.map((tag) => (
128
+ row.original.tags.map((tag: string) => (
130
129
  <Badge key={tag} variant="secondary" className="font-normal">
131
130
  {tag}
132
131
  </Badge>
@@ -137,8 +136,8 @@ function CompliancePage() {
137
136
  },
138
137
  {
139
138
  accessorKey: 'createdAt',
140
- header: t('knowledgePublic.compliance.columns.createdAt'),
141
- cell: ({ row }) => (
139
+ header: m.common_knowledgePublic_compliance_columns_createdAt(),
140
+ cell: ({ row }: any) => (
142
141
  <span className="text-muted-foreground">
143
142
  {new Date(row.original.createdAt).toLocaleDateString('zh-CN')}
144
143
  </span>
@@ -147,30 +146,30 @@ function CompliancePage() {
147
146
  {
148
147
  id: 'actions',
149
148
  header: '',
150
- cell: ({ row }) => (
149
+ cell: ({ row }: any) => (
151
150
  <div className="flex items-center gap-1">
152
151
  <Button
153
152
  variant="ghost"
154
153
  size="sm"
155
- onClick={(e) => {
154
+ onClick={(e: React.MouseEvent) => {
156
155
  e.stopPropagation()
157
156
  openEdit(row.original)
158
157
  }}
159
158
  >
160
159
  <PencilIcon className="mr-1 size-3.5" />
161
- {t('common.edit')}
160
+ {m.common_common_edit()}
162
161
  </Button>
163
162
  <Button
164
163
  variant="ghost"
165
164
  size="sm"
166
165
  className="text-destructive hover:text-destructive"
167
- onClick={(e) => {
166
+ onClick={(e: React.MouseEvent) => {
168
167
  e.stopPropagation()
169
168
  setDeleting(row.original)
170
169
  }}
171
170
  >
172
171
  <Trash2Icon className="mr-1 size-3.5" />
173
- {t('common.delete')}
172
+ {m.common_common_delete()}
174
173
  </Button>
175
174
  </div>
176
175
  ),
@@ -181,12 +180,12 @@ function CompliancePage() {
181
180
  <div className="space-y-4 p-6">
182
181
  <div className="flex items-center justify-between">
183
182
  <div>
184
- <h2 className="text-xl font-bold">{t('knowledgePublic.compliance.title')}</h2>
185
- <p className="text-sm text-muted-foreground">{t('knowledgePublic.compliance.subtitle', { total })}</p>
183
+ <h2 className="text-xl font-bold">{m.common_knowledgePublic_compliance_title()}</h2>
184
+ <p className="text-sm text-muted-foreground">{m.common_knowledgePublic_compliance_subtitle({ total })}</p>
186
185
  </div>
187
186
  <Button onClick={openCreate}>
188
187
  <PlusIcon className="mr-1 size-4" />
189
- {t('common.create')}
188
+ {m.common_common_create()}
190
189
  </Button>
191
190
  </div>
192
191
 
@@ -195,16 +194,16 @@ function CompliancePage() {
195
194
  <SearchIcon className="absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground" />
196
195
  <Input
197
196
  value={searchInput}
198
- onChange={(e) => setSearchInput(e.target.value)}
199
- onKeyDown={(e) => {
197
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchInput(e.target.value)}
198
+ onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
200
199
  if (e.key === 'Enter') applySearch()
201
200
  }}
202
- placeholder={t('knowledgePublic.compliance.placeholder')}
201
+ placeholder={m.common_knowledgePublic_compliance_placeholder()}
203
202
  className="pl-8"
204
203
  />
205
204
  </div>
206
205
  <Button variant="outline" onClick={applySearch}>
207
- {t('common.search')}
206
+ {m.common_common_search()}
208
207
  </Button>
209
208
  </div>
210
209
 
@@ -217,25 +216,25 @@ function CompliancePage() {
217
216
  onSuccess={refresh}
218
217
  />
219
218
 
220
- <AlertDialog open={!!deleting} onOpenChange={(o) => !o && setDeleting(null)}>
219
+ <AlertDialog open={!!deleting} onOpenChange={(o: boolean) => !o && setDeleting(null)}>
221
220
  <AlertDialogContent>
222
221
  <AlertDialogHeader>
223
- <AlertDialogTitle>{t('knowledgePublic.compliance.deleteConfirmTitle')}</AlertDialogTitle>
222
+ <AlertDialogTitle>{m.common_knowledgePublic_compliance_deleteConfirmTitle()}</AlertDialogTitle>
224
223
  <AlertDialogDescription>
225
- {t('knowledgePublic.compliance.deleteConfirmDesc', { title: deleting?.title })}
224
+ {m.common_knowledgePublic_compliance_deleteConfirmDesc({ title: deleting?.title ?? '' })}
226
225
  </AlertDialogDescription>
227
226
  </AlertDialogHeader>
228
227
  <AlertDialogFooter>
229
- <AlertDialogCancel disabled={deletePending}>{t('common.cancel')}</AlertDialogCancel>
228
+ <AlertDialogCancel disabled={deletePending}>{m.common_common_cancel()}</AlertDialogCancel>
230
229
  <AlertDialogAction
231
- onClick={(e) => {
230
+ onClick={(e: React.MouseEvent) => {
232
231
  e.preventDefault()
233
232
  confirmDelete()
234
233
  }}
235
234
  disabled={deletePending}
236
235
  className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
237
236
  >
238
- {deletePending ? t('common.deleting') : t('common.delete')}
237
+ {deletePending ? m.common_common_deleting() : m.common_common_delete()}
239
238
  </AlertDialogAction>
240
239
  </AlertDialogFooter>
241
240
  </AlertDialogContent>