@ploykit/ui 0.1.1 → 0.4.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 (145) hide show
  1. package/README.md +183 -23
  2. package/dist/AppProviders.d.ts +15 -0
  3. package/dist/AppProviders.js +15 -0
  4. package/dist/components/ConfirmDialog.js +8 -2
  5. package/dist/components/CronInput.js +2 -2
  6. package/dist/components/DataTable.d.ts +12 -3
  7. package/dist/components/DataTable.js +7 -3
  8. package/dist/components/ErrorBoundary.js +1 -1
  9. package/dist/components/ImpersonationBanner.js +1 -1
  10. package/dist/components/NotificationBell.js +5 -5
  11. package/dist/components/OnboardingChecklist.js +3 -3
  12. package/dist/components/Page.js +1 -1
  13. package/dist/components/ReauthDialog.d.ts +15 -0
  14. package/dist/components/ReauthDialog.js +42 -0
  15. package/dist/components/SecretModal.d.ts +8 -1
  16. package/dist/components/SecretModal.js +6 -3
  17. package/dist/components/SettingsCard.js +2 -2
  18. package/dist/components/SiteBannerLayer.js +1 -1
  19. package/dist/components/StatusBadge.d.ts +4 -0
  20. package/dist/components/StatusBadge.js +7 -0
  21. package/dist/components/UserMenu.js +2 -2
  22. package/dist/components/WorkspaceSwitcher.js +4 -4
  23. package/dist/components/ui/alert-dialog.d.ts +2 -2
  24. package/dist/components/ui/alert-dialog.js +10 -9
  25. package/dist/components/ui/avatar.js +3 -2
  26. package/dist/components/ui/badge.d.ts +7 -0
  27. package/dist/components/ui/badge.js +33 -0
  28. package/dist/components/ui/breadcrumb.js +7 -7
  29. package/dist/components/ui/button.d.ts +8 -0
  30. package/dist/components/ui/button.js +34 -0
  31. package/dist/components/ui/card.d.ts +2 -4
  32. package/dist/components/ui/card.js +7 -7
  33. package/dist/components/ui/checkbox.js +3 -2
  34. package/dist/components/ui/dialog.d.ts +22 -14
  35. package/dist/components/ui/dialog.js +40 -25
  36. package/dist/components/ui/dropdown-menu.js +50 -0
  37. package/dist/components/ui/empty.d.ts +7 -9
  38. package/dist/components/ui/empty.js +6 -9
  39. package/dist/components/ui/field.js +10 -9
  40. package/dist/components/ui/input.d.ts +3 -0
  41. package/dist/components/ui/input.js +7 -0
  42. package/dist/components/ui/popover.js +3 -2
  43. package/dist/components/ui/progress.js +2 -1
  44. package/dist/components/ui/select.d.ts +20 -1
  45. package/dist/components/ui/select.js +28 -7
  46. package/dist/components/ui/separator.js +1 -0
  47. package/dist/components/ui/sheet.d.ts +9 -1
  48. package/dist/components/ui/sheet.js +11 -4
  49. package/dist/components/ui/sidebar.d.ts +2 -2
  50. package/dist/components/ui/sidebar.js +25 -34
  51. package/dist/components/ui/skeleton.d.ts +1 -2
  52. package/dist/components/ui/switch.js +1 -1
  53. package/dist/components/ui/tabs.js +3 -3
  54. package/dist/components/ui/textarea.d.ts +9 -0
  55. package/dist/components/ui/textarea.js +12 -0
  56. package/dist/components/ui/tooltip.js +1 -1
  57. package/dist/index.d.ts +10 -40
  58. package/dist/index.js +10 -26
  59. package/dist/layouts/AppShell.d.ts +1 -1
  60. package/dist/layouts/AppShell.js +23 -1
  61. package/dist/layouts/SettingsShell.d.ts +1 -1
  62. package/dist/layouts/SettingsShell.js +3 -3
  63. package/dist/pages/LandingPage.js +1 -1
  64. package/dist/pages/LoginPage.js +7 -7
  65. package/dist/pages/account/NotificationPreferencesPage.js +2 -2
  66. package/dist/pages/account/ProfileSettingsPage.js +7 -7
  67. package/dist/pages/account/SecuritySettingsPage.js +8 -8
  68. package/dist/pages/account/TokensPage.js +4 -4
  69. package/dist/pages/admin/AdminSettingsPage.js +5 -5
  70. package/dist/pages/admin/AdminShell.js +2 -2
  71. package/dist/pages/admin/AuditPage.js +3 -3
  72. package/dist/pages/admin/OrdersPage.js +4 -3
  73. package/dist/pages/admin/OverviewPage.js +4 -4
  74. package/dist/pages/admin/SSOPage.js +3 -3
  75. package/dist/pages/admin/UserDetailPage.js +6 -5
  76. package/dist/pages/admin/UsersPage.js +7 -6
  77. package/dist/pages/admin/WebhookDeliveriesPage.js +4 -3
  78. package/dist/pages/admin/WorkspaceDetailPage.js +5 -5
  79. package/dist/pages/admin/WorkspacesPage.js +4 -4
  80. package/dist/pages/admin/shared.js +1 -1
  81. package/dist/pages/auth/ForgotPasswordPage.js +3 -3
  82. package/dist/pages/auth/InviteAcceptPage.js +4 -4
  83. package/dist/pages/auth/RegisterPage.js +6 -6
  84. package/dist/pages/auth/ResetPasswordPage.js +4 -4
  85. package/dist/pages/auth/VerifyEmailPage.js +4 -4
  86. package/dist/pages/workspace/BillingPage.js +8 -7
  87. package/dist/pages/workspace/BillingSuccessPage.js +3 -3
  88. package/dist/pages/workspace/MembersPage.js +7 -6
  89. package/dist/pages/workspace/RolePermissionsPage.d.ts +3 -0
  90. package/dist/pages/workspace/RolePermissionsPage.js +118 -0
  91. package/dist/pages/workspace/SchedulesPage.js +5 -5
  92. package/dist/pages/workspace/UsagePage.d.ts +1 -1
  93. package/dist/pages/workspace/UsagePage.js +2 -2
  94. package/dist/pages/workspace/WebhooksPage.js +9 -9
  95. package/dist/pages/workspace/WorkspaceAuditPage.js +3 -3
  96. package/dist/pages/workspace/WorkspaceGeneralPage.js +7 -7
  97. package/package.json +9 -5
  98. package/dist/components/ui/Badge.d.ts +0 -13
  99. package/dist/components/ui/Badge.js +0 -21
  100. package/dist/components/ui/Button.d.ts +0 -10
  101. package/dist/components/ui/Button.js +0 -33
  102. package/dist/components/ui/Input.d.ts +0 -3
  103. package/dist/components/ui/Input.js +0 -10
  104. package/dist/components/ui/menu.js +0 -50
  105. package/dist/hooks/useApi.d.ts +0 -10
  106. package/dist/hooks/useApi.js +0 -11
  107. package/dist/hooks/useAudit.d.ts +0 -39
  108. package/dist/hooks/useAudit.js +0 -55
  109. package/dist/hooks/useAuth.d.ts +0 -1
  110. package/dist/hooks/useAuth.js +0 -4
  111. package/dist/hooks/useBilling.d.ts +0 -44
  112. package/dist/hooks/useBilling.js +0 -64
  113. package/dist/hooks/useLogin.d.ts +0 -10
  114. package/dist/hooks/useLogin.js +0 -39
  115. package/dist/hooks/useMembers.d.ts +0 -125
  116. package/dist/hooks/useMembers.js +0 -127
  117. package/dist/hooks/useNotificationPrefs.d.ts +0 -20
  118. package/dist/hooks/useNotificationPrefs.js +0 -42
  119. package/dist/hooks/usePasswordReset.d.ts +0 -5
  120. package/dist/hooks/usePasswordReset.js +0 -12
  121. package/dist/hooks/useSEO.d.ts +0 -6
  122. package/dist/hooks/useSEO.js +0 -14
  123. package/dist/hooks/useSessions.d.ts +0 -20
  124. package/dist/hooks/useSessions.js +0 -38
  125. package/dist/hooks/useSiteConfig.d.ts +0 -12
  126. package/dist/hooks/useSiteConfig.js +0 -11
  127. package/dist/hooks/useTokens.d.ts +0 -36
  128. package/dist/hooks/useTokens.js +0 -35
  129. package/dist/hooks/useUsage.d.ts +0 -20
  130. package/dist/hooks/useUsage.js +0 -21
  131. package/dist/hooks/useWorkspace.d.ts +0 -26
  132. package/dist/hooks/useWorkspace.js +0 -32
  133. package/dist/hooks/useZodForm.d.ts +0 -6
  134. package/dist/hooks/useZodForm.js +0 -6
  135. package/dist/hooks/ws.d.ts +0 -4
  136. package/dist/hooks/ws.js +0 -21
  137. package/dist/lib/perm.d.ts +0 -2
  138. package/dist/lib/perm.js +0 -7
  139. package/dist/lib/ws-query-bridge.d.ts +0 -7
  140. package/dist/lib/ws-query-bridge.js +0 -35
  141. package/dist/provider/PloykitProvider.d.ts +0 -50
  142. package/dist/provider/PloykitProvider.js +0 -240
  143. package/dist/realtime.d.ts +0 -3
  144. package/dist/realtime.js +0 -11
  145. /package/dist/components/ui/{menu.d.ts → dropdown-menu.d.ts} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,32 +1,19 @@
1
- export { PloykitProvider, queryKeys } from './provider/PloykitProvider';
2
- export type { PKUser, PKWorkspace, PKSubscription, PKOrder, PKPlan } from './provider/PloykitProvider';
3
- export { useAuth } from './hooks/useAuth';
4
- export { useLogin } from './hooks/useLogin';
5
- export { useWorkspace, useWorkspaceSwitch } from './hooks/useWorkspace';
6
- export { useBilling, useUsagePreview, PlanGate } from './hooks/useBilling';
7
- export { useApi, ApiError } from './hooks/useApi';
8
- export type { ApiFetchOptions } from './hooks/useApi';
9
- export { useSEO } from './hooks/useSEO';
10
- export type { SeoMeta } from './hooks/useSEO';
11
- export { useWsStatus, useWsScope, useWsFrame } from './hooks/ws';
12
- export { createWsClient, defaultWsUrl } from './realtime';
13
- export { bridgeWsToQuery } from './lib/ws-query-bridge';
14
- export type { WsInvalidationRule } from './lib/ws-query-bridge';
15
1
  export { AppShell } from './layouts/AppShell';
16
2
  export type { NavItem } from './layouts/AppShell';
17
3
  export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger, } from './components/ui/sidebar';
18
4
  export { Separator } from './components/ui/separator';
19
5
  export { Skeleton } from './components/ui/skeleton';
20
6
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from './components/ui/tooltip';
21
- export { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from './components/ui/sheet';
7
+ export { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetTrigger, SheetClose } from './components/ui/sheet';
8
+ export { AppProviders } from './AppProviders';
22
9
  export { LoginPage } from './pages/LoginPage';
23
10
  export type { OAuthProviderOption, LoginPageProps } from './pages/LoginPage';
24
11
  export { LandingPage } from './pages/LandingPage';
25
12
  export type { Feature as LandingFeature, Plan as LandingPlan } from './pages/LandingPage';
26
- export { Button, buttonVariants } from './components/ui/Button';
27
- export type { ButtonProps } from './components/ui/Button';
28
- export { Input } from './components/ui/Input';
29
- export { Badge, badgeVariants, StatusBadge } from './components/ui/Badge';
13
+ export { Button, buttonVariants } from './components/ui/button';
14
+ export { Input } from './components/ui/input';
15
+ export { Textarea } from './components/ui/textarea';
16
+ export { StatusBadge } from './components/StatusBadge';
30
17
  export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, } from './components/ui/dialog';
31
18
  export { PageHeader, PageLoading, PageEmpty, PageError } from './components/Page';
32
19
  export { ConfirmProvider, useConfirm } from './components/ConfirmDialog';
@@ -35,9 +22,6 @@ export { WorkspaceSwitcher } from './components/WorkspaceSwitcher';
35
22
  export { SecretModal, ImpactConfirmation } from './components/SecretModal';
36
23
  export { cn, statusTone, statusLabel, STATUS_TONE_CLASS, STATUS_LABEL, formatDate, formatDateTime, shortID } from './lib/utils';
37
24
  export type { StatusTone } from './lib/utils';
38
- export { roleSatisfies } from './lib/perm';
39
- export type { Perm } from './lib/perm';
40
- export { usePasswordReset } from './hooks/usePasswordReset';
41
25
  export { ForgotPasswordPage } from './pages/auth/ForgotPasswordPage';
42
26
  export type { ForgotPasswordPageProps } from './pages/auth/ForgotPasswordPage';
43
27
  export { ResetPasswordPage } from './pages/auth/ResetPasswordPage';
@@ -46,8 +30,6 @@ export { VerifyEmailPage } from './pages/auth/VerifyEmailPage';
46
30
  export { ErrorBoundary } from './components/ErrorBoundary';
47
31
  export type { ErrorBoundaryProps } from './components/ErrorBoundary';
48
32
  export { toast, Toaster } from './components/toast';
49
- export { useZodForm } from './hooks/useZodForm';
50
- export type { ZodFormOptions } from './hooks/useZodForm';
51
33
  export { FormField } from './components/FormField';
52
34
  export type { FormFieldProps } from './components/FormField';
53
35
  export { DataTable } from './components/DataTable';
@@ -57,7 +39,7 @@ export { Label } from './components/ui/label';
57
39
  export { Tabs, TabsList, TabsTrigger, TabsContent } from './components/ui/tabs';
58
40
  export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, } from './components/ui/alert-dialog';
59
41
  export { Avatar, AvatarImage, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarBadge, } from './components/ui/avatar';
60
- export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, } from './components/ui/menu';
42
+ export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, } from './components/ui/dropdown-menu';
61
43
  export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, } from './components/ui/select';
62
44
  export { Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, } from './components/ui/popover';
63
45
  export { Switch } from './components/ui/switch';
@@ -65,7 +47,7 @@ export { Progress, ProgressTrack, ProgressIndicator, ProgressLabel, ProgressValu
65
47
  export { Checkbox } from './components/ui/checkbox';
66
48
  export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, } from './components/ui/card';
67
49
  export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis, } from './components/ui/breadcrumb';
68
- export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia, EmptyFooter, } from './components/ui/empty';
50
+ export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia, } from './components/ui/empty';
69
51
  export { SettingsShell } from './layouts/SettingsShell';
70
52
  export type { SettingsNavItem, SettingsNavGroup, SettingsShellProps } from './layouts/SettingsShell';
71
53
  export { AuthShell } from './layouts/AuthShell';
@@ -84,32 +66,20 @@ export { TokensPage } from './pages/account/TokensPage';
84
66
  export { NotificationPreferencesPage } from './pages/account/NotificationPreferencesPage';
85
67
  export type { NotificationPreferencesPageProps, NotificationTypeMeta } from './pages/account/NotificationPreferencesPage';
86
68
  export { MembersPage } from './pages/workspace/MembersPage';
69
+ export { RolePermissionsPage } from './pages/workspace/RolePermissionsPage';
70
+ export { ReauthDialog } from './components/ReauthDialog';
87
71
  export { WorkspaceGeneralPage } from './pages/workspace/WorkspaceGeneralPage';
88
72
  export { WorkspaceAuditPage } from './pages/workspace/WorkspaceAuditPage';
89
73
  export { UsagePage } from './pages/workspace/UsagePage';
90
74
  export { BillingPage } from './pages/workspace/BillingPage';
91
75
  export { BillingSuccessPage } from './pages/workspace/BillingSuccessPage';
92
76
  export { WebhooksPage } from './pages/workspace/WebhooksPage';
93
- export { useSessions, useRevokeSession, useRevokeAllSessions } from './hooks/useSessions';
94
- export type { SessionInfo } from './hooks/useSessions';
95
- export { useTokens, useCreateToken, useRevokeToken } from './hooks/useTokens';
96
- export type { PAT, CreatePATResult } from './hooks/useTokens';
97
- export { useNotificationPrefs, useSetNotificationPref } from './hooks/useNotificationPrefs';
98
- export type { NotificationPreference } from './hooks/useNotificationPrefs';
99
- export { useMembers, useMemberMutations, useMyInvitations, ASSIGNABLE_ROLES } from './hooks/useMembers';
100
- export type { PKMember, PKInvitation, PKShareLink, PKInvitationWithWorkspace, CreateShareLinkResult, } from './hooks/useMembers';
101
- export { useAudit, exportAuditCsv, auditQueryString, EMPTY_AUDIT_FILTERS } from './hooks/useAudit';
102
- export type { AuditFilters, PKAuditEvent } from './hooks/useAudit';
103
- export { useUsage } from './hooks/useUsage';
104
- export type { PKUsageResp, PKUsageItem } from './hooks/useUsage';
105
77
  export { apiErrorMessage } from './lib/api-error';
106
78
  export { CronInput } from './components/CronInput';
107
79
  export { SchedulesPage } from './pages/workspace/SchedulesPage';
108
80
  export { SiteBanner } from './components/SiteBanner';
109
81
  export { SiteBannerLayer } from './components/SiteBannerLayer';
110
82
  export type { SiteBannerLayerProps } from './components/SiteBannerLayer';
111
- export { useSiteConfig, SITE_CONFIG_QUERY_KEY } from './hooks/useSiteConfig';
112
- export type { SiteConfig } from './hooks/useSiteConfig';
113
83
  export { ImpersonationBanner } from './components/ImpersonationBanner';
114
84
  export { AdminShell } from './pages/admin/AdminShell';
115
85
  export { OverviewPage } from './pages/admin/OverviewPage';
package/dist/index.js CHANGED
@@ -1,24 +1,16 @@
1
- export { PloykitProvider, queryKeys } from './provider/PloykitProvider';
2
- export { useAuth } from './hooks/useAuth';
3
- export { useLogin } from './hooks/useLogin';
4
- export { useWorkspace, useWorkspaceSwitch } from './hooks/useWorkspace';
5
- export { useBilling, useUsagePreview, PlanGate } from './hooks/useBilling';
6
- export { useApi, ApiError } from './hooks/useApi';
7
- export { useSEO } from './hooks/useSEO';
8
- export { useWsStatus, useWsScope, useWsFrame } from './hooks/ws';
9
- export { createWsClient, defaultWsUrl } from './realtime';
10
- export { bridgeWsToQuery } from './lib/ws-query-bridge';
11
1
  export { AppShell } from './layouts/AppShell';
12
2
  export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger, } from './components/ui/sidebar';
13
3
  export { Separator } from './components/ui/separator';
14
4
  export { Skeleton } from './components/ui/skeleton';
15
5
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from './components/ui/tooltip';
16
- export { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from './components/ui/sheet';
6
+ export { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetTrigger, SheetClose } from './components/ui/sheet';
7
+ export { AppProviders } from './AppProviders';
17
8
  export { LoginPage } from './pages/LoginPage';
18
9
  export { LandingPage } from './pages/LandingPage';
19
- export { Button, buttonVariants } from './components/ui/Button';
20
- export { Input } from './components/ui/Input';
21
- export { Badge, badgeVariants, StatusBadge } from './components/ui/Badge';
10
+ export { Button, buttonVariants } from './components/ui/button';
11
+ export { Input } from './components/ui/input';
12
+ export { Textarea } from './components/ui/textarea';
13
+ export { StatusBadge } from './components/StatusBadge';
22
14
  export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, } from './components/ui/dialog';
23
15
  export { PageHeader, PageLoading, PageEmpty, PageError } from './components/Page';
24
16
  export { ConfirmProvider, useConfirm } from './components/ConfirmDialog';
@@ -26,14 +18,11 @@ export { NotificationBell } from './components/NotificationBell';
26
18
  export { WorkspaceSwitcher } from './components/WorkspaceSwitcher';
27
19
  export { SecretModal, ImpactConfirmation } from './components/SecretModal';
28
20
  export { cn, statusTone, statusLabel, STATUS_TONE_CLASS, STATUS_LABEL, formatDate, formatDateTime, shortID } from './lib/utils';
29
- export { roleSatisfies } from './lib/perm';
30
- export { usePasswordReset } from './hooks/usePasswordReset';
31
21
  export { ForgotPasswordPage } from './pages/auth/ForgotPasswordPage';
32
22
  export { ResetPasswordPage } from './pages/auth/ResetPasswordPage';
33
23
  export { VerifyEmailPage } from './pages/auth/VerifyEmailPage';
34
24
  export { ErrorBoundary } from './components/ErrorBoundary';
35
25
  export { toast, Toaster } from './components/toast';
36
- export { useZodForm } from './hooks/useZodForm';
37
26
  export { FormField } from './components/FormField';
38
27
  export { DataTable } from './components/DataTable';
39
28
  export { Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSeparator, FieldSet, FieldContent, FieldTitle, } from './components/ui/field';
@@ -41,7 +30,7 @@ export { Label } from './components/ui/label';
41
30
  export { Tabs, TabsList, TabsTrigger, TabsContent } from './components/ui/tabs';
42
31
  export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, } from './components/ui/alert-dialog';
43
32
  export { Avatar, AvatarImage, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarBadge, } from './components/ui/avatar';
44
- export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, } from './components/ui/menu';
33
+ export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, } from './components/ui/dropdown-menu';
45
34
  export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, } from './components/ui/select';
46
35
  export { Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, } from './components/ui/popover';
47
36
  export { Switch } from './components/ui/switch';
@@ -49,7 +38,7 @@ export { Progress, ProgressTrack, ProgressIndicator, ProgressLabel, ProgressValu
49
38
  export { Checkbox } from './components/ui/checkbox';
50
39
  export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, } from './components/ui/card';
51
40
  export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis, } from './components/ui/breadcrumb';
52
- export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia, EmptyFooter, } from './components/ui/empty';
41
+ export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia, } from './components/ui/empty';
53
42
  export { SettingsShell } from './layouts/SettingsShell';
54
43
  export { AuthShell } from './layouts/AuthShell';
55
44
  export { SettingsCard } from './components/SettingsCard';
@@ -62,24 +51,19 @@ export { SecuritySettingsPage } from './pages/account/SecuritySettingsPage';
62
51
  export { TokensPage } from './pages/account/TokensPage';
63
52
  export { NotificationPreferencesPage } from './pages/account/NotificationPreferencesPage';
64
53
  export { MembersPage } from './pages/workspace/MembersPage';
54
+ export { RolePermissionsPage } from './pages/workspace/RolePermissionsPage';
55
+ export { ReauthDialog } from './components/ReauthDialog';
65
56
  export { WorkspaceGeneralPage } from './pages/workspace/WorkspaceGeneralPage';
66
57
  export { WorkspaceAuditPage } from './pages/workspace/WorkspaceAuditPage';
67
58
  export { UsagePage } from './pages/workspace/UsagePage';
68
59
  export { BillingPage } from './pages/workspace/BillingPage';
69
60
  export { BillingSuccessPage } from './pages/workspace/BillingSuccessPage';
70
61
  export { WebhooksPage } from './pages/workspace/WebhooksPage';
71
- export { useSessions, useRevokeSession, useRevokeAllSessions } from './hooks/useSessions';
72
- export { useTokens, useCreateToken, useRevokeToken } from './hooks/useTokens';
73
- export { useNotificationPrefs, useSetNotificationPref } from './hooks/useNotificationPrefs';
74
- export { useMembers, useMemberMutations, useMyInvitations, ASSIGNABLE_ROLES } from './hooks/useMembers';
75
- export { useAudit, exportAuditCsv, auditQueryString, EMPTY_AUDIT_FILTERS } from './hooks/useAudit';
76
- export { useUsage } from './hooks/useUsage';
77
62
  export { apiErrorMessage } from './lib/api-error';
78
63
  export { CronInput } from './components/CronInput';
79
64
  export { SchedulesPage } from './pages/workspace/SchedulesPage';
80
65
  export { SiteBanner } from './components/SiteBanner';
81
66
  export { SiteBannerLayer } from './components/SiteBannerLayer';
82
- export { useSiteConfig, SITE_CONFIG_QUERY_KEY } from './hooks/useSiteConfig';
83
67
  export { ImpersonationBanner } from './components/ImpersonationBanner';
84
68
  export { AdminShell } from './pages/admin/AdminShell';
85
69
  export { OverviewPage } from './pages/admin/OverviewPage';
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import { type ReactNode } from 'react';
2
2
  export interface NavItem {
3
3
  path: string;
4
4
  label: string;
@@ -1,20 +1,42 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useLocation, useNavigate } from 'react-router';
3
+ import { useEffect } from 'react';
3
4
  import { FolderKanban } from 'lucide-react';
4
5
  import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger, } from '../components/ui/sidebar';
5
6
  import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbPage, BreadcrumbSeparator, } from '../components/ui/breadcrumb';
6
7
  import { UserMenu } from '../components/UserMenu';
7
8
  import { ImpersonationBanner } from '../components/ImpersonationBanner';
9
+ // stock SidebarProvider 只写不读 sidebar_state cookie(写入供 SSR 框架回传 defaultOpen)。
10
+ // CSR 产品在组合层回读,保持跨会话折叠状态(P2-17,自 stock 镜像化后上提至此)。
11
+ function readSidebarCookieOpen() {
12
+ if (typeof document === 'undefined')
13
+ return true; // SSR 安全
14
+ return !document.cookie.split('; ').includes('sidebar_state=false');
15
+ }
8
16
  export function AppShell({ children, nav, brand, logo, logoDark, sidebarFooter, headerRight, breadcrumbTail = null, settingsContent }) {
9
17
  const location = useLocation();
10
18
  const navigate = useNavigate();
19
+ // 输入焦点时不劫持 Ctrl/Cmd+B(P3-1,自 stock 镜像化后上提至此):
20
+ // 捕获阶段拦截可编辑目标上的快捷键,阻断 stock SidebarProvider 的全局监听。
21
+ useEffect(() => {
22
+ const guard = (e) => {
23
+ if (!(e.ctrlKey || e.metaKey) || e.key.toLowerCase() !== 'b')
24
+ return;
25
+ const t = e.target;
26
+ if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) {
27
+ e.stopImmediatePropagation();
28
+ }
29
+ };
30
+ window.addEventListener('keydown', guard, true);
31
+ return () => window.removeEventListener('keydown', guard, true);
32
+ }, []);
11
33
  const items = nav ?? [
12
34
  { path: '/app', label: '概览', icon: _jsx(FolderKanban, { size: 17, "aria-hidden": "true" }) },
13
35
  ];
14
36
  const selected = items.find((item) => location.pathname.startsWith(item.path));
15
37
  const isSettingsMode = settingsContent !== undefined &&
16
38
  (location.pathname.startsWith('/settings') || location.pathname.startsWith('/account'));
17
- return (_jsxs(SidebarProvider, { children: [_jsxs(Sidebar, { collapsible: "icon", children: [_jsx(SidebarHeader, { children: _jsxs("div", { className: "flex items-center gap-2 px-2 pb-1 pt-1 group-data-[collapsible=icon]:justify-center", children: [logo && (_jsxs("picture", { children: [_jsx("source", { media: "(prefers-color-scheme: dark)", srcSet: logoDark ?? logo }), _jsx("img", { src: logo, alt: `${brand ?? 'App'} logo`, className: "h-7 w-auto group-data-[collapsible=icon]:w-7 group-data-[collapsible=icon]:object-contain" })] })), _jsx("div", { className: "text-lg font-bold text-foreground group-data-[collapsible=icon]:hidden", children: brand ?? 'App' })] }) }), _jsx(SidebarContent, { children: isSettingsMode ? (settingsContent) : (_jsx(SidebarGroup, { children: _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: items.map((item) => {
39
+ return (_jsxs(SidebarProvider, { defaultOpen: readSidebarCookieOpen(), children: [_jsxs(Sidebar, { collapsible: "icon", children: [_jsx(SidebarHeader, { children: _jsxs("div", { className: "flex items-center gap-2 px-2 pb-1 pt-1 group-data-[collapsible=icon]:justify-center", children: [logo && (_jsxs("picture", { children: [_jsx("source", { media: "(prefers-color-scheme: dark)", srcSet: logoDark ?? logo }), _jsx("img", { src: logo, alt: `${brand ?? 'App'} logo`, className: "h-7 w-auto group-data-[collapsible=icon]:w-7 group-data-[collapsible=icon]:object-contain" })] })), _jsx("div", { className: "text-lg font-bold text-foreground group-data-[collapsible=icon]:hidden", children: brand ?? 'App' })] }) }), _jsx(SidebarContent, { children: isSettingsMode ? (settingsContent) : (_jsx(SidebarGroup, { children: _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: items.map((item) => {
18
40
  const active = selected?.path === item.path;
19
41
  return (_jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { isActive: active, "aria-current": active ? 'page' : undefined, tooltip: item.label, onClick: () => navigate(item.path), children: [item.icon, _jsx("span", { className: "truncate", children: item.label })] }) }, item.path));
20
42
  }) }) }) })) }), _jsx(SidebarFooter, { className: "group-data-[collapsible=icon]:hidden", children: sidebarFooter })] }), _jsxs(SidebarInset, { children: [_jsx(ImpersonationBanner, {}), _jsxs("header", { className: "flex h-14 shrink-0 items-center gap-3 border-b border-border bg-background px-4", children: [_jsx(SidebarTrigger, {}), breadcrumbTail !== null ? (_jsx(Breadcrumb, { children: _jsxs(BreadcrumbList, { children: [selected && (_jsxs(_Fragment, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: selected.label }) }), _jsx(BreadcrumbSeparator, {})] })), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: breadcrumbTail }) })] }) })) : null, _jsx("div", { className: "flex-1" }), headerRight, _jsx(UserMenu, {})] }), _jsx("div", { className: "flex-1 overflow-auto p-6", children: children })] })] }));
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import { type Perm } from '../lib/perm';
2
+ import { type Perm } from '@ploykit/hooks';
3
3
  export interface SettingsNavItem {
4
4
  path: string;
5
5
  label: string;
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Link, useLocation, useNavigate } from 'react-router';
3
3
  import { cn } from '../lib/utils';
4
- import { roleSatisfies } from '../lib/perm';
5
- import { useWorkspace } from '../hooks/useWorkspace';
6
- import { buttonVariants } from '../components/ui/Button';
4
+ import { roleSatisfies } from '@ploykit/hooks';
5
+ import { useWorkspace } from '@ploykit/hooks';
6
+ import { buttonVariants } from '../components/ui/button';
7
7
  import { Separator } from '../components/ui/separator';
8
8
  import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, } from '../components/ui/select';
9
9
  export function SettingsShell({ nav, children, title = '设置', description }) {
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Link } from 'react-router';
3
3
  export function LandingPage({ brand, tagline, description, features, plans, registerPath = '/register', loginPath = '/login' }) {
4
- return (_jsxs("div", { className: "min-h-screen bg-white", children: [_jsx("header", { className: "border-b border-gray-100", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4 h-16 flex items-center justify-between", children: [_jsx("span", { className: "text-xl font-bold text-gray-900", children: brand }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Link, { to: loginPath, className: "px-4 py-2 text-sm font-medium text-gray-700 rounded-lg hover:bg-gray-50", children: "\u767B\u5F55" }), _jsx(Link, { to: registerPath, className: "px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700", children: "\u514D\u8D39\u6CE8\u518C" })] })] }) }), _jsxs("section", { className: "max-w-6xl mx-auto px-4 pt-20 pb-16 text-center", children: [_jsx("h1", { className: "text-5xl font-bold text-gray-900 tracking-tight", children: tagline }), _jsx("p", { className: "mt-4 text-xl text-gray-500 max-w-2xl mx-auto", children: description }), _jsx(Link, { to: registerPath, className: "mt-8 inline-block px-6 py-3 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 text-lg", children: "\u514D\u8D39\u5F00\u59CB" })] }), _jsx("section", { className: "bg-gray-50 py-16", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [_jsx("h2", { className: "text-3xl font-bold text-center text-gray-900 mb-12", children: "\u6838\u5FC3\u529F\u80FD" }), _jsx("div", { className: "grid md:grid-cols-3 gap-8", children: features.map((f, i) => (_jsxs("div", { className: "p-6 bg-white rounded-xl border border-gray-200", children: [_jsx("div", { className: "text-3xl mb-3", children: f.icon }), _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: f.title }), _jsx("p", { className: "mt-2 text-sm text-gray-500 leading-relaxed", children: f.desc })] }, `${i}-${f.title}`))) })] }) }), _jsx("section", { className: "py-16", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [_jsx("h2", { className: "text-3xl font-bold text-center text-gray-900 mb-12", children: "\u5B9A\u4EF7" }), _jsx("div", { className: "grid md:grid-cols-2 gap-8 max-w-3xl mx-auto", children: plans.map((p, i) => (_jsxs("div", { className: `p-8 bg-white rounded-xl ${p.recommended ? 'border-2 border-blue-600 relative' : 'border border-gray-200'}`, children: [p.recommended && (_jsx("span", { className: "absolute -top-3 left-1/2 -translate-x-1/2 px-3 py-1 bg-blue-600 text-white text-xs font-medium rounded-full", children: "\u63A8\u8350" })), _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: p.name }), _jsxs("p", { className: "mt-1 text-3xl font-bold text-gray-900", children: [p.price, _jsx("span", { className: "text-sm text-gray-400", children: p.period ?? '/月' })] }), _jsx("ul", { className: "mt-6 space-y-3 text-sm text-gray-600", children: p.features.map((f, j) => _jsxs("li", { children: ["\u2713 ", f] }, `${j}-${f}`)) }), _jsx(Link, { to: registerPath, className: `mt-6 block text-center py-2.5 rounded-lg font-medium ${p.recommended ? 'bg-blue-600 text-white hover:bg-blue-700' : 'border border-gray-300 text-gray-700 hover:bg-gray-50'}`, children: p.cta })] }, `${i}-${p.name}`))) })] }) }), _jsxs("footer", { className: "border-t border-gray-100 py-8 text-center text-sm text-gray-400", children: ["\u00A9 2026 ", brand, ". All rights reserved."] })] }));
4
+ return (_jsxs("div", { className: "min-h-screen bg-card", children: [_jsx("header", { className: "border-b border-border", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4 h-16 flex items-center justify-between", children: [_jsx("span", { className: "text-xl font-bold text-foreground", children: brand }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Link, { to: loginPath, className: "px-4 py-2 text-sm font-medium text-foreground rounded-lg hover:bg-muted", children: "\u767B\u5F55" }), _jsx(Link, { to: registerPath, className: "px-4 py-2 bg-primary text-primary-foreground text-sm font-medium rounded-lg hover:bg-primary/80", children: "\u514D\u8D39\u6CE8\u518C" })] })] }) }), _jsxs("section", { className: "max-w-6xl mx-auto px-4 pt-20 pb-16 text-center", children: [_jsx("h1", { className: "text-5xl font-bold text-foreground tracking-tight", children: tagline }), _jsx("p", { className: "mt-4 text-xl text-muted-foreground max-w-2xl mx-auto", children: description }), _jsx(Link, { to: registerPath, className: "mt-8 inline-block px-6 py-3 bg-primary text-primary-foreground font-medium rounded-lg hover:bg-primary/80 text-lg", children: "\u514D\u8D39\u5F00\u59CB" })] }), _jsx("section", { className: "bg-muted py-16", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [_jsx("h2", { className: "text-3xl font-bold text-center text-foreground mb-12", children: "\u6838\u5FC3\u529F\u80FD" }), _jsx("div", { className: "grid md:grid-cols-3 gap-8", children: features.map((f, i) => (_jsxs("div", { className: "p-6 bg-card rounded-xl border border-border", children: [_jsx("div", { className: "text-3xl mb-3", children: f.icon }), _jsx("h3", { className: "text-lg font-semibold text-foreground", children: f.title }), _jsx("p", { className: "mt-2 text-sm text-muted-foreground leading-relaxed", children: f.desc })] }, `${i}-${f.title}`))) })] }) }), _jsx("section", { className: "py-16", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [_jsx("h2", { className: "text-3xl font-bold text-center text-foreground mb-12", children: "\u5B9A\u4EF7" }), _jsx("div", { className: "grid md:grid-cols-2 gap-8 max-w-3xl mx-auto", children: plans.map((p, i) => (_jsxs("div", { className: `p-8 bg-card rounded-xl ${p.recommended ? 'border-2 border-primary relative' : 'border border-border'}`, children: [p.recommended && (_jsx("span", { className: "absolute -top-3 left-1/2 -translate-x-1/2 px-3 py-1 bg-primary text-primary-foreground text-xs font-medium rounded-full", children: "\u63A8\u8350" })), _jsx("h3", { className: "text-lg font-semibold text-foreground", children: p.name }), _jsxs("p", { className: "mt-1 text-3xl font-bold text-foreground", children: [p.price, _jsx("span", { className: "text-sm text-muted-foreground", children: p.period ?? '/月' })] }), _jsx("ul", { className: "mt-6 space-y-3 text-sm text-muted-foreground", children: p.features.map((f, j) => _jsxs("li", { children: ["\u2713 ", f] }, `${j}-${f}`)) }), _jsx(Link, { to: registerPath, className: `mt-6 block text-center py-2.5 rounded-lg font-medium ${p.recommended ? 'bg-primary text-primary-foreground hover:bg-primary/80' : 'border border-input text-foreground hover:bg-muted'}`, children: p.cta })] }, `${i}-${p.name}`))) })] }) }), _jsxs("footer", { className: "border-t border-border py-8 text-center text-sm text-muted-foreground", children: ["\u00A9 2026 ", brand, ". All rights reserved."] })] }));
5
5
  }
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
3
  import { useLocation } from 'react-router';
4
- import { useLogin } from '../hooks/useLogin';
5
- import { useApi } from '../hooks/useApi';
6
- import { useAuth } from '../hooks/useAuth';
4
+ import { useLogin } from '@ploykit/hooks';
5
+ import { useApi } from '@ploykit/hooks';
6
+ import { useAuth } from '@ploykit/hooks';
7
7
  import { Tabs, TabsList, TabsTrigger, TabsContent } from '../components/ui/tabs';
8
- import { Button } from '../components/ui/Button';
9
- import { Input } from '../components/ui/Input';
8
+ import { Button } from '../components/ui/button';
9
+ import { Input } from '../components/ui/input';
10
10
  import { FormField } from '../components/FormField';
11
11
  import { apiErrorMessage } from '../lib/api-error';
12
12
  const SEND_COOLDOWN_S = 60;
@@ -77,11 +77,11 @@ export function LoginPage({ resetPath = '/forgot-password', registerPath = '/reg
77
77
  setPwLoading(false);
78
78
  }
79
79
  };
80
- return (_jsx("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: _jsxs("div", { className: "w-full max-w-sm space-y-4 p-8 bg-white rounded-lg shadow", children: [_jsxs("div", { className: "text-center", children: [_jsx("h1", { className: "text-2xl font-bold", children: title }), _jsx("p", { className: "mt-1 text-sm text-gray-500", children: description })] }), _jsxs(Tabs, { defaultValue: "code", children: [_jsxs(TabsList, { className: "w-full", children: [_jsx(TabsTrigger, { value: "code", children: "\u9A8C\u8BC1\u7801\u767B\u5F55" }), _jsx(TabsTrigger, { value: "password", children: "\u5BC6\u7801\u767B\u5F55" })] }), _jsx(TabsContent, { value: "code", children: _jsxs("form", { onSubmit: handleCodeSubmit, className: "space-y-4 pt-2", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "login-email", className: "text-sm text-gray-600", children: "\u90AE\u7BB1" }), _jsx("input", { id: "login-email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "you@example.com", required: true, autoComplete: "email", className: "w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "login-code", className: "text-sm text-gray-600", children: "\u9A8C\u8BC1\u7801" }), _jsxs("div", { className: "flex gap-2", children: [_jsx("input", { id: "login-code", type: "text", value: code, onChange: (e) => setCode(e.target.value), placeholder: "6\u4F4D\u6570\u5B57", maxLength: 6, required: true, autoComplete: "one-time-code", className: "flex-1 px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" }), _jsx("button", { type: "button", onClick: handleSendCode, disabled: sending || cooldown > 0 || !email, className: "px-4 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50 disabled:opacity-50", children: cooldown > 0
80
+ return (_jsx("div", { className: "min-h-screen flex items-center justify-center bg-background", children: _jsxs("div", { className: "w-full max-w-sm space-y-4 p-8 bg-white rounded-lg shadow", children: [_jsxs("div", { className: "text-center", children: [_jsx("h1", { className: "text-2xl font-bold", children: title }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: description })] }), _jsxs(Tabs, { defaultValue: "code", children: [_jsxs(TabsList, { className: "w-full", children: [_jsx(TabsTrigger, { value: "code", children: "\u9A8C\u8BC1\u7801\u767B\u5F55" }), _jsx(TabsTrigger, { value: "password", children: "\u5BC6\u7801\u767B\u5F55" })] }), _jsx(TabsContent, { value: "code", children: _jsxs("form", { onSubmit: handleCodeSubmit, className: "space-y-4 pt-2", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "login-email", className: "text-sm text-foreground", children: "\u90AE\u7BB1" }), _jsx("input", { id: "login-email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "you@example.com", required: true, autoComplete: "email", className: "w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-ring" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "login-code", className: "text-sm text-foreground", children: "\u9A8C\u8BC1\u7801" }), _jsxs("div", { className: "flex gap-2", children: [_jsx("input", { id: "login-code", type: "text", value: code, onChange: (e) => setCode(e.target.value), placeholder: "6\u4F4D\u6570\u5B57", maxLength: 6, required: true, autoComplete: "one-time-code", className: "flex-1 px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-ring" }), _jsx("button", { type: "button", onClick: handleSendCode, disabled: sending || cooldown > 0 || !email, className: "px-4 py-2 text-sm text-primary border border-primary/30 rounded-md hover:bg-primary/10 disabled:opacity-50", children: cooldown > 0
81
81
  ? `重发(${cooldown}s)`
82
82
  : codeSent
83
83
  ? '重新发送'
84
84
  : sending
85
85
  ? '发送中…'
86
- : '发送' })] })] }), sendError && _jsx("p", { role: "alert", className: "text-red-500 text-sm", children: sendError }), codeError && _jsx("p", { role: "alert", className: "text-red-500 text-sm", children: codeError }), _jsx("button", { type: "submit", disabled: loading || !email || !code, className: "w-full py-2 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50", children: loading ? '登录中…' : '登录' })] }) }), _jsx(TabsContent, { value: "password", children: _jsxs("form", { onSubmit: handlePasswordSubmit, className: "space-y-4 pt-2", children: [_jsx(FormField, { label: "\u90AE\u7BB1", htmlFor: "login-pw-email", children: _jsx(Input, { id: "login-pw-email", type: "email", value: email, required: true, onChange: (e) => setEmail(e.target.value), placeholder: "you@example.com", autoComplete: "email" }) }), _jsx(FormField, { label: "\u5BC6\u7801", htmlFor: "login-pw-password", children: _jsx(Input, { id: "login-pw-password", type: "password", value: password, required: true, onChange: (e) => setPassword(e.target.value), placeholder: "\u8F93\u5165\u5BC6\u7801", autoComplete: "current-password" }) }), pwError && _jsx("p", { role: "alert", className: "text-red-500 text-sm", children: pwError }), _jsx(Button, { type: "submit", className: "w-full", disabled: pwLoading || !email || !password, children: pwLoading ? '登录中…' : '登录' })] }) })] }), oauthProviders.length > 0 && (_jsxs("div", { className: "space-y-2 pt-1", "data-testid": "oauth-providers", children: [_jsxs("div", { className: "relative py-2 text-center", children: [_jsx("span", { className: "absolute inset-x-0 top-1/2 border-t border-gray-200" }), _jsx("span", { className: "relative z-10 bg-white px-2 text-xs text-gray-400", children: "\u6216\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u767B\u5F55" })] }), oauthProviders.map((p) => (_jsxs("a", { href: '/auth/oauth/' + p.id + '/start', className: "block w-full py-2 px-4 text-center text-sm border border-gray-300 rounded-md hover:bg-gray-50", children: ["\u4F7F\u7528 ", p.label, " \u767B\u5F55"] }, p.id)))] })), enableFedLogin && (_jsxs("details", { className: "pt-1", "data-testid": "fed-login", children: [_jsx("summary", { className: "text-sm text-gray-500 cursor-pointer select-none", children: "\u4F01\u4E1A\u767B\u5F55" }), _jsxs("form", { method: "get", action: "/auth/fed/start", className: "mt-2 space-y-2", children: [_jsx("input", { type: "text", name: "workspace", placeholder: "\u5DE5\u4F5C\u533A\u6807\u8BC6\uFF08slug\uFF09", required: true, className: "w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" }), _jsx("button", { type: "submit", className: "w-full py-2 px-4 bg-gray-800 text-white text-sm rounded-md hover:bg-gray-900", children: "\u901A\u8FC7\u4F01\u4E1A IdP \u767B\u5F55" })] })] })), _jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("a", { href: resetPath, className: "text-blue-600 hover:underline", children: "\u5FD8\u8BB0\u5BC6\u7801\uFF1F" }), registerPath && (_jsx("a", { href: registerPath, "data-testid": "register-link", className: "text-blue-600 hover:underline", children: "\u521B\u5EFA\u8D26\u53F7" }))] })] }) }));
86
+ : '发送' })] })] }), sendError && _jsx("p", { role: "alert", className: "text-destructive text-sm", children: sendError }), codeError && _jsx("p", { role: "alert", className: "text-destructive text-sm", children: codeError }), _jsx("button", { type: "submit", disabled: loading || !email || !code, className: "w-full py-2 px-4 bg-primary text-primary-foreground rounded-md hover:bg-primary/80 disabled:opacity-50", children: loading ? '登录中…' : '登录' })] }) }), _jsx(TabsContent, { value: "password", children: _jsxs("form", { onSubmit: handlePasswordSubmit, className: "space-y-4 pt-2", children: [_jsx(FormField, { label: "\u90AE\u7BB1", htmlFor: "login-pw-email", children: _jsx(Input, { id: "login-pw-email", type: "email", value: email, required: true, onChange: (e) => setEmail(e.target.value), placeholder: "you@example.com", autoComplete: "email" }) }), _jsx(FormField, { label: "\u5BC6\u7801", htmlFor: "login-pw-password", children: _jsx(Input, { id: "login-pw-password", type: "password", value: password, required: true, onChange: (e) => setPassword(e.target.value), placeholder: "\u8F93\u5165\u5BC6\u7801", autoComplete: "current-password" }) }), pwError && _jsx("p", { role: "alert", className: "text-destructive text-sm", children: pwError }), _jsx(Button, { type: "submit", className: "w-full", disabled: pwLoading || !email || !password, children: pwLoading ? '登录中…' : '登录' })] }) })] }), oauthProviders.length > 0 && (_jsxs("div", { className: "space-y-2 pt-1", "data-testid": "oauth-providers", children: [_jsxs("div", { className: "relative py-2 text-center", children: [_jsx("span", { className: "absolute inset-x-0 top-1/2 border-t border-border" }), _jsx("span", { className: "relative z-10 bg-card px-2 text-xs text-muted-foreground", children: "\u6216\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u767B\u5F55" })] }), oauthProviders.map((p) => (_jsxs("a", { href: '/auth/oauth/' + p.id + '/start', className: "block w-full py-2 px-4 text-center text-sm border border-input rounded-md hover:bg-background", children: ["\u4F7F\u7528 ", p.label, " \u767B\u5F55"] }, p.id)))] })), enableFedLogin && (_jsxs("details", { className: "pt-1", "data-testid": "fed-login", children: [_jsx("summary", { className: "text-sm text-muted-foreground cursor-pointer select-none", children: "\u4F01\u4E1A\u767B\u5F55" }), _jsxs("form", { method: "get", action: "/auth/fed/start", className: "mt-2 space-y-2", children: [_jsx("input", { type: "text", name: "workspace", placeholder: "\u5DE5\u4F5C\u533A\u6807\u8BC6\uFF08slug\uFF09", required: true, className: "w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-ring" }), _jsx("button", { type: "submit", className: "w-full py-2 px-4 bg-primary text-primary-foreground text-sm rounded-md hover:bg-primary/80", children: "\u901A\u8FC7\u4F01\u4E1A IdP \u767B\u5F55" })] })] })), _jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("a", { href: resetPath, className: "text-primary hover:underline", children: "\u5FD8\u8BB0\u5BC6\u7801\uFF1F" }), registerPath && (_jsx("a", { href: registerPath, "data-testid": "register-link", className: "text-primary hover:underline", children: "\u521B\u5EFA\u8D26\u53F7" }))] })] }) }));
87
87
  }
@@ -3,8 +3,8 @@ import { useId } from 'react';
3
3
  import { PageHeader, PageLoading, PageError, PageEmpty } from '../../components/Page';
4
4
  import { Switch } from '../../components/ui/switch';
5
5
  import { toast } from '../../components/toast';
6
- import { useSEO } from '../../hooks/useSEO';
7
- import { useNotificationPrefs, useSetNotificationPref, } from '../../hooks/useNotificationPrefs';
6
+ import { useSEO } from '@ploykit/hooks';
7
+ import { useNotificationPrefs, useSetNotificationPref, } from '@ploykit/hooks';
8
8
  export function NotificationPreferencesPage({ types, title = '通知偏好', description = '选择每种通知的接收渠道;未显示的类型默认全部开启', siteName, emailChannelNote, }) {
9
9
  const { prefs, loading, error, refetch } = useNotificationPrefs();
10
10
  const { setPref } = useSetNotificationPref();
@@ -4,15 +4,15 @@ import { z } from 'zod';
4
4
  import { PageHeader, PageLoading, PageError } from '../../components/Page';
5
5
  import { SettingsCard } from '../../components/SettingsCard';
6
6
  import { FormField } from '../../components/FormField';
7
- import { Button } from '../../components/ui/Button';
8
- import { Input } from '../../components/ui/Input';
9
- import { Badge } from '../../components/ui/Badge';
7
+ import { Button } from '../../components/ui/button';
8
+ import { Input } from '../../components/ui/input';
9
+ import { Badge } from '../../components/ui/badge';
10
10
  import { ImpactConfirmation } from '../../components/SecretModal';
11
11
  import { toast } from '../../components/toast';
12
12
  import { apiErrorMessage } from '../../lib/api-error';
13
- import { useApi } from '../../hooks/useApi';
14
- import { useAuth } from '../../hooks/useAuth';
15
- import { useZodForm } from '../../hooks/useZodForm';
13
+ import { useApi } from '@ploykit/hooks';
14
+ import { useAuth } from '@ploykit/hooks';
15
+ import { useZodForm } from '@ploykit/hooks';
16
16
  const profileSchema = z.object({
17
17
  display_name: z.string().trim().min(1, '请输入昵称').max(100, '昵称最多 100 字符'),
18
18
  avatar_url: z.string()
@@ -88,7 +88,7 @@ export function ProfileSettingsPage({ onDeleted }) {
88
88
  }
89
89
  };
90
90
  const emailReadyToDelete = confirmEmail.trim().toLowerCase() === user.email.toLowerCase();
91
- return (_jsxs("div", { children: [_jsx(PageHeader, { title: "\u4E2A\u4EBA\u8D44\u6599", description: "\u7BA1\u7406\u6635\u79F0\u3001\u5934\u50CF\u7B49\u8D26\u53F7\u8D44\u6599" }), _jsxs(SettingsCard, { title: "\u8D44\u6599", description: "\u5BF9\u5916\u5C55\u793A\u7684\u6635\u79F0\u4E0E\u5934\u50CF", cta: _jsx(Button, { type: "submit", form: "profile-form", disabled: saving, children: saving ? '保存中…' : '保存' }), children: [_jsxs("form", { id: "profile-form", onSubmit: handleSave, className: "max-w-xl space-y-4", children: [_jsx(FormField, { label: "\u6635\u79F0", required: true, error: form.formState.errors.display_name?.message, htmlFor: "profile-name", children: _jsx(Input, { id: "profile-name", maxLength: 100, placeholder: "\u600E\u4E48\u79F0\u547C\u4F60", ...form.register('display_name') }) }), _jsx(FormField, { label: "\u5934\u50CF\u94FE\u63A5", error: form.formState.errors.avatar_url?.message, htmlFor: "profile-avatar", description: "\u53EF\u9009\uFF1B\u9700 http(s):// \u5F00\u5934\u3001\u6700\u591A 2048 \u5B57\u7B26\u3002\u5916\u90E8\u56FE\u7247\u53EF\u80FD\u88AB\u5185\u5BB9\u5B89\u5168\u7B56\u7565\u62E6\u622A\uFF0C\u65E0\u6CD5\u52A0\u8F7D\u65F6\u663E\u793A\u9ED8\u8BA4\u5934\u50CF", children: _jsx(Input, { id: "profile-avatar", maxLength: 2048, placeholder: "https://\u2026\uFF08\u53EF\u9009\uFF09", ...form.register('avatar_url') }) })] }), _jsxs("div", { className: "mt-6 flex flex-row items-center justify-between gap-4 rounded-lg border p-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium", children: "\u767B\u5F55\u90AE\u7BB1" }), _jsx("p", { className: "mt-0.5 truncate text-sm text-muted-foreground", "data-testid": "profile-email", children: user.email }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "\u7528\u4E8E\u767B\u5F55\u4E0E\u63A5\u6536\u901A\u77E5\uFF0C\u6682\u4E0D\u652F\u6301\u81EA\u52A9\u4FEE\u6539" })] }), _jsx("div", { className: "flex shrink-0 items-center gap-2", children: user.email_verified ? (_jsx(Badge, { variant: "secondary", className: "bg-emerald-50 text-emerald-700 border-emerald-200", children: "\u5DF2\u9A8C\u8BC1" })) : (_jsxs(_Fragment, { children: [_jsx(Badge, { variant: "outline", className: "text-amber-700 border-amber-200 bg-amber-50", children: "\u672A\u9A8C\u8BC1" }), _jsx(Button, { variant: "outline", size: "sm", onClick: handleResend, disabled: sending, children: sending ? '发送中…' : '重新发送验证邮件' })] })) })] })] }), _jsx(SettingsCard, { danger: true, title: "\u5220\u9664\u8D26\u53F7", description: "\u6CE8\u9500\u540E\u8D26\u53F7\u8FDB\u5165\u5220\u9664\u72B6\u6001\uFF0C\u65E0\u6CD5\u6062\u590D", cta: _jsx(Button, { variant: "destructive", disabled: !emailReadyToDelete || deleting, onClick: () => setConfirmOpen(true), children: "\u5220\u9664\u8D26\u53F7" }), children: _jsx("div", { className: "max-w-xl space-y-4", children: _jsx(FormField, { label: "\u8F93\u5165\u767B\u5F55\u90AE\u7BB1\u4EE5\u786E\u8BA4", htmlFor: "profile-delete-email", children: _jsx(Input, { id: "profile-delete-email", placeholder: user.email, value: confirmEmail, onChange: (e) => setConfirmEmail(e.target.value) }) }) }) }), _jsx(ImpactConfirmation, { open: confirmOpen, onOpenChange: setConfirmOpen, onConfirm: handleDelete, title: "\u786E\u8BA4\u5220\u9664\u8D26\u53F7\uFF1F", confirmText: "\u6C38\u4E45\u5220\u9664", danger: true, impacts: [
91
+ return (_jsxs("div", { children: [_jsx(PageHeader, { title: "\u4E2A\u4EBA\u8D44\u6599", description: "\u7BA1\u7406\u6635\u79F0\u3001\u5934\u50CF\u7B49\u8D26\u53F7\u8D44\u6599" }), _jsxs(SettingsCard, { title: "\u8D44\u6599", description: "\u5BF9\u5916\u5C55\u793A\u7684\u6635\u79F0\u4E0E\u5934\u50CF", cta: _jsx(Button, { type: "submit", form: "profile-form", disabled: saving, children: saving ? '保存中…' : '保存' }), children: [_jsxs("form", { id: "profile-form", onSubmit: handleSave, className: "max-w-xl space-y-4", children: [_jsx(FormField, { label: "\u6635\u79F0", required: true, error: form.formState.errors.display_name?.message, htmlFor: "profile-name", children: _jsx(Input, { id: "profile-name", maxLength: 100, placeholder: "\u600E\u4E48\u79F0\u547C\u4F60", ...form.register('display_name') }) }), _jsx(FormField, { label: "\u5934\u50CF\u94FE\u63A5", error: form.formState.errors.avatar_url?.message, htmlFor: "profile-avatar", description: "\u53EF\u9009\uFF1B\u9700 http(s):// \u5F00\u5934\u3001\u6700\u591A 2048 \u5B57\u7B26\u3002\u5916\u90E8\u56FE\u7247\u53EF\u80FD\u88AB\u5185\u5BB9\u5B89\u5168\u7B56\u7565\u62E6\u622A\uFF0C\u65E0\u6CD5\u52A0\u8F7D\u65F6\u663E\u793A\u9ED8\u8BA4\u5934\u50CF", children: _jsx(Input, { id: "profile-avatar", maxLength: 2048, placeholder: "https://\u2026\uFF08\u53EF\u9009\uFF09", ...form.register('avatar_url') }) })] }), _jsxs("div", { className: "mt-6 flex flex-row items-center justify-between gap-4 rounded-lg border p-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium", children: "\u767B\u5F55\u90AE\u7BB1" }), _jsx("p", { className: "mt-0.5 truncate text-sm text-muted-foreground", "data-testid": "profile-email", children: user.email }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "\u7528\u4E8E\u767B\u5F55\u4E0E\u63A5\u6536\u901A\u77E5\uFF0C\u6682\u4E0D\u652F\u6301\u81EA\u52A9\u4FEE\u6539" })] }), _jsx("div", { className: "flex shrink-0 items-center gap-2", children: user.email_verified ? (_jsx(Badge, { variant: "secondary", className: "bg-(--success)/10 text-(--success) border-(--success)/30", children: "\u5DF2\u9A8C\u8BC1" })) : (_jsxs(_Fragment, { children: [_jsx(Badge, { variant: "outline", className: "text-(--warning) border-(--warning)/40 bg-(--warning)/15", children: "\u672A\u9A8C\u8BC1" }), _jsx(Button, { variant: "outline", size: "sm", onClick: handleResend, disabled: sending, children: sending ? '发送中…' : '重新发送验证邮件' })] })) })] })] }), _jsx(SettingsCard, { danger: true, title: "\u5220\u9664\u8D26\u53F7", description: "\u6CE8\u9500\u540E\u8D26\u53F7\u8FDB\u5165\u5220\u9664\u72B6\u6001\uFF0C\u65E0\u6CD5\u6062\u590D", cta: _jsx(Button, { variant: "destructive", disabled: !emailReadyToDelete || deleting, onClick: () => setConfirmOpen(true), children: "\u5220\u9664\u8D26\u53F7" }), children: _jsx("div", { className: "max-w-xl space-y-4", children: _jsx(FormField, { label: "\u8F93\u5165\u767B\u5F55\u90AE\u7BB1\u4EE5\u786E\u8BA4", htmlFor: "profile-delete-email", children: _jsx(Input, { id: "profile-delete-email", placeholder: user.email, value: confirmEmail, onChange: (e) => setConfirmEmail(e.target.value) }) }) }) }), _jsx(ImpactConfirmation, { open: confirmOpen, onOpenChange: setConfirmOpen, onConfirm: handleDelete, title: "\u786E\u8BA4\u5220\u9664\u8D26\u53F7\uFF1F", confirmText: "\u6C38\u4E45\u5220\u9664", danger: true, impacts: [
92
92
  '账号进入 deleted 状态,邮箱被释放(可用同邮箱重新注册)',
93
93
  '所有会话立即失效并吊销全部个人访问令牌(PAT)',
94
94
  '昵称、头像等资料被清空,操作不可恢复',
@@ -4,17 +4,17 @@ import { z } from 'zod';
4
4
  import { PageHeader, PageError } from '../../components/Page';
5
5
  import { SettingsCard } from '../../components/SettingsCard';
6
6
  import { FormField } from '../../components/FormField';
7
- import { Button } from '../../components/ui/Button';
8
- import { Input } from '../../components/ui/Input';
9
- import { Badge } from '../../components/ui/Badge';
7
+ import { Button } from '../../components/ui/button';
8
+ import { Input } from '../../components/ui/input';
9
+ import { Badge } from '../../components/ui/badge';
10
10
  import { DataTable } from '../../components/DataTable';
11
11
  import { ImpactConfirmation } from '../../components/SecretModal';
12
12
  import { useConfirm } from '../../components/ConfirmDialog';
13
13
  import { toast } from '../../components/toast';
14
- import { useApi } from '../../hooks/useApi';
15
- import { useAuth } from '../../hooks/useAuth';
16
- import { useZodForm } from '../../hooks/useZodForm';
17
- import { useSessions, useRevokeSession, useRevokeAllSessions } from '../../hooks/useSessions';
14
+ import { useApi } from '@ploykit/hooks';
15
+ import { useAuth } from '@ploykit/hooks';
16
+ import { useZodForm } from '@ploykit/hooks';
17
+ import { useSessions, useRevokeSession, useRevokeAllSessions } from '@ploykit/hooks';
18
18
  import { passwordSchema } from '../auth/RegisterPage';
19
19
  import { apiErrorMessage } from '../../lib/api-error';
20
20
  import { formatDateTime, shortID } from '../../lib/utils';
@@ -119,7 +119,7 @@ export function SecuritySettingsPage() {
119
119
  { key: 'expires_at', header: '过期时间', render: (s) => formatDateTime(s.expires_at) },
120
120
  {
121
121
  key: 'current', header: '当前',
122
- render: (s) => s.current === undefined ? (_jsx("span", { className: "text-muted-foreground", children: "\u2014" })) : s.current ? (_jsx(Badge, { variant: "secondary", className: "bg-emerald-50 text-emerald-700 border-emerald-200", children: "\u5F53\u524D\u8BBE\u5907" })) : (_jsx("span", { className: "text-muted-foreground", children: "\u2014" })),
122
+ render: (s) => s.current === undefined ? (_jsx("span", { className: "text-muted-foreground", children: "\u2014" })) : s.current ? (_jsx(Badge, { variant: "secondary", className: "bg-(--success)/10 text-(--success) border-(--success)/30", children: "\u5F53\u524D\u8BBE\u5907" })) : (_jsx("span", { className: "text-muted-foreground", children: "\u2014" })),
123
123
  },
124
124
  {
125
125
  key: 'actions', header: '', className: 'text-right',
@@ -2,15 +2,15 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
3
  import { PageHeader, PageEmpty } from '../../components/Page';
4
4
  import { FormField } from '../../components/FormField';
5
- import { Button } from '../../components/ui/Button';
6
- import { Input } from '../../components/ui/Input';
7
- import { Badge } from '../../components/ui/Badge';
5
+ import { Button } from '../../components/ui/button';
6
+ import { Input } from '../../components/ui/input';
7
+ import { Badge } from '../../components/ui/badge';
8
8
  import { DataTable } from '../../components/DataTable';
9
9
  import { SecretModal } from '../../components/SecretModal';
10
10
  import { useConfirm } from '../../components/ConfirmDialog';
11
11
  import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from '../../components/ui/dialog';
12
12
  import { toast } from '../../components/toast';
13
- import { useTokens, useCreateToken, useRevokeToken } from '../../hooks/useTokens';
13
+ import { useTokens, useCreateToken, useRevokeToken } from '@ploykit/hooks';
14
14
  import { apiErrorMessage } from '../../lib/api-error';
15
15
  import { formatDateTime } from '../../lib/utils';
16
16
  const NAME_MAX_BYTES = 64;
@@ -4,15 +4,15 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
4
4
  import { FormField } from '../../components/FormField';
5
5
  import { PageError, PageHeader } from '../../components/Page';
6
6
  import { toast } from '../../components/toast';
7
- import { Badge } from '../../components/ui/Badge';
8
- import { Button } from '../../components/ui/Button';
7
+ import { Badge } from '../../components/ui/badge';
8
+ import { Button } from '../../components/ui/button';
9
9
  import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, } from '../../components/ui/card';
10
- import { Input } from '../../components/ui/Input';
10
+ import { Input } from '../../components/ui/input';
11
11
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../components/ui/select';
12
12
  import { Switch } from '../../components/ui/switch';
13
- import { useApi } from '../../hooks/useApi';
13
+ import { useApi } from '@ploykit/hooks';
14
14
  import { SiteBanner } from '../../components/SiteBanner';
15
- import { SITE_CONFIG_QUERY_KEY } from '../../hooks/useSiteConfig';
15
+ import { SITE_CONFIG_QUERY_KEY } from '@ploykit/hooks';
16
16
  import { adminError } from './shared';
17
17
  const ERROR_TOAST_MS = 8_000;
18
18
  function parseRateLimit(raw) {
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Link, Navigate, useLocation } from 'react-router';
3
3
  import { Activity, ArrowLeft, Building2, KeyRound, LayoutDashboard, Receipt, ScrollText, Settings, ShieldCheck, Users, Webhook, } from 'lucide-react';
4
- import { buttonVariants } from '../../components/ui/Button';
4
+ import { buttonVariants } from '../../components/ui/button';
5
5
  import { UserMenu } from '../../components/UserMenu';
6
- import { useAuth } from '../../hooks/useAuth';
6
+ import { useAuth } from '@ploykit/hooks';
7
7
  import { cn } from '../../lib/utils';
8
8
  const NAV = [
9
9
  {
@@ -7,9 +7,9 @@ import { apiFetch } from '@ploykit/client';
7
7
  import { DataTable } from '../../components/DataTable';
8
8
  import { PageEmpty, PageError, PageHeader } from '../../components/Page';
9
9
  import { toast } from '../../components/toast';
10
- import { Button } from '../../components/ui/Button';
11
- import { Input } from '../../components/ui/Input';
12
- import { useApi } from '../../hooks/useApi';
10
+ import { Button } from '../../components/ui/button';
11
+ import { Input } from '../../components/ui/input';
12
+ import { useApi } from '@ploykit/hooks';
13
13
  import { apiErrorMessage } from '../../lib/api-error';
14
14
  import { shortID, formatDateTime } from '../../lib/utils';
15
15
  import { ADMIN_PAGE_SIZE, adminError } from './shared';
@@ -7,11 +7,12 @@ import { DataTable } from '../../components/DataTable';
7
7
  import { PageEmpty, PageError, PageHeader } from '../../components/Page';
8
8
  import { SettingsCard } from '../../components/SettingsCard';
9
9
  import { toast } from '../../components/toast';
10
- import { Badge, StatusBadge } from '../../components/ui/Badge';
11
- import { Button } from '../../components/ui/Button';
10
+ import { Badge } from '../../components/ui/badge';
11
+ import { StatusBadge } from '../../components/StatusBadge';
12
+ import { Button } from '../../components/ui/button';
12
13
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../components/ui/select';
13
14
  import { Tabs, TabsContent, TabsList, TabsTrigger, } from '../../components/ui/tabs';
14
- import { useApi } from '../../hooks/useApi';
15
+ import { useApi } from '@ploykit/hooks';
15
16
  import { formatDateTime, shortID, statusLabel } from '../../lib/utils';
16
17
  import { ADMIN_PAGE_SIZE, adminError, adminListQuery, formatCents, } from './shared';
17
18
  const ORDER_STATUSES = ['pending', 'paid', 'failed', 'canceled', 'refunded'];
@@ -7,13 +7,13 @@ import { DataTable } from '../../components/DataTable';
7
7
  import { FormField } from '../../components/FormField';
8
8
  import { PageEmpty, PageError, PageHeader } from '../../components/Page';
9
9
  import { toast } from '../../components/toast';
10
- import { Badge } from '../../components/ui/Badge';
11
- import { Button } from '../../components/ui/Button';
10
+ import { Badge } from '../../components/ui/badge';
11
+ import { Button } from '../../components/ui/button';
12
12
  import { Card, CardAction, CardDescription, CardHeader, CardTitle, } from '../../components/ui/card';
13
13
  import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../components/ui/dialog';
14
- import { Input } from '../../components/ui/Input';
14
+ import { Input } from '../../components/ui/input';
15
15
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../components/ui/select';
16
- import { useApi } from '../../hooks/useApi';
16
+ import { useApi } from '@ploykit/hooks';
17
17
  import { apiErrorMessage } from '../../lib/api-error';
18
18
  import { formatDateTime } from '../../lib/utils';
19
19
  import { adminError } from './shared';
@@ -4,9 +4,9 @@ import { Link } from 'react-router';
4
4
  import { useQuery } from '@tanstack/react-query';
5
5
  import { DataTable } from '../../components/DataTable';
6
6
  import { PageEmpty, PageError, PageHeader } from '../../components/Page';
7
- import { Badge } from '../../components/ui/Badge';
8
- import { Button } from '../../components/ui/Button';
9
- import { useApi } from '../../hooks/useApi';
7
+ import { Badge } from '../../components/ui/badge';
8
+ import { Button } from '../../components/ui/button';
9
+ import { useApi } from '@ploykit/hooks';
10
10
  import { formatDateTime } from '../../lib/utils';
11
11
  import { ADMIN_PAGE_SIZE, adminError } from './shared';
12
12
  export function SSOPage() {