@allbluecn/admin-app 0.3.2 → 0.3.3

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 (198) hide show
  1. package/package.json +19 -17
  2. package/src/components/admin/admin-user-menu.tsx +4 -4
  3. package/src/components/admin/developer-log.tsx +16 -32
  4. package/src/components/ai-memory/memory-facts-panel.tsx +30 -70
  5. package/src/components/ai-prompts/preview-panel.tsx +1 -1
  6. package/src/components/ai-prompts/prompt-editor.tsx +8 -9
  7. package/src/components/ai-prompts/prompt-table.tsx +6 -6
  8. package/src/components/ai-prompts/section-editor.tsx +3 -3
  9. package/src/components/ai-prompts/variable-panel.tsx +2 -2
  10. package/src/components/ai-prompts/version-history.tsx +21 -41
  11. package/src/components/ai-provider/model-list-editor.tsx +2 -3
  12. package/src/components/ai-provider/provider-form.tsx +7 -7
  13. package/src/components/ai-provider/provider-table.tsx +17 -40
  14. package/src/components/auth/admin-login-form.tsx +7 -7
  15. package/src/components/auth/icon-input.tsx +2 -2
  16. package/src/components/auth/password-input.tsx +2 -2
  17. package/src/components/component/component-form-dialog.tsx +10 -18
  18. package/src/components/component/component-import-dialog.tsx +6 -6
  19. package/src/components/component/component-preview.tsx +311 -0
  20. package/src/components/component/component-table.tsx +3 -3
  21. package/src/components/dependency/changelog-dialog.tsx +2 -2
  22. package/src/components/dependency/columns.tsx +3 -3
  23. package/src/components/dependency/dependency-table.tsx +7 -7
  24. package/src/components/dependency/edit-dialog.tsx +8 -8
  25. package/src/components/invitations/invitations-page.tsx +26 -49
  26. package/src/components/knowledge-public/bookmark-form-dialog.tsx +6 -6
  27. package/src/components/knowledge-public/compliance-form-dialog.tsx +6 -6
  28. package/src/components/knowledge-public/legal-form-dialog.tsx +7 -7
  29. package/src/components/layout/sidebar-02/app-sidebar.tsx +1 -2
  30. package/src/components/layout/sidebar-02/index.tsx +1 -1
  31. package/src/components/layout/sidebar-02/nav-main.tsx +2 -3
  32. package/src/components/layout/sidebar-02/nav-notifications.tsx +3 -3
  33. package/src/components/market/columns.tsx +4 -4
  34. package/src/components/market/market-app-form.tsx +6 -7
  35. package/src/components/market/market-app-list.tsx +14 -29
  36. package/src/components/monitoring/error-list.tsx +2 -2
  37. package/src/components/monitoring/metrics-stats.tsx +1 -1
  38. package/src/components/monitoring/request-log-table.tsx +2 -2
  39. package/src/components/oauth-providers/provider-page.tsx +20 -38
  40. package/src/components/permissions/assign-dialog.tsx +135 -0
  41. package/src/components/permissions/create-role-dialog.tsx +135 -0
  42. package/src/components/permissions/types.ts +49 -0
  43. package/src/components/user/columns.tsx +6 -6
  44. package/src/components/user/settings-activity-log.tsx +7 -7
  45. package/src/components/user/settings-profile/avatar-uploader.tsx +118 -0
  46. package/src/components/user/settings-profile/social-links.tsx +63 -0
  47. package/src/components/user/settings-profile.tsx +26 -125
  48. package/src/components/user/user-create-dialog.tsx +6 -6
  49. package/src/components/user/user-detail/error-boundary.tsx +19 -0
  50. package/src/components/user/user-detail/user-detail-dialogs.tsx +203 -0
  51. package/src/components/user/user-filters.tsx +4 -4
  52. package/src/lib/auth/page-gate.ts +28 -0
  53. package/src/lib/auth.config.ts +25 -9
  54. package/src/lib/i18n/detect.ts +1 -1
  55. package/src/lib/loader-serial.ts +14 -0
  56. package/src/providers/index.tsx +1 -1
  57. package/src/routeTree.gen.ts +67 -78
  58. package/src/routes/__root.tsx +4 -4
  59. package/src/routes/_nav/audit/route.lazy.tsx +1 -2
  60. package/src/routes/_nav/compliance/route.lazy.tsx +5 -3
  61. package/src/routes/_nav/components/route.lazy.tsx +14 -34
  62. package/src/routes/_nav/knowledge-public/bookmarks/route.lazy.tsx +18 -38
  63. package/src/routes/_nav/knowledge-public/compliance/route.lazy.tsx +18 -38
  64. package/src/routes/_nav/knowledge-public/legal/route.lazy.tsx +6 -6
  65. package/src/routes/_nav/licenses/$licenseId/route.lazy.tsx +3 -3
  66. package/src/routes/_nav/licenses/new/route.lazy.tsx +5 -5
  67. package/src/routes/_nav/licenses/route.lazy.tsx +1 -1
  68. package/src/routes/_nav/monitoring/ai-usage/route.lazy.tsx +2 -2
  69. package/src/routes/_nav/monitoring/errors/route.lazy.tsx +10 -10
  70. package/src/routes/_nav/monitoring/errors/route.tsx +7 -0
  71. package/src/routes/_nav/monitoring/health/route.lazy.tsx +13 -15
  72. package/src/routes/_nav/monitoring/health/route.tsx +14 -0
  73. package/src/routes/_nav/monitoring/logs/route.lazy.tsx +24 -9
  74. package/src/routes/_nav/monitoring/logs/route.tsx +13 -0
  75. package/src/routes/_nav/monitoring/metrics/route.lazy.tsx +12 -14
  76. package/src/routes/_nav/monitoring/metrics/route.tsx +7 -0
  77. package/src/routes/_nav/monitoring/overview/route.lazy.tsx +14 -13
  78. package/src/routes/_nav/monitoring/overview/route.tsx +17 -0
  79. package/src/routes/_nav/monitoring/route.lazy.tsx +6 -6
  80. package/src/routes/_nav/monitoring/sentry/route.lazy.tsx +2 -2
  81. package/src/routes/_nav/permissions/route.lazy.tsx +21 -311
  82. package/src/routes/_nav/permissions/route.tsx +1 -1
  83. package/src/routes/_nav/route.tsx +5 -13
  84. package/src/routes/_nav/sso/route.lazy.tsx +2 -3
  85. package/src/routes/_nav/users/$userId/route.lazy.tsx +91 -156
  86. package/src/routes/_nav/users/-components/users-table.tsx +1 -1
  87. package/src/routes/_nav/users/route.lazy.tsx +1 -1
  88. package/src/routes/login/route.lazy.tsx +1 -1
  89. package/src/routes/setup/route.lazy.tsx +2 -2
  90. package/src/server/__tests__/admin-billing.test.ts +191 -16
  91. package/src/server/__tests__/compliance.test.ts +44 -7
  92. package/src/server/__tests__/permissions.test.ts +10 -5
  93. package/src/server/__tests__/prompt-defaults.test.ts +3 -3
  94. package/src/server/admin-ai-alerts.ts +2 -1
  95. package/src/server/admin-ai-usage.ts +2 -1
  96. package/src/server/ai-memory/store.ts +6 -2
  97. package/src/server/{serverFns/ai-prompts → ai-prompts}/prompt-defaults.ts +5 -3
  98. package/src/server/{serverFns/dependency → dependency}/helpers.ts +4 -3
  99. package/src/server/knowledge-public/github-sync.ts +2 -1
  100. package/src/server/license-issue.ts +2 -1
  101. package/src/server/middlewares/auth-rate-limit.ts +117 -0
  102. package/src/server/observability/health-check.ts +4 -1
  103. package/src/server/observability/metrics.ts +17 -15
  104. package/src/server/observability/request-middleware.ts +2 -1
  105. package/src/server/observability/timing.ts +14 -16
  106. package/src/server/serverFns/admin-billing.ts +107 -12
  107. package/src/server/serverFns/ai-memory/list-users.ts +2 -1
  108. package/src/server/serverFns/ai-prompts/activate.ts +2 -1
  109. package/src/server/serverFns/ai-prompts/get.ts +3 -2
  110. package/src/server/serverFns/ai-prompts/list.ts +3 -2
  111. package/src/server/serverFns/ai-prompts/rollback.ts +3 -1
  112. package/src/server/serverFns/ai-prompts/save.ts +5 -3
  113. package/src/server/serverFns/ai-provider/create.ts +4 -1
  114. package/src/server/serverFns/ai-provider/delete.ts +4 -1
  115. package/src/server/serverFns/ai-provider/get.ts +4 -1
  116. package/src/server/serverFns/ai-provider/list.ts +28 -1
  117. package/src/server/serverFns/ai-provider/seed-from-seed.ts +2 -1
  118. package/src/server/serverFns/ai-provider/update.ts +4 -1
  119. package/src/server/serverFns/anyhub/market.ts +8 -1
  120. package/src/server/serverFns/audit.ts +14 -1
  121. package/src/server/serverFns/auth/setup.ts +3 -1
  122. package/src/server/serverFns/compliance.ts +32 -3
  123. package/src/server/serverFns/components/import.ts +69 -14
  124. package/src/server/serverFns/components/list.ts +4 -1
  125. package/src/server/serverFns/components/mutations.ts +9 -1
  126. package/src/server/serverFns/dependency/list.ts +28 -5
  127. package/src/server/serverFns/dependency/sync.ts +7 -2
  128. package/src/server/serverFns/dependency/update.ts +4 -1
  129. package/src/server/serverFns/developer-log-auto-generate.ts +63 -32
  130. package/src/server/serverFns/developer-logs.ts +5 -1
  131. package/src/server/serverFns/invitations.ts +7 -1
  132. package/src/server/serverFns/knowledge-public/bookmarks/create.ts +2 -1
  133. package/src/server/serverFns/knowledge-public/bookmarks/delete.ts +2 -1
  134. package/src/server/serverFns/knowledge-public/bookmarks/detail.ts +2 -1
  135. package/src/server/serverFns/knowledge-public/bookmarks/list.ts +2 -1
  136. package/src/server/serverFns/knowledge-public/bookmarks/sync-all-github.ts +2 -1
  137. package/src/server/serverFns/knowledge-public/bookmarks/update.ts +2 -1
  138. package/src/server/serverFns/knowledge-public/compliance/create.ts +2 -1
  139. package/src/server/serverFns/knowledge-public/compliance/delete.ts +2 -1
  140. package/src/server/serverFns/knowledge-public/compliance/detail.ts +2 -1
  141. package/src/server/serverFns/knowledge-public/compliance/list.ts +2 -1
  142. package/src/server/serverFns/knowledge-public/compliance/update.ts +2 -1
  143. package/src/server/serverFns/knowledge-public/legal/create.ts +2 -1
  144. package/src/server/serverFns/knowledge-public/legal/delete.ts +2 -1
  145. package/src/server/serverFns/knowledge-public/legal/detail.ts +2 -1
  146. package/src/server/serverFns/knowledge-public/legal/list.ts +2 -1
  147. package/src/server/serverFns/knowledge-public/legal/update.ts +2 -1
  148. package/src/server/serverFns/licenses.ts +8 -2
  149. package/src/server/serverFns/monitoring/get-errors.ts +2 -1
  150. package/src/server/serverFns/monitoring/get-health.ts +2 -1
  151. package/src/server/serverFns/monitoring/get-metrics.ts +2 -1
  152. package/src/server/serverFns/monitoring/get-request-logs.ts +2 -1
  153. package/src/server/serverFns/monitoring/report-error.ts +2 -1
  154. package/src/server/serverFns/monitoring/reset.ts +2 -1
  155. package/src/server/serverFns/oauth-providers.ts +4 -1
  156. package/src/server/serverFns/permissions.ts +18 -11
  157. package/src/server/serverFns/sentry/config.ts +11 -8
  158. package/src/server/serverFns/sso-config.ts +17 -2
  159. package/src/server/serverFns/user/create.ts +6 -1
  160. package/src/server/serverFns/user/delete.ts +6 -1
  161. package/src/server/serverFns/user/detail.ts +5 -2
  162. package/src/server/serverFns/user/list.ts +19 -4
  163. package/src/server/serverFns/user/reset-password.ts +10 -2
  164. package/src/server/serverFns/user/update-role.ts +10 -2
  165. package/src/server/serverFns/user/update-status.ts +10 -2
  166. package/src/styles/globals.css +4 -0
  167. package/src/components/data-table/data-table-pagination.tsx +0 -112
  168. package/src/components/data-table/data-table.tsx +0 -218
  169. package/src/components/data-table/table-detail-layout.tsx +0 -98
  170. package/src/components/ui/alert-dialog.tsx +0 -187
  171. package/src/components/ui/alert.tsx +0 -75
  172. package/src/components/ui/avatar.tsx +0 -106
  173. package/src/components/ui/badge.tsx +0 -51
  174. package/src/components/ui/button.tsx +0 -57
  175. package/src/components/ui/card.tsx +0 -102
  176. package/src/components/ui/checkbox.tsx +0 -28
  177. package/src/components/ui/collapsible.tsx +0 -19
  178. package/src/components/ui/dialog.tsx +0 -155
  179. package/src/components/ui/dropdown-menu.tsx +0 -267
  180. package/src/components/ui/field.tsx +0 -236
  181. package/src/components/ui/input-group.tsx +0 -158
  182. package/src/components/ui/input.tsx +0 -19
  183. package/src/components/ui/label.tsx +0 -17
  184. package/src/components/ui/pagination.tsx +0 -130
  185. package/src/components/ui/select.tsx +0 -234
  186. package/src/components/ui/separator.tsx +0 -22
  187. package/src/components/ui/sheet.tsx +0 -135
  188. package/src/components/ui/sidebar.tsx +0 -721
  189. package/src/components/ui/skeleton.tsx +0 -13
  190. package/src/components/ui/switch.tsx +0 -29
  191. package/src/components/ui/table.tsx +0 -115
  192. package/src/components/ui/textarea.tsx +0 -17
  193. package/src/components/ui/toast.tsx +0 -282
  194. package/src/components/ui/tooltip.tsx +0 -63
  195. package/src/hooks/use-mobile.ts +0 -19
  196. package/src/lib/avatar.ts +0 -41
  197. /package/src/routes/{api.auth.$.ts → api/auth/$.ts} +0 -0
  198. /package/src/routes/{api.sentry-test.ts → api/sentry-test.ts} +0 -0
@@ -1,158 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { cva, type VariantProps } from "class-variance-authority"
5
- import { cn } from "cn"
6
-
7
- import { Button } from "@/components/ui/button"
8
- import { Input } from "@/components/ui/input"
9
- import { Textarea } from "@/components/ui/textarea"
10
-
11
- function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
12
- return (
13
- <div
14
- data-slot="input-group"
15
- role="group"
16
- className={cn(
17
- "group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
18
- className
19
- )}
20
- {...props}
21
- />
22
- )
23
- }
24
-
25
- const inputGroupAddonVariants = cva(
26
- "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
27
- {
28
- variants: {
29
- align: {
30
- "inline-start":
31
- "order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]",
32
- "inline-end":
33
- "order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]",
34
- "block-start":
35
- "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
36
- "block-end":
37
- "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2",
38
- },
39
- },
40
- defaultVariants: {
41
- align: "inline-start",
42
- },
43
- }
44
- )
45
-
46
- function InputGroupAddon({
47
- className,
48
- align = "inline-start",
49
- ...props
50
- }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
51
- return (
52
- <div
53
- role="group"
54
- data-slot="input-group-addon"
55
- data-align={align}
56
- className={cn(inputGroupAddonVariants({ align }), className)}
57
- onClick={(e) => {
58
- if ((e.target as HTMLElement).closest("button")) {
59
- return
60
- }
61
- e.currentTarget.parentElement?.querySelector("input")?.focus()
62
- }}
63
- {...props}
64
- />
65
- )
66
- }
67
-
68
- const inputGroupButtonVariants = cva(
69
- "flex items-center gap-2 text-sm shadow-none",
70
- {
71
- variants: {
72
- size: {
73
- xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
74
- sm: "",
75
- "icon-xs":
76
- "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
77
- "icon-sm": "size-8 p-0 has-[>svg]:p-0",
78
- },
79
- },
80
- defaultVariants: {
81
- size: "xs",
82
- },
83
- }
84
- )
85
-
86
- function InputGroupButton({
87
- className,
88
- type = "button",
89
- variant = "ghost",
90
- size = "xs",
91
- ...props
92
- }: Omit<React.ComponentProps<typeof Button>, "size" | "type"> &
93
- VariantProps<typeof inputGroupButtonVariants> & {
94
- type?: "button" | "submit" | "reset"
95
- }) {
96
- return (
97
- <Button
98
- type={type}
99
- data-size={size}
100
- variant={variant}
101
- className={cn(inputGroupButtonVariants({ size }), className)}
102
- {...props}
103
- />
104
- )
105
- }
106
-
107
- function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
108
- return (
109
- <span
110
- className={cn(
111
- "flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
112
- className
113
- )}
114
- {...props}
115
- />
116
- )
117
- }
118
-
119
- function InputGroupInput({
120
- className,
121
- ...props
122
- }: React.ComponentProps<"input">) {
123
- return (
124
- <Input
125
- data-slot="input-group-control"
126
- className={cn(
127
- "flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
128
- className
129
- )}
130
- {...props}
131
- />
132
- )
133
- }
134
-
135
- function InputGroupTextarea({
136
- className,
137
- ...props
138
- }: React.ComponentProps<"textarea">) {
139
- return (
140
- <Textarea
141
- data-slot="input-group-control"
142
- className={cn(
143
- "flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
144
- className
145
- )}
146
- {...props}
147
- />
148
- )
149
- }
150
-
151
- export {
152
- InputGroup,
153
- InputGroupAddon,
154
- InputGroupButton,
155
- InputGroupText,
156
- InputGroupInput,
157
- InputGroupTextarea,
158
- }
@@ -1,19 +0,0 @@
1
- import * as React from "react"
2
- import { Input as InputPrimitive } from "@base-ui/react/input"
3
- import { cn } from "cn"
4
-
5
- function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
- return (
7
- <InputPrimitive
8
- type={type}
9
- data-slot="input"
10
- className={cn(
11
- "h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
12
- className
13
- )}
14
- {...props}
15
- />
16
- )
17
- }
18
-
19
- export { Input }
@@ -1,17 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "cn"
3
-
4
- function Label({ className, ...props }: React.ComponentProps<"label">) {
5
- return (
6
- <label
7
- data-slot="label"
8
- className={cn(
9
- "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
10
- className
11
- )}
12
- {...props}
13
- />
14
- )
15
- }
16
-
17
- export { Label }
@@ -1,130 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "cn"
3
-
4
- import { Button } from "@/components/ui/button"
5
- import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react"
6
-
7
- function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
8
- return (
9
- <nav
10
- role="navigation"
11
- aria-label="pagination"
12
- data-slot="pagination"
13
- className={cn("mx-auto flex w-full justify-center", className)}
14
- {...props}
15
- />
16
- )
17
- }
18
-
19
- function PaginationContent({
20
- className,
21
- ...props
22
- }: React.ComponentProps<"ul">) {
23
- return (
24
- <ul
25
- data-slot="pagination-content"
26
- className={cn("flex items-center gap-1", className)}
27
- {...props}
28
- />
29
- )
30
- }
31
-
32
- function PaginationItem({ ...props }: React.ComponentProps<"li">) {
33
- return <li data-slot="pagination-item" {...props} />
34
- }
35
-
36
- type PaginationLinkProps = {
37
- isActive?: boolean
38
- } & Pick<React.ComponentProps<typeof Button>, "size"> &
39
- React.ComponentProps<"a">
40
-
41
- function PaginationLink({
42
- className,
43
- isActive,
44
- size = "icon",
45
- ...props
46
- }: PaginationLinkProps) {
47
- return (
48
- <Button
49
- variant={isActive ? "outline" : "ghost"}
50
- size={size}
51
- className={cn(className)}
52
- nativeButton={false}
53
- render={
54
- <a
55
- aria-current={isActive ? "page" : undefined}
56
- data-slot="pagination-link"
57
- data-active={isActive}
58
- {...props}
59
- />
60
- }
61
- />
62
- )
63
- }
64
-
65
- function PaginationPrevious({
66
- className,
67
- text = "Previous",
68
- ...props
69
- }: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
70
- return (
71
- <PaginationLink
72
- aria-label="Go to previous page"
73
- size="default"
74
- className={cn("pl-2!", className)}
75
- {...props}
76
- >
77
- <ChevronLeftIcon data-icon="inline-start" />
78
- <span className="hidden sm:block">{text}</span>
79
- </PaginationLink>
80
- )
81
- }
82
-
83
- function PaginationNext({
84
- className,
85
- text = "Next",
86
- ...props
87
- }: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
88
- return (
89
- <PaginationLink
90
- aria-label="Go to next page"
91
- size="default"
92
- className={cn("pr-2!", className)}
93
- {...props}
94
- >
95
- <span className="hidden sm:block">{text}</span>
96
- <ChevronRightIcon data-icon="inline-end" />
97
- </PaginationLink>
98
- )
99
- }
100
-
101
- function PaginationEllipsis({
102
- className,
103
- ...props
104
- }: React.ComponentProps<"span">) {
105
- return (
106
- <span
107
- aria-hidden
108
- data-slot="pagination-ellipsis"
109
- className={cn(
110
- "flex size-9 items-center justify-center [&_svg:not([class*='size-'])]:size-4",
111
- className
112
- )}
113
- {...props}
114
- >
115
- <MoreHorizontalIcon
116
- />
117
- <span className="sr-only">More pages</span>
118
- </span>
119
- )
120
- }
121
-
122
- export {
123
- Pagination,
124
- PaginationContent,
125
- PaginationEllipsis,
126
- PaginationItem,
127
- PaginationLink,
128
- PaginationNext,
129
- PaginationPrevious,
130
- }
@@ -1,234 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { Select as SelectPrimitive } from "@base-ui/react/select"
5
- import { cn } from "cn"
6
- import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
7
-
8
- type CollectedItem = {
9
- label: React.ReactNode
10
- value: any
11
- }
12
-
13
- function collectItems(children: React.ReactNode, acc: CollectedItem[] = []): CollectedItem[] {
14
- React.Children.forEach(children, child => {
15
- if (!React.isValidElement(child)) {
16
- return
17
- }
18
- const el = child as React.ReactElement<any>
19
- if (el.type === SelectItem) {
20
- const { value, children: label } = el.props
21
- if (value !== undefined) {
22
- acc.push({ value, label })
23
- }
24
- return
25
- }
26
- if (el.props?.children) {
27
- collectItems(el.props.children, acc)
28
- }
29
- })
30
- return acc
31
- }
32
-
33
- function Select<Value, Multiple extends boolean | undefined = false>(
34
- { children, items, ...props }: SelectPrimitive.Root.Props<Value, Multiple>
35
- ) {
36
- const resolvedItems = React.useMemo(() => items ?? collectItems(children), [items, children])
37
- return (
38
- <SelectPrimitive.Root items={resolvedItems} {...props}>
39
- {children}
40
- </SelectPrimitive.Root>
41
- )
42
- }
43
-
44
- function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
45
- return (
46
- <SelectPrimitive.Group
47
- data-slot="select-group"
48
- className={cn("scroll-my-1 p-1", className)}
49
- {...props}
50
- />
51
- )
52
- }
53
-
54
- function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
55
- return (
56
- <SelectPrimitive.Value
57
- data-slot="select-value"
58
- className={cn("flex flex-1 text-left", className)}
59
- {...props}
60
- />
61
- )
62
- }
63
-
64
- function SelectTrigger({
65
- className,
66
- size = "default",
67
- children,
68
- ...props
69
- }: SelectPrimitive.Trigger.Props & {
70
- size?: "sm" | "default"
71
- }) {
72
- return (
73
- <SelectPrimitive.Trigger
74
- data-slot="select-trigger"
75
- data-size={size}
76
- className={cn(
77
- "flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
78
- className
79
- )}
80
- {...props}
81
- >
82
- {children}
83
- <SelectPrimitive.Icon
84
- render={
85
- <ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
86
- }
87
- />
88
- </SelectPrimitive.Trigger>
89
- )
90
- }
91
-
92
- function SelectContent({
93
- className,
94
- children,
95
- side = "bottom",
96
- sideOffset = 4,
97
- align = "center",
98
- alignOffset = 0,
99
- alignItemWithTrigger = true,
100
- ...props
101
- }: SelectPrimitive.Popup.Props &
102
- Pick<
103
- SelectPrimitive.Positioner.Props,
104
- "align" | "alignOffset" | "side" | "sideOffset" | "alignItemWithTrigger"
105
- >) {
106
- return (
107
- <SelectPrimitive.Portal>
108
- <SelectPrimitive.Positioner
109
- side={side}
110
- sideOffset={sideOffset}
111
- align={align}
112
- alignOffset={alignOffset}
113
- alignItemWithTrigger={alignItemWithTrigger}
114
- className="isolate z-50"
115
- >
116
- <SelectPrimitive.Popup
117
- data-slot="select-content"
118
- data-align-trigger={alignItemWithTrigger}
119
- className={cn("relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
120
- {...props}
121
- >
122
- <SelectScrollUpButton />
123
- <SelectPrimitive.List>{children}</SelectPrimitive.List>
124
- <SelectScrollDownButton />
125
- </SelectPrimitive.Popup>
126
- </SelectPrimitive.Positioner>
127
- </SelectPrimitive.Portal>
128
- )
129
- }
130
-
131
- function SelectLabel({
132
- className,
133
- ...props
134
- }: SelectPrimitive.GroupLabel.Props) {
135
- return (
136
- <SelectPrimitive.GroupLabel
137
- data-slot="select-label"
138
- className={cn("px-2 py-1.5 text-xs text-muted-foreground", className)}
139
- {...props}
140
- />
141
- )
142
- }
143
-
144
- function SelectItem({
145
- className,
146
- children,
147
- ...props
148
- }: SelectPrimitive.Item.Props) {
149
- return (
150
- <SelectPrimitive.Item
151
- data-slot="select-item"
152
- className={cn(
153
- "relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
154
- className
155
- )}
156
- {...props}
157
- >
158
- <SelectPrimitive.ItemText className="flex flex-1 shrink-0 gap-2 whitespace-nowrap">
159
- {children}
160
- </SelectPrimitive.ItemText>
161
- <SelectPrimitive.ItemIndicator
162
- render={
163
- <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />
164
- }
165
- >
166
- <CheckIcon className="pointer-events-none" />
167
- </SelectPrimitive.ItemIndicator>
168
- </SelectPrimitive.Item>
169
- )
170
- }
171
-
172
- function SelectSeparator({
173
- className,
174
- ...props
175
- }: SelectPrimitive.Separator.Props) {
176
- return (
177
- <SelectPrimitive.Separator
178
- data-slot="select-separator"
179
- className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
180
- {...props}
181
- />
182
- )
183
- }
184
-
185
- function SelectScrollUpButton({
186
- className,
187
- ...props
188
- }: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {
189
- return (
190
- <SelectPrimitive.ScrollUpArrow
191
- data-slot="select-scroll-up-button"
192
- className={cn(
193
- "top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
194
- className
195
- )}
196
- {...props}
197
- >
198
- <ChevronUpIcon
199
- />
200
- </SelectPrimitive.ScrollUpArrow>
201
- )
202
- }
203
-
204
- function SelectScrollDownButton({
205
- className,
206
- ...props
207
- }: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {
208
- return (
209
- <SelectPrimitive.ScrollDownArrow
210
- data-slot="select-scroll-down-button"
211
- className={cn(
212
- "bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
213
- className
214
- )}
215
- {...props}
216
- >
217
- <ChevronDownIcon
218
- />
219
- </SelectPrimitive.ScrollDownArrow>
220
- )
221
- }
222
-
223
- export {
224
- Select,
225
- SelectContent,
226
- SelectGroup,
227
- SelectItem,
228
- SelectLabel,
229
- SelectScrollDownButton,
230
- SelectScrollUpButton,
231
- SelectSeparator,
232
- SelectTrigger,
233
- SelectValue,
234
- }
@@ -1,22 +0,0 @@
1
- import { Separator as SeparatorPrimitive } from "@base-ui/react/separator"
2
- import { cn } from "cn"
3
-
4
- function Separator({
5
- className,
6
- orientation = "horizontal",
7
- ...props
8
- }: SeparatorPrimitive.Props) {
9
- return (
10
- <SeparatorPrimitive
11
- data-slot="separator"
12
- orientation={orientation}
13
- className={cn(
14
- "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
15
- className
16
- )}
17
- {...props}
18
- />
19
- )
20
- }
21
-
22
- export { Separator }