@ailog/cli 0.1.1 → 0.1.2

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 (111) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/cli.js +70 -3
  3. package/dist/standalone/.next/BUILD_ID +1 -1
  4. package/dist/standalone/.next/build-manifest.json +2 -2
  5. package/dist/standalone/.next/server/app/_global-error.html +2 -2
  6. package/dist/standalone/.next/server/app/_global-error.rsc +1 -1
  7. package/dist/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/dist/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/dist/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  10. package/dist/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  11. package/dist/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  12. package/dist/standalone/.next/server/app/_not-found.html +1 -1
  13. package/dist/standalone/.next/server/app/_not-found.rsc +1 -1
  14. package/dist/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  15. package/dist/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  16. package/dist/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  17. package/dist/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  18. package/dist/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  19. package/dist/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  20. package/dist/standalone/.next/server/app/api/[[...route]]/route.js.nft.json +1 -1
  21. package/dist/standalone/.next/server/app/index.html +1 -1
  22. package/dist/standalone/.next/server/app/index.rsc +1 -1
  23. package/dist/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  24. package/dist/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  25. package/dist/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  26. package/dist/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  27. package/dist/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  28. package/dist/standalone/.next/server/chunks/[root-of-the-server]__a0f47697._.js +1 -1
  29. package/dist/standalone/.next/server/chunks/ssr/node_modules__bun_4bd60410._.js +1 -1
  30. package/dist/standalone/.next/server/pages/404.html +1 -1
  31. package/dist/standalone/.next/server/pages/500.html +2 -2
  32. package/dist/standalone/dist/standalone/dist/standalone/package.json +4 -3
  33. package/dist/standalone/dist/standalone/package.json +3 -3
  34. package/dist/standalone/package.json +3 -3
  35. package/package.json +3 -3
  36. package/dist/standalone/.env +0 -0
  37. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  38. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  39. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  40. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  41. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  42. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  43. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  44. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  45. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  46. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  47. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  48. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  49. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  50. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  51. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  52. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  53. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  54. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  55. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  56. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  57. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  58. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  59. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  60. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  61. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  62. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  63. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  64. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  65. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  66. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  67. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  68. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  69. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  70. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  71. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  72. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  73. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  74. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  75. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  76. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  77. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  78. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  79. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  80. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  81. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  82. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  83. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  84. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  85. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/layout.tsx +0 -3
  86. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/page.tsx +0 -238
  87. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/settings/page.tsx +0 -224
  88. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/app/apps/[appId]/threads/[threadId]/page.tsx +0 -283
  89. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components/apps-table.tsx +0 -274
  90. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/components.json +0 -24
  91. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  92. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  93. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  94. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  95. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  96. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  97. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  98. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  99. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  100. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  101. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  102. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  103. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  104. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  105. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  106. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  107. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/package.json +0 -65
  108. package/dist/standalone/dist/standalone/dist/standalone/dist/standalone/tsconfig.json +0 -34
  109. /package/dist/standalone/.next/static/{8H5ZwnsPRw0PovUUXMbkb → UNT-TmC5XRRFhNzj7jZmZ}/_buildManifest.js +0 -0
  110. /package/dist/standalone/.next/static/{8H5ZwnsPRw0PovUUXMbkb → UNT-TmC5XRRFhNzj7jZmZ}/_clientMiddlewareManifest.json +0 -0
  111. /package/dist/standalone/.next/static/{8H5ZwnsPRw0PovUUXMbkb → UNT-TmC5XRRFhNzj7jZmZ}/_ssgManifest.js +0 -0
@@ -1,274 +0,0 @@
1
- 'use client'
2
-
3
- import { useState } from 'react'
4
- import { useRouter } from 'next/navigation'
5
- import Link from 'next/link'
6
- import {
7
- Table,
8
- TableBody,
9
- TableCell,
10
- TableHead,
11
- TableHeader,
12
- TableRow,
13
- } from '@/components/ui/table'
14
- import {
15
- DropdownMenu,
16
- DropdownMenuContent,
17
- DropdownMenuItem,
18
- DropdownMenuTrigger,
19
- } from '@/components/ui/dropdown-menu'
20
- import {
21
- AlertDialog,
22
- AlertDialogAction,
23
- AlertDialogCancel,
24
- AlertDialogContent,
25
- AlertDialogDescription,
26
- AlertDialogFooter,
27
- AlertDialogHeader,
28
- AlertDialogTitle,
29
- } from '@/components/ui/alert-dialog'
30
- import { Button } from '@/components/ui/button'
31
- import { Skeleton } from '@/components/ui/skeleton'
32
- import {
33
- Tooltip,
34
- TooltipContent,
35
- TooltipTrigger,
36
- } from '@/components/ui/tooltip'
37
- import { HugeiconsIcon } from '@hugeicons/react'
38
- import {
39
- MoreHorizontalCircle01Icon,
40
- EyeIcon,
41
- Delete02Icon,
42
- Copy01Icon,
43
- } from '@hugeicons/core-free-icons'
44
- import { rpcClient } from '@/lib/rpc-client'
45
- import { toast } from 'sonner'
46
- import type { App } from '@/lib/api'
47
-
48
- interface AppsTableProps {
49
- apps: App[]
50
- isLoading: boolean
51
- onDelete: () => void
52
- }
53
-
54
- function formatDate(dateString: string) {
55
- return new Date(dateString).toLocaleDateString('en-US', {
56
- year: 'numeric',
57
- month: 'short',
58
- day: 'numeric',
59
- hour: '2-digit',
60
- minute: '2-digit',
61
- })
62
- }
63
-
64
- function copyToClipboard(text: string) {
65
- navigator.clipboard.writeText(text)
66
- toast.success('Copied to clipboard')
67
- }
68
-
69
- function truncateId(id: string, maxLength = 12) {
70
- return id.length > maxLength ? `${id.substring(0, maxLength)}...` : id
71
- }
72
-
73
- export function AppsTable({ apps, isLoading, onDelete }: AppsTableProps) {
74
- const router = useRouter()
75
- const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)
76
- const [appToDelete, setAppToDelete] = useState<App | null>(null)
77
- const [isDeleting, setIsDeleting] = useState(false)
78
-
79
- const handleDelete = async () => {
80
- if (!appToDelete) return
81
-
82
- setIsDeleting(true)
83
- try {
84
- const res = await rpcClient.api.admin.apps[':appId'].$delete({
85
- param: { appId: appToDelete.appId },
86
- })
87
-
88
- if (!res.ok) {
89
- throw new Error('Failed to delete app')
90
- }
91
-
92
- toast.success('App deleted successfully')
93
- setDeleteDialogOpen(false)
94
- setAppToDelete(null)
95
- onDelete()
96
- } catch (error) {
97
- toast.error('Failed to delete app')
98
- console.error(error)
99
- } finally {
100
- setIsDeleting(false)
101
- }
102
- }
103
-
104
- if (isLoading) {
105
- return (
106
- <div className="rounded-md border">
107
- <Table>
108
- <TableHeader>
109
- <TableRow>
110
- <TableHead>App ID</TableHead>
111
- <TableHead>Name</TableHead>
112
- <TableHead>Created</TableHead>
113
- <TableHead>Updated</TableHead>
114
- <TableHead className="w-[70px]"></TableHead>
115
- </TableRow>
116
- </TableHeader>
117
- <TableBody>
118
- {[...Array(3)].map((_, i) => (
119
- <TableRow key={i}>
120
- <TableCell>
121
- <Skeleton className="h-5 w-48" />
122
- </TableCell>
123
- <TableCell>
124
- <Skeleton className="h-5 w-32" />
125
- </TableCell>
126
- <TableCell>
127
- <Skeleton className="h-5 w-36" />
128
- </TableCell>
129
- <TableCell>
130
- <Skeleton className="h-5 w-36" />
131
- </TableCell>
132
- <TableCell>
133
- <Skeleton className="h-8 w-8" />
134
- </TableCell>
135
- </TableRow>
136
- ))}
137
- </TableBody>
138
- </Table>
139
- </div>
140
- )
141
- }
142
-
143
- if (apps.length === 0) {
144
- return (
145
- <div className="rounded-md border p-8 text-center">
146
- <p className="text-muted-foreground">
147
- No apps yet. Create your first app to get started.
148
- </p>
149
- </div>
150
- )
151
- }
152
-
153
- return (
154
- <>
155
- <div className="rounded-md border">
156
- <Table>
157
- <TableHeader>
158
- <TableRow>
159
- <TableHead>App ID</TableHead>
160
- <TableHead>Name</TableHead>
161
- <TableHead>Created</TableHead>
162
- <TableHead>Updated</TableHead>
163
- <TableHead className="w-[70px]"></TableHead>
164
- </TableRow>
165
- </TableHeader>
166
- <TableBody>
167
- {apps.map((app) => (
168
- <TableRow
169
- key={app.appId}
170
- className="cursor-pointer"
171
- onClick={() => router.push(`/apps/${app.appId}`)}
172
- >
173
- <TableCell>
174
- <div className="flex items-center gap-2">
175
- {app.appId.length > 12 ? (
176
- <Tooltip>
177
- <TooltipTrigger asChild>
178
- <code className="text-muted-foreground cursor-default font-mono text-sm">
179
- {truncateId(app.appId)}
180
- </code>
181
- </TooltipTrigger>
182
- <TooltipContent>{app.appId}</TooltipContent>
183
- </Tooltip>
184
- ) : (
185
- <code className="text-muted-foreground font-mono text-sm">
186
- {app.appId}
187
- </code>
188
- )}
189
- <Button
190
- variant="ghost"
191
- size="icon"
192
- className="h-6 w-6"
193
- onClick={(e) => {
194
- e.stopPropagation()
195
- copyToClipboard(app.appId)
196
- }}
197
- >
198
- <HugeiconsIcon icon={Copy01Icon} className="h-3 w-3" />
199
- </Button>
200
- </div>
201
- </TableCell>
202
- <TableCell className="font-medium">{app.name}</TableCell>
203
- <TableCell className="text-muted-foreground">
204
- {formatDate(app.createdAt)}
205
- </TableCell>
206
- <TableCell className="text-muted-foreground">
207
- {formatDate(app.updatedAt)}
208
- </TableCell>
209
- <TableCell className="p-0" onClick={(e) => e.stopPropagation()}>
210
- <DropdownMenu>
211
- <DropdownMenuTrigger asChild>
212
- <button className="hover:bg-muted/50 flex h-full w-full items-center justify-center p-4">
213
- <HugeiconsIcon
214
- icon={MoreHorizontalCircle01Icon}
215
- className="h-4 w-4"
216
- />
217
- </button>
218
- </DropdownMenuTrigger>
219
- <DropdownMenuContent align="end">
220
- <DropdownMenuItem asChild>
221
- <Link href={`/apps/${app.appId}`}>
222
- <HugeiconsIcon
223
- icon={EyeIcon}
224
- className="mr-2 h-4 w-4"
225
- />
226
- View
227
- </Link>
228
- </DropdownMenuItem>
229
- <DropdownMenuItem
230
- className="text-destructive focus:text-destructive"
231
- onClick={() => {
232
- setAppToDelete(app)
233
- setDeleteDialogOpen(true)
234
- }}
235
- >
236
- <HugeiconsIcon
237
- icon={Delete02Icon}
238
- className="mr-2 h-4 w-4"
239
- />
240
- Delete
241
- </DropdownMenuItem>
242
- </DropdownMenuContent>
243
- </DropdownMenu>
244
- </TableCell>
245
- </TableRow>
246
- ))}
247
- </TableBody>
248
- </Table>
249
- </div>
250
-
251
- <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
252
- <AlertDialogContent>
253
- <AlertDialogHeader>
254
- <AlertDialogTitle>Delete App</AlertDialogTitle>
255
- <AlertDialogDescription>
256
- Are you sure you want to delete &quot;{appToDelete?.name}&quot;?
257
- This action cannot be undone and will delete all associated data.
258
- </AlertDialogDescription>
259
- </AlertDialogHeader>
260
- <AlertDialogFooter>
261
- <AlertDialogCancel>Cancel</AlertDialogCancel>
262
- <AlertDialogAction
263
- onClick={handleDelete}
264
- className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
265
- disabled={isDeleting}
266
- >
267
- {isDeleting ? 'Deleting...' : 'Delete'}
268
- </AlertDialogAction>
269
- </AlertDialogFooter>
270
- </AlertDialogContent>
271
- </AlertDialog>
272
- </>
273
- )
274
- }
@@ -1,24 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "radix-lyra",
4
- "rsc": true,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "",
8
- "css": "app/globals.css",
9
- "baseColor": "neutral",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "iconLibrary": "hugeicons",
14
- "aliases": {
15
- "components": "@/components",
16
- "utils": "@/lib/utils",
17
- "ui": "@/components/ui",
18
- "lib": "@/lib",
19
- "hooks": "@/hooks"
20
- },
21
- "menuColor": "default",
22
- "menuAccent": "subtle",
23
- "registries": {}
24
- }
@@ -1,238 +0,0 @@
1
- 'use client'
2
-
3
- import { useEffect, useState, useCallback } from 'react'
4
- import Link from 'next/link'
5
- import { useParams } from 'next/navigation'
6
- import { useQueryState, parseAsString } from 'nuqs'
7
- import { ThreadsTable } from '@/components/threads-table'
8
- import { Button } from '@/components/ui/button'
9
- import { Card, CardContent } from '@/components/ui/card'
10
- import { Input } from '@/components/ui/input'
11
- import { Label } from '@/components/ui/label'
12
- import { rpcClient } from '@/lib/rpc-client'
13
- import { useConfig } from '@/providers/config-provider'
14
- import { HugeiconsIcon } from '@hugeicons/react'
15
- import { FilterIcon, Cancel01Icon } from '@hugeicons/core-free-icons'
16
- import type { Thread, ApiKey } from '@/lib/api'
17
-
18
- export default function ThreadsPage() {
19
- const params = useParams()
20
- const appId = params.appId as string
21
- const { config, isLoading: isLoadingConfig } = useConfig()
22
-
23
- // URL params managed by nuqs
24
- const [tenantId, setTenantId] = useQueryState(
25
- 'tenantId',
26
- parseAsString.withDefault(''),
27
- )
28
- const [userId, setUserId] = useQueryState(
29
- 'userId',
30
- parseAsString.withDefault(''),
31
- )
32
-
33
- const [threads, setThreads] = useState<Thread[]>([])
34
- const [isLoading, setIsLoading] = useState(true)
35
- const [isLoadingMore, setIsLoadingMore] = useState(false)
36
- const [showFilters, setShowFilters] = useState(false)
37
-
38
- // Cursor pagination state
39
- const [nextCursor, setNextCursor] = useState<string | null>(null)
40
- const [hasMore, setHasMore] = useState(false)
41
-
42
- // API Keys state
43
- const [apiKeys, setApiKeys] = useState<ApiKey[]>([])
44
- const [isLoadingKeys, setIsLoadingKeys] = useState(true)
45
-
46
- // Pending filter state (for input fields before applying)
47
- const [pendingTenantId, setPendingTenantId] = useState(tenantId)
48
- const [pendingUserId, setPendingUserId] = useState(userId)
49
-
50
- // Sync pending state when URL params change
51
- useEffect(() => {
52
- setPendingTenantId(tenantId)
53
- setPendingUserId(userId)
54
- }, [tenantId, userId])
55
-
56
- const fetchThreads = useCallback(
57
- async (cursor?: string) => {
58
- if (cursor) {
59
- setIsLoadingMore(true)
60
- } else {
61
- setIsLoading(true)
62
- }
63
-
64
- try {
65
- const query: Record<string, string> = { limit: '50' }
66
- if (tenantId) query.tenantId = tenantId
67
- if (userId) query.userId = userId
68
- if (cursor) query.cursor = cursor
69
-
70
- const res = await rpcClient.api.admin.apps[':appId'].threads.$get({
71
- param: { appId },
72
- query,
73
- })
74
-
75
- if (res.ok) {
76
- const data = await res.json()
77
- if (cursor) {
78
- setThreads((prev) => [...prev, ...data.threads])
79
- } else {
80
- setThreads(data.threads)
81
- }
82
- setNextCursor(data.nextCursor)
83
- setHasMore(data.hasMore)
84
- }
85
- } catch (error) {
86
- console.error('Failed to fetch threads:', error)
87
- } finally {
88
- setIsLoading(false)
89
- setIsLoadingMore(false)
90
- }
91
- },
92
- [appId, tenantId, userId],
93
- )
94
-
95
- const fetchApiKeys = useCallback(async () => {
96
- try {
97
- const res = await rpcClient.api.admin.apps[':appId']['api-keys'].$get({
98
- param: { appId },
99
- })
100
- if (res.ok) {
101
- const data = await res.json()
102
- setApiKeys(data.keys)
103
- }
104
- } catch (error) {
105
- console.error('Failed to fetch API keys:', error)
106
- } finally {
107
- setIsLoadingKeys(false)
108
- }
109
- }, [appId])
110
-
111
- // Fetch threads when URL params change
112
- useEffect(() => {
113
- setNextCursor(null)
114
- setHasMore(false)
115
- fetchThreads()
116
- }, [fetchThreads])
117
-
118
- useEffect(() => {
119
- fetchApiKeys()
120
- }, [fetchApiKeys])
121
-
122
- const applyFilters = async () => {
123
- await Promise.all([
124
- setTenantId(pendingTenantId || null),
125
- setUserId(pendingUserId || null),
126
- ])
127
- }
128
-
129
- const clearFilters = async () => {
130
- setPendingTenantId('')
131
- setPendingUserId('')
132
- await Promise.all([setTenantId(null), setUserId(null)])
133
- }
134
-
135
- const loadMore = () => {
136
- if (nextCursor && !isLoadingMore) {
137
- fetchThreads(nextCursor)
138
- }
139
- }
140
-
141
- const hasFilters = tenantId || userId
142
- const standaloneMode = config?.standaloneMode ?? true
143
- const hasNoApiKeys =
144
- apiKeys.length === 0 &&
145
- !isLoadingKeys &&
146
- !isLoadingConfig &&
147
- !standaloneMode
148
-
149
- return (
150
- <div className="flex h-full flex-col">
151
- {/* Fixed Filter Section */}
152
- <div className="bg-background shrink-0 space-y-4 pb-4">
153
- {hasNoApiKeys && (
154
- <Card>
155
- <CardContent className="py-6 text-center">
156
- <p className="text-muted-foreground mb-2 text-sm">
157
- No API keys yet. Create one to start logging.
158
- </p>
159
- <Link
160
- href={`/apps/${appId}/settings`}
161
- className="text-primary text-sm font-medium hover:underline"
162
- >
163
- Go to Settings
164
- </Link>
165
- </CardContent>
166
- </Card>
167
- )}
168
-
169
- <div className="flex items-center justify-between">
170
- <p className="text-muted-foreground text-sm">
171
- {threads.length} thread{threads.length !== 1 ? 's' : ''} found
172
- </p>
173
- <Button
174
- variant="outline"
175
- size="sm"
176
- onClick={() => setShowFilters(!showFilters)}
177
- >
178
- <HugeiconsIcon icon={FilterIcon} className="mr-2 h-4 w-4" />
179
- Filters
180
- {hasFilters && (
181
- <span className="bg-primary text-primary-foreground ml-2 rounded-full px-2 py-0.5 text-xs">
182
- Active
183
- </span>
184
- )}
185
- </Button>
186
- </div>
187
-
188
- {showFilters && (
189
- <div className="space-y-4 rounded-lg border p-4">
190
- <div className="grid gap-4 md:grid-cols-3">
191
- <div className="space-y-2">
192
- <Label htmlFor="tenantId">Tenant ID</Label>
193
- <Input
194
- id="tenantId"
195
- placeholder="Filter by tenant..."
196
- value={pendingTenantId}
197
- onChange={(e) => setPendingTenantId(e.target.value)}
198
- />
199
- </div>
200
- <div className="space-y-2">
201
- <Label htmlFor="userId">User ID</Label>
202
- <Input
203
- id="userId"
204
- placeholder="Filter by user..."
205
- value={pendingUserId}
206
- onChange={(e) => setPendingUserId(e.target.value)}
207
- />
208
- </div>
209
- </div>
210
- <div className="flex gap-2">
211
- <Button size="sm" onClick={applyFilters}>
212
- Apply Filters
213
- </Button>
214
- {hasFilters && (
215
- <Button size="sm" variant="outline" onClick={clearFilters}>
216
- <HugeiconsIcon icon={Cancel01Icon} className="mr-2 h-4 w-4" />
217
- Clear
218
- </Button>
219
- )}
220
- </div>
221
- </div>
222
- )}
223
- </div>
224
-
225
- {/* Table with sticky header - scrollable area */}
226
- <div className="min-h-0 flex-1 overflow-auto rounded-md border">
227
- <ThreadsTable
228
- threads={threads}
229
- isLoading={isLoading}
230
- appId={appId}
231
- hasMore={hasMore}
232
- isLoadingMore={isLoadingMore}
233
- onLoadMore={loadMore}
234
- />
235
- </div>
236
- </div>
237
- )
238
- }