create-fullstack-scaffold 0.4.3 → 0.4.5

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 (147) hide show
  1. package/dist/cli/index.js +5 -0
  2. package/dist/cli/index.js.map +1 -1
  3. package/package.json +1 -1
  4. package/template/dist/cli/index.js +237 -94
  5. package/template/dist/cli/index.js.map +1 -1
  6. package/template/dist/client/admin.html +15 -10
  7. package/template/dist/client/assets/App-BpFUIC-5.js +114 -0
  8. package/template/dist/client/assets/{CartPage-DESSHkaG.js → CartPage-DgDZP-R5.js} +2 -2
  9. package/template/dist/client/assets/{CategoriesPage-DqLZ_Mom.js → CategoriesPage-fuYNiSmE.js} +2 -2
  10. package/template/dist/client/assets/ContentDetailPage-BvvFU1Mr.js +1 -0
  11. package/template/dist/client/assets/ContentListPage-ShPxo6WG.js +1 -0
  12. package/template/dist/client/assets/DashboardPage-C1rZzZo4.js +11 -0
  13. package/template/dist/client/assets/{DeveloperDashboardPage-Cum7zFwO.js → DeveloperDashboardPage-_WtmbVoA.js} +2 -2
  14. package/template/dist/client/assets/{EmptyState-BK7ttK8D.js → EmptyState-DEyOQjbY.js} +1 -1
  15. package/template/dist/client/assets/LoadingSpinner-BcHjaM1m.js +6 -0
  16. package/template/dist/client/assets/LoginPage-CjeQqDdO.js +1 -0
  17. package/template/dist/client/assets/LogoutOutlined-ColFAHdd.js +1 -0
  18. package/template/dist/client/assets/NotificationPage-DRkEv02s.js +1 -0
  19. package/template/dist/client/assets/OrdersPage-7I3vPWLP.js +11 -0
  20. package/template/dist/client/assets/{PluginDetailPage-Br24YS4P.js → PluginDetailPage-CWyxdVCg.js} +3 -13
  21. package/template/dist/client/assets/PluginsPage-DRgWLeJT.js +6 -0
  22. package/template/dist/client/assets/ProfilePage-2FFkaii8.js +16 -0
  23. package/template/dist/client/assets/PublishPage-DW7yvROx.js +1 -0
  24. package/template/dist/client/assets/{RegisterPage-rPFG4Sry.js → RegisterPage-Dvaf9b0e.js} +2 -2
  25. package/template/dist/client/assets/SaveOutlined-CLQ2tsSY.js +2 -0
  26. package/template/dist/client/assets/{SearchPage-DQl1U5Uy.js → SearchPage-DvnEyswS.js} +2 -2
  27. package/template/dist/client/assets/{SettingsPage-DaYE80wj.js → SettingsPage-IrU-L9Zr.js} +2 -2
  28. package/template/dist/client/assets/{StatusBadge-BJ3W2Zc7.js → StatusBadge-CG7wVqpu.js} +1 -1
  29. package/template/dist/client/assets/{TodoPage-zC5wWNBa.js → TodoPage-B7D-bl65.js} +3 -3
  30. package/template/dist/client/assets/TopicsPage-CYCNr-mn.js +6 -0
  31. package/template/dist/client/assets/{WebSocketPage-B4NLdz1w.js → WebSocketPage-CGEg6QJE.js} +2 -2
  32. package/template/dist/client/assets/{activity-B94BUAsD.js → activity-CgTz9Mrd.js} +1 -1
  33. package/template/dist/client/assets/admin-D2iHWNOg.js +1 -0
  34. package/template/dist/client/assets/api-request-DIJocPxr.js +356 -0
  35. package/template/dist/client/assets/{arrow-left-H5JH0iU1.js → arrow-left-DtLQ3tTk.js} +1 -1
  36. package/template/dist/client/assets/{chevron-down-DwRh_wjD.js → chevron-down-CpIAV_yr.js} +1 -1
  37. package/template/dist/client/assets/{chevron-right-CpIWaqAL.js → chevron-right-CnU7oPQs.js} +1 -1
  38. package/template/dist/client/assets/{circle-check-big-CSElLscG.js → circle-check-big-CrZdwS75.js} +1 -1
  39. package/template/dist/client/assets/{circle-x-CYxr4RAw.js → circle-x-CvN9r3fW.js} +1 -1
  40. package/template/dist/client/assets/{clock-BseUJ7ex.js → clock-CTeSZBiH.js} +1 -1
  41. package/template/dist/client/assets/{download-BsGC_Xhq.js → download-OSVfVuNV.js} +1 -1
  42. package/template/dist/client/assets/{external-link-UTDzdjq8.js → external-link-fBsuHMby.js} +1 -1
  43. package/template/dist/client/assets/{eye-nR10ui7i.js → eye-CwlZZEsj.js} +1 -1
  44. package/template/dist/client/assets/index-09IqiOaE.css +1 -0
  45. package/template/dist/client/assets/index-B3CRby6r.js +51 -0
  46. package/template/dist/client/assets/index-CC_zy73y.js +17 -0
  47. package/template/dist/client/assets/main-Cn4IDo2I.js +92 -0
  48. package/template/dist/client/assets/merchant-DDDN9bMu.js +40 -0
  49. package/template/dist/client/assets/{message-square-CwWGL-Bh.js → message-square-BRaZfgbJ.js} +1 -1
  50. package/template/dist/client/assets/pluginStore-DDsWJPe6.js +1 -0
  51. package/template/dist/client/assets/{plus-pZld_nUL.js → plus-DDZfPiDJ.js} +1 -1
  52. package/template/dist/client/assets/sse-client-DGQ072hl.js +64 -0
  53. package/template/dist/client/assets/star-C7tO6w4H.js +11 -0
  54. package/template/dist/client/assets/{tag-DsiUPF90.js → tag-DBfpQDuJ.js} +1 -1
  55. package/template/dist/client/assets/tenant-CizbLaLJ.js +1 -0
  56. package/template/dist/client/assets/{trash-2-DRblNbnA.js → trash-2-BP7fkd5b.js} +1 -1
  57. package/template/dist/client/assets/{triangle-alert-D1CLh-Vd.js → triangle-alert-CrOQEdJ2.js} +1 -1
  58. package/template/dist/client/assets/{wifi-BwXjnCqI.js → wifi-CwYSE0J4.js} +1 -1
  59. package/template/dist/client/assets/{x-BH2rJdFq.js → x-t615pnNR.js} +1 -1
  60. package/template/dist/client/content/index.html +5 -4
  61. package/template/dist/client/index.html +4 -3
  62. package/template/dist/client/merchant.html +18 -0
  63. package/template/dist/client/notifications/index.html +6 -5
  64. package/template/dist/client/tenant.html +18 -0
  65. package/template/dist/client/todos/index.html +6 -5
  66. package/template/dist/client/websocket/index.html +6 -5
  67. package/template/dist/cloudflare/chunk-HX7DVRDX.js +1 -0
  68. package/template/dist/cloudflare/{chunk-QBHAPWIA.js → chunk-IXJL2LE4.js} +1 -1
  69. package/template/dist/cloudflare/chunk-Q34AN3RF.js +14 -0
  70. package/template/dist/cloudflare/{chunk-BHPTQ4K2.js → chunk-ZAMVL4EG.js} +2 -2
  71. package/template/dist/cloudflare/cloudflare.js +35 -29
  72. package/template/dist/cloudflare/db-4AQOSFAX.js +1 -0
  73. package/template/dist/cloudflare/{migrator-2ZYYKNI5.js → migrator-TEPBVUFO.js} +1 -1
  74. package/template/dist/cloudflare/permission-service-impl-RE7NPW3Q.js +1 -0
  75. package/template/dist/cloudflare/schema-DVEMT3X2.js +1 -0
  76. package/template/dist/cloudflare/test-setup-Z2RYE5B4.js +265 -0
  77. package/template/dist/server/chunk-27SIJSPF.js +1 -0
  78. package/template/dist/server/chunk-37QNGBQU.js +1 -0
  79. package/template/dist/server/chunk-FIY4CGJJ.js +1 -0
  80. package/template/dist/server/chunk-HZUDBIT4.js +1 -0
  81. package/template/dist/server/chunk-I6OBDFDU.js +1 -0
  82. package/template/dist/server/chunk-JHNYLNG7.js +1 -0
  83. package/template/dist/server/chunk-MDOVVKKD.js +1 -0
  84. package/template/dist/server/chunk-NSOCT7E5.js +1 -0
  85. package/template/dist/server/chunk-OU5IGVVO.js +1 -0
  86. package/template/dist/server/chunk-OYCBNRMK.js +1 -0
  87. package/template/dist/server/chunk-P2RJNNGD.js +1 -0
  88. package/template/dist/server/chunk-UMAQLNPE.js +1 -0
  89. package/template/dist/server/chunk-XZZTSRSN.js +1 -0
  90. package/template/dist/server/content-service-5QVHDR5X.js +1 -0
  91. package/template/dist/server/db-FLI5L5DD.js +1 -0
  92. package/template/dist/server/dispute-service-E2FCYUEM.js +1 -0
  93. package/template/dist/server/init-72JXJV3I.js +46 -0
  94. package/template/dist/server/init-FWYXSKPX.js +46 -0
  95. package/template/dist/server/node.js +34 -28
  96. package/template/dist/server/order-service-TKGG5S5K.js +1 -0
  97. package/template/dist/server/permission-service-impl-M3AKEYNY.js +1 -0
  98. package/template/dist/server/schema-V4UG7HMU.js +1 -0
  99. package/template/dist/server/tenant-service-JG6UUWXQ.js +1 -0
  100. package/template/dist/server/tenant-service-XJWZSEDX.js +1 -0
  101. package/template/dist/{cloudflare/test-setup-NMZJZLRV.js → server/test-setup-VFOPBGYM.js} +83 -2
  102. package/template/dist/server/ticket-service-3RSW7V2Z.js +1 -0
  103. package/template/dist/server/todo-service-S6BGIO7D.js +1 -0
  104. package/template/src/merchant/pages/DisputesPage.tsx +11 -11
  105. package/template/src/merchant/pages/OrdersPage.tsx +4 -3
  106. package/template/src/merchant/pages/ProductsPage.tsx +2 -2
  107. package/template/src/merchant/stores/merchantStore.ts +11 -6
  108. package/template/src/server/db/init.ts +5 -642
  109. package/template/src/server/module-plugin/services/plugin-seed-service.ts +623 -0
  110. package/template/src/server/module-tenant/routes/tenant-routes.ts +2 -2
  111. package/template/src/server/module-tenant/services/tenant-service.ts +63 -17
  112. package/template/src/shared/modules/merchant/index.ts +9 -0
  113. package/template/src/shared/modules/merchant/schemas.ts +37 -0
  114. package/template/src/shared/modules/tenant/index.ts +2 -0
  115. package/template/src/shared/schemas/index.ts +27 -0
  116. package/template/src/tenant/layouts/Header.tsx +1 -1
  117. package/template/src/tenant/layouts/Sidebar.tsx +1 -1
  118. package/template/src/tenant/pages/SettingsPage.tsx +4 -8
  119. package/template/src/tenant/stores/tenantStore.ts +41 -302
  120. package/template/tsconfig.json +1 -0
  121. package/template/tsup.config.ts +11 -3
  122. package/template/dist/client/assets/ContentDetailPage-DdltMANL.js +0 -1
  123. package/template/dist/client/assets/ContentListPage-B63sUB6N.js +0 -1
  124. package/template/dist/client/assets/DashboardPage-tUMilc7Z.js +0 -11
  125. package/template/dist/client/assets/LoadingSpinner-DVYOLSRM.js +0 -6
  126. package/template/dist/client/assets/LoginPage-g9mSLIMC.js +0 -6
  127. package/template/dist/client/assets/NotificationPage-COTzp-HD.js +0 -1
  128. package/template/dist/client/assets/OrdersPage-BsPh4oEI.js +0 -11
  129. package/template/dist/client/assets/PluginsPage-BNtAe_yo.js +0 -6
  130. package/template/dist/client/assets/ProfilePage-dL_iSuZN.js +0 -16
  131. package/template/dist/client/assets/PublishPage-D96FnbLA.js +0 -1
  132. package/template/dist/client/assets/TopicsPage-DyLjZa4D.js +0 -6
  133. package/template/dist/client/assets/admin-Bh1vfz_L.js +0 -486
  134. package/template/dist/client/assets/index-1bA-ixFv.js +0 -114
  135. package/template/dist/client/assets/index-CWh3vXC_.css +0 -1
  136. package/template/dist/client/assets/main-DHnArIp_.js +0 -82
  137. package/template/dist/client/assets/pluginStore-XQfsm3iR.js +0 -1
  138. package/template/dist/client/content/content-1/index.html +0 -18
  139. package/template/dist/client/content/content-13/index.html +0 -18
  140. package/template/dist/client/content/content-14/index.html +0 -18
  141. package/template/dist/client/content/content-15/index.html +0 -18
  142. package/template/dist/client/content/content-19/index.html +0 -18
  143. package/template/dist/client/content/content-2/index.html +0 -18
  144. package/template/dist/client/content/content-20/index.html +0 -18
  145. package/template/dist/cloudflare/chunk-YY6FRMAQ.js +0 -14
  146. package/template/dist/cloudflare/db-7J42RQ3T.js +0 -1
  147. package/template/dist/cloudflare/permission-service-impl-TGXVSSSA.js +0 -1
@@ -1,6 +1,4 @@
1
1
  import { create } from 'zustand'
2
- import { hc } from 'hono/client'
3
- import type { AppType } from '@server/index'
4
2
  import type {
5
3
  Tenant,
6
4
  UpdateTenantInput,
@@ -9,8 +7,6 @@ import type {
9
7
  UpdateTodoInput,
10
8
  Topic,
11
9
  } from '@shared/schemas'
12
- import type { WSClientImpl } from '@shared/core/ws-client'
13
- import type { SSEClientImpl } from '@shared/core/sse-client'
14
10
 
15
11
  interface TenantState {
16
12
  isAuthenticated: boolean
@@ -44,51 +40,6 @@ interface TenantState {
44
40
  stopLoading: () => void
45
41
  }
46
42
 
47
- let apiClient: ReturnType<typeof hc<AppType>> | null = null
48
-
49
- function createTenantClient(): ReturnType<typeof hc<AppType>> {
50
- if (!apiClient) {
51
- const tenantSlug = localStorage.getItem('current-tenant-slug') || ''
52
- const baseUrl = import.meta.env.API_BASE_URL || window.location.origin
53
-
54
- apiClient = hc<AppType>(baseUrl, {
55
- webSocket: (url: string) => {
56
- const wsClass = class extends WebSocket {
57
- constructor(urlStr: string) {
58
- super(urlStr)
59
- this.addEventListener('open', () => {
60
- if (this instanceof WebSocket) {
61
- this.send(
62
- JSON.stringify({
63
- type: 'auth',
64
- token: localStorage.getItem('tenant-token') || '',
65
- })
66
- )
67
- }
68
- })
69
- }
70
- }
71
- return new wsClass(url) as unknown as WSClientImpl
72
- },
73
- sse: (url: string) => {
74
- const eventSourceClass = class extends EventSource {
75
- constructor(urlStr: string, eventSourceInitDict?: EventSourceInit) {
76
- const headers = eventSourceInitDict || {}
77
- headers['X-Tenant-Slug'] = tenantSlug
78
- super(urlStr, headers)
79
- }
80
- }
81
- return new eventSourceClass(url) as unknown as SSEClientImpl
82
- },
83
- })
84
- }
85
- return apiClient
86
- }
87
-
88
- function getTenantSlug(): string {
89
- return localStorage.getItem('current-tenant-slug') || ''
90
- }
91
-
92
43
  interface TenantStats {
93
44
  totalUsers: number
94
45
  activeTodos: number
@@ -115,290 +66,78 @@ export const useTenantStore = create<TenantState>(set => ({
115
66
 
116
67
  setLoading: loading => set({ loading }),
117
68
 
118
- fetchCurrentTenant: async slug => {
119
- set({ loading: true })
120
- try {
121
- const client = createTenantClient()
122
- const response = await client.api.tenant.slug.$get({
123
- param: { slug },
124
- headers: { 'X-Tenant-Slug': slug },
125
- })
126
- const result = await response.json()
127
-
128
- if (result.success) {
129
- set({ currentTenant: result.data })
130
- }
131
- } catch (error) {
132
- console.error('Failed to fetch tenant:', error)
133
- } finally {
134
- set({ loading: false })
135
- }
136
- },
137
-
138
69
  fetchUsers: async () => {
139
- set({ loading: true })
140
- try {
141
- const client = createTenantClient()
142
- const tenantSlug = getTenantSlug()
143
- const response = await client.api.users.$get({
144
- headers: { 'X-Tenant-Slug': tenantSlug },
145
- })
146
- const result = await response.json()
147
-
148
- if (result.success) {
149
- set({ users: result.data })
150
- }
151
- } catch (error) {
152
- console.error('Failed to fetch users:', error)
153
- } finally {
154
- set({ loading: false })
155
- }
70
+ console.warn('User management not implemented for tenant module')
156
71
  },
157
72
 
158
- createUser: async data => {
159
- try {
160
- const client = createTenantClient()
161
- const tenantSlug = getTenantSlug()
162
- const response = await client.api.users.$post({
163
- json: data,
164
- headers: { 'X-Tenant-Slug': tenantSlug },
165
- })
166
- const result = await response.json()
167
- return result.success
168
- } catch (error) {
169
- console.error('Failed to create user:', error)
170
- return false
171
- }
73
+ createUser: async () => {
74
+ console.warn('User creation not implemented for tenant module')
75
+ return false
172
76
  },
173
77
 
174
- updateUser: async (userId, data) => {
175
- try {
176
- const client = createTenantClient()
177
- const tenantSlug = getTenantSlug()
178
- const response = await client.api.users[':id'].$put({
179
- param: { id: userId.toString() },
180
- json: data,
181
- headers: { 'X-Tenant-Slug': tenantSlug },
182
- })
183
- const result = await response.json()
184
- return result.success
185
- } catch (error) {
186
- console.error('Failed to update user:', error)
187
- return false
188
- }
78
+ updateUser: async () => {
79
+ console.warn('User update not implemented for tenant module')
80
+ return false
189
81
  },
190
82
 
191
- deleteUser: async userId => {
192
- try {
193
- const client = createTenantClient()
194
- const tenantSlug = getTenantSlug()
195
- const response = await client.api.users[':id'].$delete({
196
- param: { id: userId.toString() },
197
- headers: { 'X-Tenant-Slug': tenantSlug },
198
- })
199
- const result = await response.json()
200
- return result.success
201
- } catch (error) {
202
- console.error('Failed to delete user:', error)
203
- return false
204
- }
83
+ deleteUser: async () => {
84
+ console.warn('User deletion not implemented for tenant module')
85
+ return false
205
86
  },
206
87
 
207
- fetchTodos: async () => {
208
- set({ loading: true })
209
- try {
210
- const client = createTenantClient()
211
- const tenantSlug = getTenantSlug()
212
- const response = await client.api.todos.$get({
213
- headers: { 'X-Tenant-Slug': tenantSlug },
214
- })
215
- const result = await response.json()
216
-
217
- if (result.success) {
218
- set({ todos: result.data })
219
- }
220
- } catch (error) {
221
- console.error('Failed to fetch todos:', error)
222
- } finally {
223
- set({ loading: false })
224
- }
88
+ createTopic: async () => {
89
+ console.warn('Topic creation not implemented for tenant module')
90
+ return false
225
91
  },
226
92
 
227
- createTodo: async data => {
228
- try {
229
- const client = createTenantClient()
230
- const tenantSlug = getTenantSlug()
231
- const response = await client.api.todos.$post({
232
- json: data,
233
- headers: { 'X-Tenant-Slug': tenantSlug },
234
- })
235
- const result = await response.json()
236
- return result.success
237
- } catch (error) {
238
- console.error('Failed to create todo:', error)
239
- return false
240
- }
93
+ updateTopic: async () => {
94
+ console.warn('Topic update not implemented for tenant module')
95
+ return false
241
96
  },
242
97
 
243
- updateTodo: async (todoId, data) => {
244
- try {
245
- const client = createTenantClient()
246
- const tenantSlug = getTenantSlug()
247
- const response = await client.api.todos[':id'].$put({
248
- param: { id: todoId.toString() },
249
- json: data,
250
- headers: { 'X-Tenant-Slug': tenantSlug },
251
- })
252
- const result = await response.json()
253
- return result.success
254
- } catch (error) {
255
- console.error('Failed to update todo:', error)
256
- return false
257
- }
98
+ deleteTopic: async () => {
99
+ console.warn('Topic deletion not implemented for tenant module')
100
+ return false
258
101
  },
259
102
 
260
- deleteTodo: async todoId => {
261
- try {
262
- const client = createTenantClient()
263
- const tenantSlug = getTenantSlug()
264
- const response = await client.api.todos[':id'].$delete({
265
- param: { id: todoId.toString() },
266
- headers: { 'X-Tenant-Slug': tenantSlug },
267
- })
268
- const result = await response.json()
269
- return result.success
270
- } catch (error) {
271
- console.error('Failed to delete todo:', error)
272
- return false
273
- }
103
+ fetchSubscription: async () => {
104
+ console.warn('Subscription management not implemented for tenant module')
274
105
  },
275
106
 
276
- fetchTopics: async () => {
277
- set({ loading: true })
278
- try {
279
- const client = createTenantClient()
280
- const tenantSlug = getTenantSlug()
281
- const response = await client.api.topics.$get({
282
- headers: { 'X-Tenant-Slug': tenantSlug },
283
- })
284
- const result = await response.json()
285
-
286
- if (result.success) {
287
- set({ topics: result.data })
288
- }
289
- } catch (error) {
290
- console.error('Failed to fetch topics:', error)
291
- } finally {
292
- set({ loading: false })
293
- }
107
+ fetchCurrentTenant: async (_slug: string) => {
108
+ console.warn('Tenant routes not registered - tenant module not active')
294
109
  },
295
110
 
296
- createTopic: async data => {
297
- try {
298
- const client = createTenantClient()
299
- const tenantSlug = getTenantSlug()
300
- const response = await client.api.topics.$post({
301
- json: data,
302
- headers: { 'X-Tenant-Slug': tenantSlug },
303
- })
304
- const result = await response.json()
305
- return result.success
306
- } catch (error) {
307
- console.error('Failed to create topic:', error)
308
- return false
309
- }
111
+ fetchTodos: async () => {
112
+ console.warn('Tenant routes not registered - tenant module not active')
310
113
  },
311
114
 
312
- updateTopic: async (topicId, data) => {
313
- try {
314
- const client = createTenantClient()
315
- const tenantSlug = getTenantSlug()
316
- const response = await client.api.topics[':id'].$put({
317
- param: { id: topicId.toString() },
318
- json: data,
319
- headers: { 'X-Tenant-Slug': tenantSlug },
320
- })
321
- const result = await response.json()
322
- return result.success
323
- } catch (error) {
324
- console.error('Failed to update topic:', error)
325
- return false
326
- }
115
+ createTodo: async () => {
116
+ console.warn('Tenant routes not registered - tenant module not active')
117
+ return false
327
118
  },
328
119
 
329
- deleteTopic: async topicId => {
330
- try {
331
- const client = createTenantClient()
332
- const tenantSlug = getTenantSlug()
333
- const response = await client.api.topics[':id'].$delete({
334
- param: { id: topicId.toString() },
335
- headers: { 'X-Tenant-Slug': tenantSlug },
336
- })
337
- const result = await response.json()
338
- return result.success
339
- } catch (error) {
340
- console.error('Failed to delete topic:', error)
341
- return false
342
- }
120
+ updateTodo: async () => {
121
+ console.warn('Tenant routes not registered - tenant module not active')
122
+ return false
343
123
  },
344
124
 
345
- fetchSubscription: async () => {
346
- set({ loading: true })
347
- try {
348
- const client = createTenantClient()
349
- const tenantSlug = getTenantSlug()
350
- const response = await client.api.subscription.$get({
351
- headers: { 'X-Tenant-Slug': tenantSlug },
352
- })
353
- const result = await response.json()
354
-
355
- if (result.success) {
356
- set({ subscription: result.data })
357
- }
358
- } catch (error) {
359
- console.error('Failed to fetch subscription:', error)
360
- } finally {
361
- set({ loading: false })
362
- }
125
+ deleteTodo: async () => {
126
+ console.warn('Tenant routes not registered - tenant module not active')
127
+ return false
363
128
  },
364
129
 
365
- updateTenant: async (tenantId, data) => {
366
- try {
367
- const client = createTenantClient()
368
- const tenantSlug = getTenantSlug()
369
- const response = await client.api.tenants[':id'].$put({
370
- param: { id: tenantId.toString() },
371
- json: data,
372
- headers: { 'X-Tenant-Slug': tenantSlug },
373
- })
374
- const result = await response.json()
375
-
376
- if (result.success) {
377
- set({ currentTenant: result.data })
378
- }
130
+ fetchTopics: async () => {
131
+ console.warn('Tenant routes not registered - tenant module not active')
132
+ },
379
133
 
380
- return result.success
381
- } catch (error) {
382
- console.error('Failed to update tenant:', error)
383
- return false
384
- }
134
+ updateTenant: async () => {
135
+ console.warn('Tenant routes not registered - tenant module not active')
136
+ return false
385
137
  },
386
138
 
387
139
  fetchStats: async () => {
388
- try {
389
- const client = createTenantClient()
390
- const tenantSlug = getTenantSlug()
391
- const response = await client.api.stats.$get({
392
- headers: { 'X-Tenant-Slug': tenantSlug },
393
- })
394
- const result = await response.json()
395
-
396
- if (result.success) {
397
- set({ stats: result.data })
398
- }
399
- } catch (error) {
400
- console.error('Failed to fetch stats:', error)
401
- }
140
+ console.warn('Stats endpoint not implemented for tenant module')
402
141
  },
403
142
 
404
143
  startLoading: (_text?: string) => {
@@ -28,6 +28,7 @@
28
28
  "@client/*": ["./src/client/*"],
29
29
  "@server/*": ["src/server/*"],
30
30
  "@admin/*": ["./src/admin/*"],
31
+ "@cli/*": ["./src/cli/*"],
31
32
  "@tenant/*": ["./src/tenant/*"],
32
33
  "@merchant/*": ["./src/merchant/*"]
33
34
  }
@@ -1,8 +1,10 @@
1
- import { defineConfig } from 'tsup'
1
+ import { defineConfig, type Options } from 'tsup'
2
2
  import { existsSync } from 'fs'
3
- import { join } from 'path'
3
+ import { join, resolve } from 'path'
4
4
 
5
- const serverBuildConfigs = [
5
+ const root = process.cwd()
6
+
7
+ const serverBuildConfigs: Options[] = [
6
8
  {
7
9
  entry: ['src/server/entries/node.ts'],
8
10
  outDir: 'dist/server',
@@ -89,6 +91,12 @@ if (existsSync(cliEntryPath)) {
89
91
  treeshake: true,
90
92
  dts: true,
91
93
  external: ['hono', 'hono/client', 'commander', 'chalk', 'eslint'],
94
+ esbuildOptions(options) {
95
+ // Resolve @cli/* path aliases for CLI build
96
+ options.alias = {
97
+ '@cli': resolve(root, 'src/cli'),
98
+ }
99
+ },
92
100
  })
93
101
  }
94
102
 
@@ -1 +0,0 @@
1
- import{o as g,r,j as e,L as c}from"./index-1bA-ixFv.js";import{b as y,H as b}from"./main-DHnArIp_.js";const v=()=>{var d,m;const{id:n}=g(),[t,h]=r.useState(null),[u,i]=r.useState(!0),[o,a]=r.useState(null),x=r.useCallback(async s=>{i(!0),a(null);try{const l=await y.api.public.contents[":id"].$get({param:{id:s}});if(!l.ok){l.status===404?a("内容不存在"):a("加载失败");return}const p=await l.json();p.success?h(p.data??null):a("Failed to fetch content")}catch{a("Network error")}finally{i(!1)}},[]);r.useEffect(()=>{n&&x(n)},[n,x]);const j=s=>s?new Date(s).toLocaleDateString("zh-CN",{year:"numeric",month:"long",day:"numeric"}):"";return u?e.jsx("div",{className:"max-w-4xl mx-auto p-6",children:e.jsx("div",{className:"text-center py-12 text-gray-500",children:"加载中..."})}):o||!t?e.jsx("div",{className:"max-w-4xl mx-auto p-6",children:e.jsxs("div",{className:"text-center py-12",children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-4",children:o||"内容不存在"}),e.jsx(c,{to:"/content",className:"text-blue-600 hover:underline",children:"← 返回内容列表"})]})}):e.jsxs(e.Fragment,{children:[e.jsxs(b,{children:[e.jsxs("title",{children:[t.title," - Biomimic App"]}),e.jsx("meta",{name:"description",content:t.content.slice(0,160)}),e.jsx("meta",{property:"og:title",content:t.title}),e.jsx("meta",{property:"og:description",content:t.content.slice(0,200)}),e.jsx("meta",{property:"og:type",content:"article"}),t.publishedAt&&e.jsx("meta",{property:"article:published_time",content:t.publishedAt}),t.author&&e.jsx("meta",{property:"article:author",content:t.author}),(d=t.tags)==null?void 0:d.map(s=>e.jsx("meta",{property:"article:tag",content:s},s))]}),e.jsxs("div",{className:"max-w-4xl mx-auto p-6","data-testid":"content-detail-page",children:[e.jsxs("nav",{className:"mb-6 text-sm text-gray-500",children:[e.jsx(c,{to:"/content",className:"hover:text-blue-600",children:"内容中心"}),e.jsx("span",{className:"mx-2",children:"/"}),e.jsx("span",{className:"text-gray-900",children:t.category})]}),e.jsxs("article",{className:"bg-white rounded-xl border border-gray-200 p-8",children:[e.jsxs("header",{className:"mb-8 pb-6 border-b border-gray-100",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx("span",{className:"px-3 py-1 bg-blue-100 text-blue-700 text-sm font-medium rounded-full",children:t.category}),(m=t.tags)==null?void 0:m.map(s=>e.jsx("span",{className:"px-2 py-1 bg-gray-100 text-gray-600 text-xs rounded",children:s},s))]}),e.jsx("h1",{className:"text-3xl font-bold text-gray-900 mb-4",children:t.title}),e.jsxs("div",{className:"flex items-center gap-4 text-sm text-gray-500",children:[t.author&&e.jsxs("span",{children:["✍ ",t.author]}),t.publishedAt&&e.jsxs("span",{children:["📅 ",j(t.publishedAt)]}),e.jsxs("span",{children:["👁 ",t.viewCount," 阅读"]}),e.jsxs("span",{children:["❤ ",t.likeCount," 喜欢"]})]})]}),e.jsx("div",{className:"prose prose-gray max-w-none",children:e.jsx("div",{className:"whitespace-pre-wrap text-gray-700 leading-relaxed",children:t.content})})]}),e.jsx("div",{className:"mt-6",children:e.jsx(c,{to:"/content",className:"text-blue-600 hover:underline",children:"← 返回内容列表"})})]})]})};export{v as ContentDetailPage};
@@ -1 +0,0 @@
1
- import{r as s,j as e,L as f}from"./index-1bA-ixFv.js";import{b as v,H as N}from"./main-DHnArIp_.js";const m=[{value:"",label:"全部"},{value:"article",label:"文章"},{value:"announcement",label:"公告"},{value:"tutorial",label:"教程"},{value:"news",label:"新闻"},{value:"policy",label:"政策"}],S=()=>{const[n,u]=s.useState([]),[i,x]=s.useState(!0),[o,c]=s.useState(null),[l,p]=s.useState(""),[r,h]=s.useState(""),d=s.useCallback(async()=>{x(!0),c(null);try{const a=await(await v.api.public.contents.$get({query:{...l?{category:l}:{},...r?{search:r}:{},limit:20}})).json();a.success?u(a.data):c("Failed to fetch contents")}catch{c("Network error")}finally{x(!1)}},[l,r]);s.useEffect(()=>{d()},[d]);const b=t=>{t.preventDefault(),d()},g=t=>{var a;return((a=m.find(y=>y.value===t))==null?void 0:a.label)??t},j=t=>t?new Date(t).toLocaleDateString("zh-CN",{year:"numeric",month:"long",day:"numeric"}):"";return e.jsxs(e.Fragment,{children:[e.jsxs(N,{children:[e.jsx("title",{children:"内容 - Biomimic App"}),e.jsx("meta",{name:"description",content:"浏览最新的文章、公告、教程和新闻"}),e.jsx("meta",{property:"og:title",content:"内容 - Biomimic App"}),e.jsx("meta",{property:"og:description",content:"浏览最新的文章、公告、教程和新闻"})]}),e.jsxs("div",{className:"max-w-4xl mx-auto p-6","data-testid":"content-list-page",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-3xl font-bold text-gray-900",children:"内容中心"}),e.jsx("p",{className:"mt-2 text-gray-600",children:"浏览最新的文章、公告、教程和新闻"})]}),e.jsxs("div",{className:"mb-6 flex flex-col sm:flex-row gap-4",children:[e.jsx("div",{className:"flex gap-2 flex-wrap",children:m.map(t=>e.jsx("button",{onClick:()=>p(t.value),className:`px-4 py-2 rounded-full text-sm font-medium transition-colors ${l===t.value?"bg-blue-600 text-white":"bg-gray-100 text-gray-700 hover:bg-gray-200"}`,children:t.label},t.value))}),e.jsxs("form",{onSubmit:b,className:"flex gap-2 sm:ml-auto",children:[e.jsx("input",{type:"text",value:r,onChange:t=>h(t.target.value),placeholder:"搜索内容...",className:"px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"}),e.jsx("button",{type:"submit",className:"px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors",children:"搜索"})]})]}),o&&e.jsx("div",{className:"mb-4 p-4 bg-red-50 border border-red-200 rounded-lg text-red-700",children:o}),i&&e.jsx("div",{className:"text-center py-12 text-gray-500",children:"加载中..."}),!i&&!o&&n.length===0&&e.jsx("div",{className:"text-center py-12 text-gray-500",children:"暂无内容"}),!i&&n.length>0&&e.jsx("div",{className:"space-y-4",children:n.map(t=>e.jsx(f,{to:`/content/${t.id}`,className:"block p-6 bg-white rounded-xl border border-gray-200 hover:border-blue-300 hover:shadow-md transition-all",children:e.jsx("div",{className:"flex items-start justify-between gap-4",children:e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx("span",{className:"px-2 py-1 bg-blue-100 text-blue-700 text-xs font-medium rounded",children:g(t.category)}),e.jsx("span",{className:"text-sm text-gray-500",children:t.author})]}),e.jsx("h2",{className:"text-xl font-semibold text-gray-900 mb-2",children:t.title}),e.jsxs("p",{className:"text-gray-600 line-clamp-2",children:[t.content.slice(0,150),"..."]}),e.jsxs("div",{className:"flex items-center gap-4 mt-3 text-sm text-gray-400",children:[t.publishedAt&&e.jsx("span",{children:j(t.publishedAt)}),e.jsxs("span",{children:["👁 ",t.viewCount]}),e.jsxs("span",{children:["❤ ",t.likeCount]})]})]})})},t.id))})]})]})};export{S as ContentListPage};
@@ -1,11 +0,0 @@
1
- import{c as i,r as a,j as e,T as f}from"./index-1bA-ixFv.js";import{H as N,b as v}from"./main-DHnArIp_.js";import{L as w}from"./LoadingSpinner-DVYOLSRM.js";import{C as S}from"./chevron-down-DwRh_wjD.js";/**
2
- * @license lucide-react v0.576.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const k=[["path",{d:"M7 7h10v10",key:"1tivn9"}],["path",{d:"M7 17 17 7",key:"1vkiza"}]],$=i("arrow-up-right",k);/**
7
- * @license lucide-react v0.576.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const D=[["path",{d:"M16 17h6v-6",key:"t6n2it"}],["path",{d:"m22 17-8.5-8.5-5 5L2 7",key:"x473p"}]],L=i("trending-down",D),R={Active:"bg-green-100 text-green-700",Pending:"bg-yellow-100 text-yellow-700",Inactive:"bg-gray-100 text-gray-600"},A=["Last 7 days","Last 30 days","Last 90 days","Last year"],_=()=>{const[r,c]=a.useState("Last 30 days"),[l,d]=a.useState(!1),[x,o]=a.useState(!0),[m,h]=a.useState([]),[g,p]=a.useState([]),[b,u]=a.useState([]),[y,j]=a.useState([]);return a.useEffect(()=>{async function s(){try{const t=await(await v.api.admin.dashboard.stats.$get()).json();t.success&&(h(t.data.stats),p(t.data.revenue),u(t.data.userGrowth),j(t.data.activity))}finally{o(!1)}}s()},[]),x?e.jsx("div",{className:"flex items-center justify-center min-h-screen","data-testid":"dashboard-loading",children:e.jsx(w,{size:"lg"})}):e.jsxs("div",{className:"min-h-screen bg-gray-50 p-4 sm:p-6 lg:p-8","data-testid":"dashboard-page",children:[e.jsxs(N,{children:[e.jsx("title",{children:"Dashboard - SaaS Admin"}),e.jsx("meta",{name:"description",content:"SaaS Admin Dashboard"})]}),e.jsxs("div",{className:"max-w-7xl mx-auto",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-8 gap-4",children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold text-gray-900",children:"Dashboard"}),e.jsxs("div",{className:"relative",children:[e.jsxs("button",{onClick:()=>d(!l),"data-testid":"time-range-dropdown",className:"flex items-center gap-2 px-4 py-2 bg-white border border-gray-200 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors",children:[r,e.jsx(S,{className:"w-4 h-4"})]}),l&&e.jsx("div",{className:"absolute right-0 mt-1 w-44 bg-white border border-gray-200 rounded-lg shadow-lg z-10",children:A.map(s=>e.jsx("button",{onClick:()=>{c(s),d(!1)},"data-testid":`time-range-${s.toLowerCase().replace(/\s+/g,"-")}`,className:`block w-full text-left px-4 py-2 text-sm transition-colors first:rounded-t-lg last:rounded-b-lg ${s===r?"bg-gray-100 text-gray-900 font-medium":"text-gray-600 hover:bg-gray-50"}`,children:s},s))})]})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6 mb-8",children:m.map(s=>{const n=s.icon,t=s.trend>=0;return e.jsxs("div",{"data-testid":`stat-card-${s.label.toLowerCase().replace(/\s+/g,"-")}`,className:"bg-white rounded-lg border border-gray-200 p-5 hover:shadow-sm transition-shadow",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("span",{className:"text-sm font-medium text-gray-500",children:s.label}),e.jsx("div",{className:"p-2 bg-gray-100 rounded-lg",children:e.jsx(n,{className:"w-4 h-4 text-gray-600"})})]}),e.jsx("div",{className:"text-2xl font-bold text-gray-900 mb-1",children:s.value}),e.jsxs("div",{className:"flex items-center gap-1",children:[t?e.jsx(f,{className:"w-3 h-3 text-green-500"}):e.jsx(L,{className:"w-3 h-3 text-red-500"}),e.jsxs("span",{className:`text-sm font-medium ${t?"text-green-600":"text-red-600"}`,children:[t?"+":"",s.trend,"%"]}),e.jsx("span",{className:"text-xs text-gray-400 ml-1",children:"vs last period"})]})]},s.label)})}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6 mb-8",children:[e.jsxs("div",{className:"bg-white rounded-lg border border-gray-200 p-5 sm:p-6","data-testid":"revenue-chart",children:[e.jsx("h2",{className:"text-base font-semibold text-gray-900 mb-6",children:"Revenue Overview"}),e.jsx("div",{className:"flex items-end gap-3 h-48",children:g.map(s=>e.jsxs("div",{className:"flex-1 flex flex-col items-center gap-2",children:[e.jsxs("div",{className:"w-full flex flex-col items-center",children:[e.jsxs("span",{className:"text-xs text-gray-500 mb-1",children:["$",s.value,"k"]}),e.jsx("div",{className:"w-full rounded-t-md bg-gray-800 transition-all hover:bg-gray-700",style:{height:`${s.value/100*160}px`}})]}),e.jsx("span",{className:"text-xs text-gray-500",children:s.month})]},s.month))})]}),e.jsxs("div",{className:"bg-white rounded-lg border border-gray-200 p-5 sm:p-6","data-testid":"user-growth-chart",children:[e.jsx("h2",{className:"text-base font-semibold text-gray-900 mb-6",children:"User Growth"}),e.jsx("div",{className:"flex items-end gap-3 h-48",children:b.map(s=>e.jsxs("div",{className:"flex-1 flex flex-col items-center gap-2",children:[e.jsxs("div",{className:"w-full flex flex-col items-center",children:[e.jsxs("span",{className:"text-xs text-gray-500 mb-1",children:[s.value,"%"]}),e.jsx("div",{className:"w-full rounded-t-md transition-all",style:{height:`${s.value/100*160}px`,background:`linear-gradient(to top, #1f2937 ${s.value}%, #e5e7eb ${s.value}%)`}})]}),e.jsx("span",{className:"text-xs text-gray-500",children:s.month})]},s.month))})]})]}),e.jsxs("div",{className:"bg-white rounded-lg border border-gray-200 overflow-hidden","data-testid":"recent-activity",children:[e.jsxs("div",{className:"px-5 sm:px-6 py-4 border-b border-gray-100 flex items-center justify-between",children:[e.jsx("h2",{className:"text-base font-semibold text-gray-900",children:"Recent Activity"}),e.jsxs("button",{"data-testid":"view-all-activity",className:"flex items-center gap-1 text-sm font-medium text-gray-600 hover:text-gray-900 transition-colors",children:["View all",e.jsx($,{className:"w-3.5 h-3.5"})]})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-gray-100",children:[e.jsx("th",{className:"text-left px-5 sm:px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider",children:"User"}),e.jsx("th",{className:"text-left px-5 sm:px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Action"}),e.jsx("th",{className:"text-left px-5 sm:px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider hidden sm:table-cell",children:"Date"}),e.jsx("th",{className:"text-left px-5 sm:px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Status"})]})}),e.jsx("tbody",{children:y.map(s=>e.jsxs("tr",{"data-testid":`activity-row-${s.id}`,className:"border-b border-gray-50 last:border-0 hover:bg-gray-50 transition-colors",children:[e.jsx("td",{className:"px-5 sm:px-6 py-4",children:e.jsx("span",{className:"text-sm font-medium text-gray-900",children:s.user})}),e.jsx("td",{className:"px-5 sm:px-6 py-4",children:e.jsx("span",{className:"text-sm text-gray-600",children:s.action})}),e.jsx("td",{className:"px-5 sm:px-6 py-4 hidden sm:table-cell",children:e.jsx("span",{className:"text-sm text-gray-500",children:s.date})}),e.jsx("td",{className:"px-5 sm:px-6 py-4",children:e.jsx("span",{"data-testid":`status-badge-${s.id}`,className:`inline-flex items-center px-2.5 py-0.5 rounded-md text-xs font-medium ${R[s.status]}`,children:s.status})})]},s.id))})]})})]})]})]})};export{_ as DashboardPage};
@@ -1,6 +0,0 @@
1
- import{c as t,j as n}from"./index-1bA-ixFv.js";/**
2
- * @license lucide-react v0.576.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const o=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],i=t("loader-circle",o),c={sm:"w-4 h-4",md:"w-6 h-6",lg:"w-8 h-8"},d=({size:e="md",color:a="text-blue-500",className:s=""})=>n.jsx(i,{className:`animate-spin ${c[e]} ${a} ${s}`,"data-testid":"loading-spinner"});export{d as L};
@@ -1,6 +0,0 @@
1
- import{c as b,n as f,r as d,j as e,L as y}from"./index-1bA-ixFv.js";import{u as t,a as j,H as w}from"./main-DHnArIp_.js";/**
2
- * @license lucide-react v0.576.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const v=[["path",{d:"m10 17 5-5-5-5",key:"1bsop3"}],["path",{d:"M15 12H3",key:"6jk70r"}],["path",{d:"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4",key:"u53s6r"}]],N=b("log-in",v),m={todo:{email:"demo@biomimic.app",password:"demo123",name:"Demo User"},plugin:{email:"developer@pluginhub.io",password:"dev123",name:"Plugin Developer"},ecommerce:{email:"shopper@shopmart.com",password:"shop123",name:"Shopper"},community:{email:"member@community.dev",password:"member123",name:"Community Member"},saas:{email:"admin@biomimic.app",password:"admin123",name:"Admin"}},L=()=>{const c=f(),u=t(s=>s.login),a=t(s=>s.loading),r=t(s=>s.error),o=t(s=>s.clearError),p=j(),n=m[p]??m.todo,[i,g]=d.useState(n.email),[l,x]=d.useState(n.password),h=async s=>{s.preventDefault(),await u(i,l),t.getState().isAuthenticated&&c("/todos")};return e.jsxs(e.Fragment,{children:[e.jsx(w,{children:e.jsx("title",{children:"Login - Biomimic App"})}),e.jsx("div",{className:"min-h-[calc(100vh-200px)] flex items-center justify-center",children:e.jsx("div",{className:"w-full max-w-md","data-testid":"login-page",children:e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-200 p-8",children:[e.jsxs("div",{className:"text-center mb-6",children:[e.jsx("div",{className:"inline-flex items-center justify-center w-12 h-12 bg-blue-100 rounded-full mb-3",children:e.jsx(N,{className:"w-6 h-6 text-blue-600"})}),e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"Welcome Back"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Sign in to your account"})]}),e.jsxs("form",{onSubmit:h,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"username",className:"block text-sm font-medium text-gray-700 mb-1",children:"Username"}),e.jsx("input",{id:"username",type:"text",value:i,onChange:s=>{g(s.target.value),r&&o()},placeholder:"Enter your username",required:!0,"data-testid":"login-username",className:"w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"password",className:"block text-sm font-medium text-gray-700 mb-1",children:"Password"}),e.jsx("input",{id:"password",type:"password",value:l,onChange:s=>{x(s.target.value),r&&o()},placeholder:"Enter your password",required:!0,"data-testid":"login-password",className:"w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"})]}),r&&e.jsx("div",{className:"text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg px-3 py-2","data-testid":"login-error",children:r}),e.jsx("button",{type:"submit",disabled:a,"data-testid":"login-submit",className:"w-full py-2 px-4 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:a?"Signing in...":"Sign In"})]}),e.jsxs("p",{className:"mt-4 text-center text-sm text-gray-500",children:["Don't have an account?"," ",e.jsx(y,{to:"/register",className:"text-blue-600 hover:text-blue-700 font-medium","data-testid":"login-register-link",children:"Sign up"})]})]})})})]})};export{L as LoginPage};
@@ -1 +0,0 @@
1
- import{a as U,r as p,j as e,B as j}from"./index-1bA-ixFv.js";import{b as c,H as T}from"./main-DHnArIp_.js";import{S as D}from"./StatusBadge-BJ3W2Zc7.js";import{L as F}from"./LoadingSpinner-DVYOLSRM.js";import{E as M}from"./EmptyState-BK7ttK8D.js";import{W as N,a as w,S as I}from"./wifi-BwXjnCqI.js";import{C,T as W,I as H}from"./triangle-alert-D1CLh-Vd.js";import{C as L}from"./circle-x-CYxr4RAw.js";import{C as z}from"./circle-check-big-CSElLscG.js";import{T as O}from"./trash-2-DRblNbnA.js";let m=null;const l=U(a=>({notifications:[],unreadCount:0,loading:!1,error:null,sseConnected:!1,fetchNotifications:async(r=!1)=>{a({loading:!0,error:null});try{const n=await(await c.api.notifications.$get({query:{unreadOnly:String(r)}})).json();n.success?a({notifications:n.data.items,loading:!1}):a({error:n.error,loading:!1})}catch(t){a({error:t instanceof Error?t.message:"Unknown error",loading:!1})}},createNotification:async r=>{a({loading:!0,error:null});try{const n=await(await c.api.notifications.$post({json:r})).json();n.success?a(o=>({notifications:[n.data,...o.notifications],unreadCount:o.unreadCount+1,loading:!1})):a({error:n.error,loading:!1})}catch(t){a({error:t instanceof Error?t.message:"Unknown error",loading:!1})}},markAsRead:async r=>{try{(await(await c.api.notifications[":id"].read.$patch({param:{id:r}})).json()).success&&a(o=>({notifications:o.notifications.map(i=>i.id===r?{...i,read:!0}:i),unreadCount:Math.max(0,o.unreadCount-1)}))}catch(t){console.error("Failed to mark as read:",t),a({error:t instanceof Error?t.message:"Unknown error"})}},markAllAsRead:async()=>{try{(await(await c.api.notifications["read-all"].$patch()).json()).success&&a(n=>({notifications:n.notifications.map(o=>({...o,read:!0})),unreadCount:0}))}catch(r){console.error("Failed to mark all as read:",r),a({error:r instanceof Error?r.message:"Unknown error"})}},deleteNotification:async r=>{try{(await(await c.api.notifications[":id"].$delete({param:{id:r}})).json()).success&&a(o=>{const i=o.notifications.find(d=>d.id===r);return{notifications:o.notifications.filter(d=>d.id!==r),unreadCount:i&&!i.read?o.unreadCount-1:o.unreadCount}})}catch(t){console.error("Failed to delete:",t),a({error:t instanceof Error?t.message:"Unknown error"})}},fetchUnreadCount:async()=>{try{const t=await(await c.api.notifications["unread-count"].$get()).json();t.success&&a({unreadCount:t.data.count})}catch(r){console.error("Failed to fetch unread count:",r),a({error:r instanceof Error?r.message:"Unknown error"})}},connectSSE:async()=>{if(!m)try{const r=c.api.notifications.stream.$sse();r.onStatusChange(t=>{a({sseConnected:t==="open"})}),r.on("connected",t=>{}),r.on("notification",t=>{a(n=>n.notifications.some(o=>o.id===t.id)?n:{notifications:[t,...n.notifications],unreadCount:t.read?n.unreadCount:n.unreadCount+1})}),r.onError(t=>{console.error("[SSE] Error:",t)}),m=r}catch(r){console.error("[SSE] Failed to connect:",r)}},disconnectSSE:()=>{m&&(m.abort(),m=null,a({sseConnected:!1}))}})),_=()=>{const a=l(s=>s.notifications),r=l(s=>s.unreadCount),t=l(s=>s.sseConnected),n=l(s=>s.loading),o=l(s=>s.error),{fetchNotifications:i,createNotification:d,markAsRead:S,markAllAsRead:v,deleteNotification:k,connectSSE:E,disconnectSSE:A}=l(),[u,x]=p.useState(""),[f,h]=p.useState(""),[b,$]=p.useState("info");p.useEffect(()=>{i()},[i]);const B=async s=>{s.preventDefault(),!(!u.trim()||!f.trim())&&(await d({type:b,title:u,message:f}),x(""),h(""))},y={info:{icon:H,colorScheme:"blue",border:"border-blue-400",lightBg:"bg-blue-50"},warning:{icon:W,colorScheme:"yellow",border:"border-yellow-400",lightBg:"bg-yellow-50"},success:{icon:z,colorScheme:"green",border:"border-green-400",lightBg:"bg-green-50"},error:{icon:L,colorScheme:"red",border:"border-red-400",lightBg:"bg-red-50"}};return e.jsxs("div",{className:"max-w-3xl mx-auto p-6","data-testid":"notification-container",children:[e.jsxs(T,{children:[e.jsx("title",{children:"Notifications - Biomimic App"}),e.jsx("meta",{name:"description",content:"Real-time notifications powered by Server-Sent Events"}),e.jsx("meta",{property:"og:title",content:"Notifications - Biomimic App"}),e.jsx("meta",{property:"og:description",content:"Real-time notifications powered by Server-Sent Events"})]}),e.jsxs("div",{className:"mb-8",children:[e.jsxs("h1",{className:"text-3xl font-bold text-gray-900 flex items-center gap-2",children:[e.jsx(j,{className:"w-8 h-8 text-purple-500"}),"Notifications"]}),e.jsx("p",{className:"text-gray-500 mt-2",children:"Demonstrates SSE (Server-Sent Events) with Hono RPC type inference"})]}),e.jsxs("div",{className:"mb-6 p-4 bg-white rounded-xl shadow-sm border border-gray-200 flex flex-wrap items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-6",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"SSE Status:"}),t?e.jsxs("span",{className:"flex items-center gap-1 text-green-600","data-testid":"sse-status-connected",children:[e.jsx(N,{className:"w-4 h-4"}),"Connected"]}):e.jsxs("span",{className:"flex items-center gap-1 text-red-500","data-testid":"sse-status-disconnected",children:[e.jsx(w,{className:"w-4 h-4"}),"Disconnected"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"Unread:"}),e.jsx("span",{className:"px-2.5 py-0.5 bg-blue-500 text-white text-sm font-medium rounded-full","data-testid":"unread-count",children:r})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:E,disabled:t,className:`flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium transition-colors ${t?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-green-500 text-white hover:bg-green-600"}`,"data-testid":"connect-sse-button",children:[e.jsx(N,{className:"w-4 h-4"}),"Connect"]}),e.jsxs("button",{onClick:A,disabled:!t,className:`flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium transition-colors ${t?"bg-red-500 text-white hover:bg-red-600":"bg-gray-100 text-gray-400 cursor-not-allowed"}`,"data-testid":"disconnect-sse-button",children:[e.jsx(w,{className:"w-4 h-4"}),"Disconnect"]}),e.jsxs("button",{onClick:v,className:"flex items-center gap-1.5 px-4 py-2 bg-gray-500 text-white rounded-lg text-sm font-medium hover:bg-gray-600 transition-colors","data-testid":"mark-all-read-button",children:[e.jsx(C,{className:"w-4 h-4"}),"Mark All Read"]})]})]}),e.jsxs("form",{onSubmit:B,className:"mb-8 p-6 bg-white rounded-xl shadow-sm border border-gray-200",children:[e.jsxs("div",{className:"flex gap-4 mb-4",children:[e.jsxs("select",{value:b,onChange:s=>$(s.target.value),className:"px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 outline-none","data-testid":"notification-type-select",children:[e.jsx("option",{value:"info",children:"Info"}),e.jsx("option",{value:"warning",children:"Warning"}),e.jsx("option",{value:"success",children:"Success"}),e.jsx("option",{value:"error",children:"Error"})]}),e.jsx("input",{type:"text",value:u,onChange:s=>x(s.target.value),placeholder:"Title...",className:"flex-1 px-4 py-3 text-base border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent outline-none","data-testid":"notification-title-input"})]}),e.jsx("div",{className:"mb-4",children:e.jsx("textarea",{value:f,onChange:s=>h(s.target.value),placeholder:"Message...",className:"w-full px-4 py-3 text-base border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent outline-none resize-none min-h-[100px]","data-testid":"notification-message-input"})}),e.jsxs("button",{type:"submit",disabled:!u.trim()||!f.trim()||n,className:"flex items-center gap-2 px-6 py-3 text-base font-medium text-white bg-purple-500 rounded-lg hover:bg-purple-600 disabled:bg-gray-300 disabled:cursor-not-allowed transition-colors","data-testid":"create-notification-button",children:[n?e.jsx(F,{size:"sm",color:"text-white"}):e.jsx(I,{className:"w-5 h-5"}),"Create Notification"]})]}),o&&e.jsx("div",{className:"mb-6 p-4 bg-red-50 border border-red-200 text-red-700 rounded-lg",children:o}),e.jsx("div",{className:"space-y-4",children:a.map(s=>{const g=y[s.type]??y.info,R=g.icon;return e.jsx("div",{className:`p-5 rounded-xl border-l-4 transition-all ${s.read?"bg-gray-50 border-gray-200":"bg-white border-gray-200 shadow-sm"} ${g.border}`,"data-testid":s.read?"notification-item-read":"notification-item-unread",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(D,{label:s.type.toUpperCase(),icon:R,colorScheme:g.colorScheme}),e.jsx("span",{className:"font-medium text-gray-900","data-testid":"notification-title",children:s.title})]}),e.jsx("p",{className:"text-gray-600 text-sm","data-testid":"notification-message",children:s.message}),e.jsx("span",{className:"text-xs text-gray-400 mt-2 block",children:new Date(s.createdAt).toLocaleString()})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[!s.read&&e.jsx("button",{onClick:()=>S(s.id),className:"p-2 text-gray-400 hover:text-blue-500 hover:bg-blue-50 rounded-lg transition-colors",title:"Mark as read","data-testid":"mark-as-read-button",children:e.jsx(C,{className:"w-5 h-5"})}),e.jsx("button",{onClick:()=>k(s.id),className:"p-2 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded-lg transition-colors","data-testid":"delete-notification-button",children:e.jsx(O,{className:"w-5 h-5"})})]})]})},s.id)})}),!n&&a.length===0&&e.jsx(M,{icon:j,title:"No notifications yet. Create one above!",className:"py-12"})]})};export{_ as NotificationPage};
@@ -1,11 +0,0 @@
1
- import{c as o,r,j as e}from"./index-1bA-ixFv.js";import{H as u,c as b,P as y,b as f}from"./main-DHnArIp_.js";import{L as j}from"./LoadingSpinner-DVYOLSRM.js";import{C as N}from"./circle-x-CYxr4RAw.js";import{C as v}from"./circle-check-big-CSElLscG.js";import{C as w}from"./clock-BseUJ7ex.js";/**
2
- * @license lucide-react v0.576.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const k=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],$=o("rotate-ccw",k);/**
7
- * @license lucide-react v0.576.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const C=[["path",{d:"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2",key:"wrbu53"}],["path",{d:"M15 18H9",key:"1lyqi6"}],["path",{d:"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14",key:"lysw3i"}],["circle",{cx:"17",cy:"18",r:"2",key:"332jqn"}],["circle",{cx:"7",cy:"18",r:"2",key:"19iecd"}]],x=o("truck",C),S={processing:{label:"Processing",icon:w,bg:"bg-amber-100",text:"text-amber-700"},shipped:{label:"Shipped",icon:x,bg:"bg-blue-100",text:"text-blue-700"},delivered:{label:"Delivered",icon:v,bg:"bg-green-100",text:"text-green-700"},cancelled:{label:"Cancelled",icon:N,bg:"bg-red-100",text:"text-red-700"}},O=[{value:"all",label:"All"},{value:"processing",label:"Processing"},{value:"shipped",label:"Shipped"},{value:"delivered",label:"Delivered"},{value:"cancelled",label:"Cancelled"}],F=()=>{const[l,m]=r.useState("all"),[i,g]=r.useState([]),[p,h]=r.useState(!0);r.useEffect(()=>{async function t(){try{const a=await(await f.api.orders.$get()).json();a.success&&g(a.data.orders)}finally{h(!1)}}t()},[]);const d=l==="all"?i:i.filter(t=>t.status===l);return p?e.jsx("div",{className:"flex items-center justify-center py-20","data-testid":"orders-loading",children:e.jsx(j,{size:"lg"})}):e.jsxs("div",{className:"max-w-4xl mx-auto p-4 sm:p-6","data-testid":"orders-page",children:[e.jsxs(u,{children:[e.jsx("title",{children:"Order History - Biomimic App"}),e.jsx("meta",{name:"description",content:"View your order history and track shipments"})]}),e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-3xl font-bold text-gray-900","data-testid":"orders-title",children:"Order History"}),e.jsxs("p",{className:"text-gray-500 mt-2",children:[i.length," orders placed"]})]}),e.jsx("div",{className:"flex flex-wrap gap-2 mb-6","data-testid":"orders-filters",children:O.map(t=>e.jsx("button",{onClick:()=>m(t.value),className:`px-4 py-2 text-sm font-medium rounded-xl transition-colors ${l===t.value?"bg-amber-500 text-white":"bg-white text-gray-600 border border-gray-200 hover:bg-gray-50"}`,"data-testid":`orders-filter-${t.value}`,children:t.label},t.value))}),d.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-20","data-testid":"orders-empty",children:[e.jsx("div",{className:"w-20 h-20 rounded-full bg-gray-100 flex items-center justify-center mb-6",children:e.jsx(b,{className:"w-10 h-10 text-gray-400"})}),e.jsx("h2",{className:"text-xl font-semibold text-gray-900 mb-2",children:"No orders found"}),e.jsx("p",{className:"text-gray-500",children:"No orders match the selected filter."})]}):e.jsx("div",{className:"space-y-4","data-testid":"orders-list",children:d.map(t=>{const s=S[t.status],a=s.icon;return e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 shadow-sm p-5","data-testid":`order-card-${t.id}`,children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h3",{className:"font-semibold text-gray-900","data-testid":`order-id-${t.id}`,children:t.id}),e.jsxs("span",{className:`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-medium ${s.bg} ${s.text}`,"data-testid":`order-status-${t.id}`,children:[e.jsx(a,{className:"w-3.5 h-3.5"}),s.label]})]}),e.jsx("p",{className:"text-sm text-gray-500 mt-0.5","data-testid":`order-date-${t.id}`,children:new Date(t.date).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})})]}),e.jsxs("p",{className:"text-lg font-bold text-gray-900","data-testid":`order-total-${t.id}`,children:["$",t.total.toFixed(2)]})]}),e.jsx("div",{className:"flex items-center gap-2 mb-4","data-testid":`order-products-${t.id}`,children:t.products.map((c,n)=>e.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-gray-50 rounded-lg","data-testid":`order-product-${t.id}-${n}`,children:[e.jsx("div",{className:"w-6 h-6 rounded-md flex items-center justify-center flex-shrink-0",style:{backgroundColor:c.color},children:e.jsx(y,{className:"w-3 h-3 text-white/70"})}),e.jsx("span",{className:"text-sm text-gray-700 truncate max-w-[120px] sm:max-w-[200px]",children:c.name})]},n))}),e.jsxs("div",{className:"flex items-center gap-3 pt-3 border-t border-gray-100",children:[(t.status==="shipped"||t.status==="processing")&&e.jsxs("button",{className:"flex items-center gap-1.5 px-4 py-2 text-sm font-medium text-amber-600 bg-amber-50 rounded-xl hover:bg-amber-100 transition-colors","data-testid":`order-track-${t.id}`,children:[e.jsx(x,{className:"w-4 h-4"}),"Track Order"]}),e.jsxs("button",{className:"flex items-center gap-1.5 px-4 py-2 text-sm font-medium text-gray-600 bg-gray-50 rounded-xl hover:bg-gray-100 transition-colors","data-testid":`order-reorder-${t.id}`,children:[e.jsx($,{className:"w-4 h-4"}),"Reorder"]})]})]},t.id)})})]})};export{F as OrdersPage};
@@ -1,6 +0,0 @@
1
- import{c as u,r as h,j as e,L as n,T as f}from"./index-1bA-ixFv.js";import{H as v,P as g,S as j}from"./main-DHnArIp_.js";import{u as t}from"./pluginStore-XQfsm3iR.js";import{S as N}from"./StatusBadge-BJ3W2Zc7.js";import{L as w}from"./LoadingSpinner-DVYOLSRM.js";import{E as y}from"./EmptyState-BK7ttK8D.js";import{D as k}from"./download-BsGC_Xhq.js";import{T as C}from"./tag-DsiUPF90.js";import{C as P,a as S}from"./chevron-right-CpIWaqAL.js";/**
2
- * @license lucide-react v0.576.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const E=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],L=u("zap",E),U=()=>{const l=t(s=>s.plugins),p=t(s=>s.loading),d=t(s=>s.error),b=t(s=>s.categories),i=t(s=>s.selectedCategory),a=t(s=>s.pagination),r=t(s=>s.fetchPlugins),c=t(s=>s.fetchCategories),x=t(s=>s.setSelectedCategory);h.useEffect(()=>{r(1),c()},[r,c]),h.useEffect(()=>{r(1)},[i,r]);const o=Math.ceil(a.total/a.limit);return e.jsxs("div",{className:"min-h-screen","data-testid":"plugins-page",children:[e.jsxs(v,{children:[e.jsx("title",{children:"Plugin Marketplace - Biomimic App"}),e.jsx("meta",{name:"description",content:"Browse and discover plugins for your application"})]}),e.jsx("div",{className:"bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 pt-12 pb-16 px-6",children:e.jsxs("div",{className:"max-w-6xl mx-auto",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx("div",{className:"p-2.5 bg-gradient-to-br from-violet-500 to-fuchsia-500 rounded-xl shadow-lg shadow-violet-500/25",children:e.jsx(g,{className:"w-6 h-6 text-white"})}),e.jsx("h1",{className:"text-3xl font-bold text-white tracking-tight",children:"Plugin Marketplace"})]}),e.jsx("p",{className:"text-purple-200/70 text-lg max-w-xl",children:"Extend your application with powerful plugins. Browse, install, and publish community-built extensions."}),e.jsxs("div",{className:"mt-6 flex items-center gap-4",children:[e.jsxs(n,{to:"/publish",className:"group flex items-center gap-2 px-5 py-2.5 bg-gradient-to-r from-violet-500 to-fuchsia-500 text-white rounded-xl hover:from-violet-400 hover:to-fuchsia-400 transition-all shadow-lg shadow-violet-500/25 hover:shadow-violet-500/40 text-sm font-semibold",children:[e.jsx(j,{className:"w-4 h-4 group-hover:rotate-12 transition-transform"}),"Publish Plugin"]}),e.jsx(n,{to:"/search",className:"flex items-center gap-2 px-5 py-2.5 bg-white/10 text-white rounded-xl hover:bg-white/20 transition-all text-sm font-medium backdrop-blur-sm border border-white/10",children:"Search Plugins"})]})]})}),e.jsxs("div",{className:"max-w-6xl mx-auto px-6 -mt-8",children:[d&&e.jsx("div",{className:"mb-6 p-4 bg-red-500/10 border border-red-500/20 text-red-300 rounded-2xl backdrop-blur-sm",children:d}),e.jsxs("div",{className:"flex gap-8",children:[e.jsx("aside",{className:"w-60 flex-shrink-0 hidden lg:block",children:e.jsxs("div",{className:"bg-white rounded-2xl shadow-lg shadow-black/5 border border-gray-100 p-4 sticky top-6",children:[e.jsx("h3",{className:"text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3 px-2",children:"Categories"}),e.jsxs("div",{className:"space-y-0.5",children:[e.jsxs("button",{onClick:()=>x(null),className:`w-full text-left px-3 py-2.5 text-sm rounded-xl transition-all flex items-center gap-2 ${i?"text-gray-600 hover:bg-gray-50":"bg-gradient-to-r from-violet-50 to-fuchsia-50 text-violet-700 font-semibold shadow-sm"}`,children:[e.jsx(L,{className:"w-4 h-4"}),"All Plugins"]}),b.map(s=>e.jsxs("button",{onClick:()=>x(s.slug),className:`w-full text-left px-3 py-2.5 text-sm rounded-xl transition-all flex items-center gap-2 ${i===s.slug?"bg-gradient-to-r from-violet-50 to-fuchsia-50 text-violet-700 font-semibold shadow-sm":"text-gray-600 hover:bg-gray-50"}`,children:[e.jsx("span",{className:"text-base",children:s.icon||"📁"}),s.name]},s.id))]})]})}),e.jsx("div",{className:"flex-1 min-w-0",children:p&&l.length===0?e.jsx("div",{className:"flex items-center justify-center py-20",children:e.jsx(w,{size:"lg"})}):l.length===0?e.jsx(y,{icon:g,title:"No plugins found"}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between mb-5",children:[e.jsxs("p",{className:"text-sm text-gray-500",children:[e.jsx("span",{className:"font-semibold text-gray-700",children:a.total})," plugins available"]}),e.jsxs("div",{className:"flex items-center gap-1 text-xs text-gray-400",children:[e.jsx(f,{className:"w-3.5 h-3.5"}),"Sorted by popularity"]})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:l.map(s=>e.jsxs(n,{to:`/plugins/${s.slug}`,className:"group relative p-5 bg-white rounded-2xl border border-gray-100 hover:border-violet-200 hover:shadow-xl hover:shadow-violet-500/5 transition-all duration-300 block overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-violet-500/0 to-fuchsia-500/0 group-hover:from-violet-500/[0.02] group-hover:to-fuchsia-500/[0.04] transition-all duration-300"}),e.jsxs("div",{className:"relative",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-10 h-10 rounded-xl bg-gradient-to-br from-violet-100 to-fuchsia-100 flex items-center justify-center text-lg font-bold text-violet-600 shrink-0",children:s.name.charAt(0).toUpperCase()}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h3",{className:"text-base font-semibold text-gray-900 truncate group-hover:text-violet-700 transition-colors",children:s.name}),e.jsxs("p",{className:"text-xs text-gray-400",children:["by ",s.authorName]})]})]}),e.jsx(N,{label:`v${s.version}`,colorScheme:"purple"})]}),e.jsx("p",{className:"text-sm text-gray-500 line-clamp-2 mb-4 leading-relaxed",children:s.description}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"flex items-center gap-3 text-xs text-gray-400",children:e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(k,{className:"w-3.5 h-3.5"}),s.downloadCount]})}),s.tags&&s.tags.length>0&&e.jsx("div",{className:"flex items-center gap-1",children:s.tags.slice(0,2).map(m=>e.jsxs("span",{className:"inline-flex items-center px-2 py-0.5 bg-gray-50 text-gray-500 rounded-md text-xs",children:[e.jsx(C,{className:"w-2.5 h-2.5 mr-0.5 opacity-50"}),m]},m))})]})]})]},s.id))}),o>1&&e.jsxs("div",{className:"mt-10 flex items-center justify-center gap-3",children:[e.jsx("button",{onClick:()=>r(a.page-1),disabled:a.page<=1,className:"p-2.5 rounded-xl bg-white border border-gray-200 hover:border-violet-300 hover:shadow-md disabled:opacity-30 disabled:cursor-not-allowed transition-all",children:e.jsx(P,{className:"w-5 h-5 text-gray-600"})}),e.jsx("div",{className:"flex items-center gap-1.5 px-4 py-2 bg-white rounded-xl border border-gray-200",children:e.jsxs("span",{className:"text-sm text-gray-600",children:[e.jsx("span",{className:"font-semibold text-gray-900",children:a.page}),e.jsx("span",{className:"mx-1.5 text-gray-300",children:"/"}),o]})}),e.jsx("button",{onClick:()=>r(a.page+1),disabled:a.page>=o,className:"p-2.5 rounded-xl bg-white border border-gray-200 hover:border-violet-300 hover:shadow-md disabled:opacity-30 disabled:cursor-not-allowed transition-all",children:e.jsx(S,{className:"w-5 h-5 text-gray-600"})})]})]})})]})]})]})};export{U as PluginsPage};
@@ -1,16 +0,0 @@
1
- import{c as n,r as a,j as e}from"./index-1bA-ixFv.js";import{H as g,b as j}from"./main-DHnArIp_.js";import{L as v}from"./LoadingSpinner-DVYOLSRM.js";import{M as N}from"./message-square-CwWGL-Bh.js";/**
2
- * @license lucide-react v0.576.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const b=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]],o=n("file-text",b);/**
7
- * @license lucide-react v0.576.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const w=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],k=n("pencil",w);/**
12
- * @license lucide-react v0.576.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const M=[["path",{d:"M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z",key:"emmmcr"}],["path",{d:"M7 10v12",key:"1qc93n"}]],S=n("thumbs-up",M),T={name:"Jane Doe",initials:"JD",joinedDate:"March 2025",bio:"Full-stack developer passionate about real-time web apps, type safety, and building developer tools."},A={topics:0,replies:0,likes:0},L=[{value:"activity",label:"Activity"},{value:"topics",label:"Topics"},{value:"replies",label:"Replies"}],P=s=>{switch(s){case"topic":return e.jsx(o,{className:"w-4 h-4"});case"reply":return e.jsx(N,{className:"w-4 h-4"});case"like":return e.jsx(S,{className:"w-4 h-4"})}},_=s=>{switch(s){case"topic":return"bg-emerald-100 text-emerald-600";case"reply":return"bg-blue-100 text-blue-600";case"like":return"bg-rose-100 text-rose-500"}},C=()=>{const[s,m]=a.useState("activity"),[l,p]=a.useState(T),[r,h]=a.useState(A),[x,y]=a.useState([]),[u,f]=a.useState(!0);a.useEffect(()=>{async function t(){try{const i=await(await j.api.profile.$get()).json();i.success&&(p(i.data.profile),h(i.data.stats),y(i.data.activity))}finally{f(!1)}}t()},[]);const c=s==="activity"?x:x.filter(t=>s==="topics"?t.type==="topic":s==="replies"?t.type==="reply":!0);return u?e.jsx("div",{className:"flex items-center justify-center py-20","data-testid":"profile-loading",children:e.jsx(v,{size:"lg"})}):e.jsxs("div",{className:"min-h-screen bg-white","data-testid":"profile-page",children:[e.jsxs(g,{children:[e.jsx("title",{children:"Profile — Community"}),e.jsx("meta",{name:"description",content:"Community user profile"})]}),e.jsx("div",{className:"bg-gradient-to-b from-emerald-50 to-white pt-12 pb-16 px-4 sm:px-6",children:e.jsxs("div",{className:"max-w-3xl mx-auto",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row items-center sm:items-start gap-5",children:[e.jsx("div",{className:"w-20 h-20 rounded-full bg-emerald-500 text-white text-2xl font-bold flex items-center justify-center shadow-lg shadow-emerald-500/25 shrink-0",children:l.initials}),e.jsxs("div",{className:"text-center sm:text-left flex-1",children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:l.name}),e.jsxs("p",{className:"text-sm text-gray-500 mt-0.5",children:["Joined ",l.joinedDate]}),e.jsx("p",{className:"text-gray-600 mt-2 text-sm leading-relaxed max-w-md",children:l.bio})]}),e.jsxs("button",{className:"inline-flex items-center gap-2 px-4 py-2 bg-emerald-500 hover:bg-emerald-600 text-white text-sm font-medium rounded-xl shadow-sm shadow-emerald-500/25 transition-colors self-center sm:self-start shrink-0",children:[e.jsx(k,{className:"w-3.5 h-3.5"}),"Edit Profile"]})]}),e.jsxs("div",{className:"flex justify-center sm:justify-start gap-6 mt-6",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"text-xl font-bold text-gray-900",children:r.topics}),e.jsx("div",{className:"text-xs text-gray-500",children:"Topics"})]}),e.jsx("div",{className:"w-px bg-gray-200"}),e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"text-xl font-bold text-gray-900",children:r.replies}),e.jsx("div",{className:"text-xs text-gray-500",children:"Replies"})]}),e.jsx("div",{className:"w-px bg-gray-200"}),e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"text-xl font-bold text-gray-900",children:r.likes}),e.jsx("div",{className:"text-xs text-gray-500",children:"Likes"})]})]})]})}),e.jsxs("div",{className:"max-w-3xl mx-auto px-4 sm:px-6 -mt-6 pb-16",children:[e.jsx("div",{className:"flex gap-1 bg-gray-100 p-1 rounded-xl mb-6",children:L.map(t=>e.jsx("button",{onClick:()=>m(t.value),className:`flex-1 py-2 text-sm font-medium rounded-lg transition-colors ${s===t.value?"bg-white text-gray-900 shadow-sm":"text-gray-500 hover:text-gray-700"}`,children:t.label},t.value))}),c.length===0?e.jsxs("div",{className:"text-center py-16",children:[e.jsx("div",{className:"inline-flex items-center justify-center w-14 h-14 bg-gray-100 rounded-full mb-3",children:e.jsx(o,{className:"w-6 h-6 text-gray-400"})}),e.jsx("p",{className:"text-gray-500 text-sm",children:"No items yet"})]}):e.jsx("div",{className:"space-y-1",children:c.map((t,d)=>e.jsxs("div",{className:"flex items-start gap-3 p-3.5 rounded-xl hover:bg-gray-50 transition-colors",children:[e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:`w-8 h-8 rounded-lg flex items-center justify-center ${_(t.type)}`,children:P(t.type)}),d<c.length-1&&e.jsx("div",{className:"absolute top-8 left-1/2 -translate-x-px w-0.5 h-[calc(100%+4px)] bg-gray-100"})]}),e.jsxs("div",{className:"flex-1 min-w-0 pt-0.5",children:[e.jsxs("p",{className:"text-sm text-gray-700 leading-relaxed",children:[e.jsx("span",{className:"text-gray-500",children:t.text})," ",e.jsx("span",{className:"font-medium text-gray-900",children:t.target})]}),e.jsx("p",{className:"text-xs text-gray-400 mt-0.5",children:t.time})]})]},t.id))})]})]})};export{C as ProfilePage};