@sonicjs-cms/core 2.0.0-alpha.9 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-4XI3YBKU.cjs +266 -0
- package/dist/chunk-4XI3YBKU.cjs.map +1 -0
- package/dist/chunk-ET5I4GBD.cjs +3515 -0
- package/dist/chunk-ET5I4GBD.cjs.map +1 -0
- package/dist/{chunk-N7EIZ74L.js → chunk-JETM2U2D.js} +3479 -1328
- package/dist/chunk-JETM2U2D.js.map +1 -0
- package/dist/chunk-LU6J53IX.js +262 -0
- package/dist/chunk-LU6J53IX.js.map +1 -0
- package/dist/chunk-P3VS4DV3.js +3498 -0
- package/dist/chunk-P3VS4DV3.js.map +1 -0
- package/dist/{chunk-H6E2I5GW.cjs → chunk-QUMBDPNJ.cjs} +3522 -1365
- package/dist/chunk-QUMBDPNJ.cjs.map +1 -0
- package/dist/index.cjs +97 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +2 -0
- package/dist/plugins.d.ts +2 -0
- package/dist/routes.cjs +37 -12
- package/dist/routes.d.ts +2 -0
- package/dist/routes.js +2 -1
- package/dist/services.d.ts +2 -0
- package/dist/templates.cjs +45 -12
- package/dist/templates.d.ts +2 -0
- package/dist/templates.js +2 -1
- package/dist/types.d.ts +2 -0
- package/dist/utils.d.ts +2 -0
- package/package.json +2 -2
- package/dist/chunk-BRC3F4CG.cjs +0 -792
- package/dist/chunk-BRC3F4CG.cjs.map +0 -1
- package/dist/chunk-H6E2I5GW.cjs.map +0 -1
- package/dist/chunk-KRJMGD4E.js +0 -783
- package/dist/chunk-KRJMGD4E.js.map +0 -1
- package/dist/chunk-N7EIZ74L.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/routes/api-content-crud.ts","../src/routes/api.ts","../src/routes/api-media.ts","../src/routes/api-system.ts","../src/routes/admin-api.ts","../src/templates/pages/auth-login.template.ts","../src/templates/pages/auth-register.template.ts","../src/services/auth-validation.ts","../src/routes/auth.ts","../src/templates/pages/admin-content-form.template.ts","../src/templates/components/dynamic-field.template.ts","../src/templates/pages/admin-content-list.template.ts","../src/templates/components/version-history.template.ts","../src/routes/admin-content.ts","../src/templates/pages/admin-profile.template.ts","../src/templates/components/alert.template.ts","../src/templates/pages/admin-activity-logs.template.ts","../src/templates/pages/admin-user-edit.template.ts","../src/templates/components/confirmation-dialog.template.ts","../src/templates/pages/admin-user-new.template.ts","../src/templates/pages/admin-users-list.template.ts","../src/routes/admin-users.ts","../src/templates/components/media-grid.template.ts","../src/templates/pages/admin-media-library.template.ts","../src/templates/components/media-file-details.template.ts","../src/routes/admin-media.ts","../src/templates/pages/admin-plugins-list.template.ts","../src/templates/components/auth-settings-form.template.ts","../src/templates/pages/admin-plugin-settings.template.ts","../src/routes/admin-plugins.ts","../src/templates/pages/admin-logs-list.template.ts","../src/templates/pages/admin-log-details.template.ts","../src/templates/pages/admin-log-config.template.ts","../src/routes/admin-logs.ts","../src/routes/admin-design.ts","../src/routes/admin-checkboxes.ts","../src/templates/pages/admin-faq-form.template.ts","../src/routes/admin-faq.ts","../src/templates/pages/admin-testimonials-form.template.ts","../src/routes/admin-testimonials.ts","../src/templates/pages/admin-code-examples-form.template.ts","../src/routes/admin-code-examples.ts","../src/routes/index.ts"],"names":["Hono","z","error","escapeHtml","options","db","collection","formData","html","renderAlert","renderConfirmationDialog","getConfirmationDialogScript","fileValidationSchema","getImageDimensions","getJPEGDimensions","getPNGDimensions"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;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","file":"chunk-JETM2U2D.js","sourcesContent":["/**\n * Schema Definitions\n *\n * Placeholder for schema definitions - to be populated as needed\n */\n\nexport interface SchemaDefinition {\n name: string\n fields: any[]\n}\n\n// Empty array for now - schemas will be migrated incrementally\nexport const schemaDefinitions: SchemaDefinition[] = []\n","import { Hono } from 'hono'\nimport { requireAuth } from '../middleware'\nimport { getCacheService, CACHE_CONFIGS } from '../services'\nimport type { Bindings, Variables } from '../app'\n\nconst apiContentCrudRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// GET /api/content/:id - Get single content item by ID\napiContentCrudRoutes.get('/:id', async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n\n const stmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const content = await stmt.bind(id).first()\n\n if (!content) {\n return c.json({ error: 'Content not found' }, 404)\n }\n\n const transformedContent = {\n id: (content as any).id,\n title: (content as any).title,\n slug: (content as any).slug,\n status: (content as any).status,\n collectionId: (content as any).collection_id,\n data: (content as any).data ? JSON.parse((content as any).data) : {},\n created_at: (content as any).created_at,\n updated_at: (content as any).updated_at\n }\n\n return c.json({ data: transformedContent })\n } catch (error) {\n console.error('Error fetching content:', error)\n return c.json({\n error: 'Failed to fetch content',\n details: error instanceof Error ? error.message : String(error)\n }, 500)\n }\n})\n\n// POST /api/content - Create new content (requires authentication)\napiContentCrudRoutes.post('/', requireAuth(), async (c) => {\n try {\n const db = c.env.DB\n const user = c.get('user')\n const body = await c.req.json()\n\n const { collectionId, title, slug, status, data } = body\n\n // Validate required fields\n if (!collectionId) {\n return c.json({ error: 'collectionId is required' }, 400)\n }\n\n if (!title) {\n return c.json({ error: 'title is required' }, 400)\n }\n\n // Generate slug from title if not provided\n let finalSlug = slug || title\n finalSlug = finalSlug.toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .trim()\n\n // Check for duplicate slug within the same collection\n const duplicateCheck = db.prepare(\n 'SELECT id FROM content WHERE collection_id = ? AND slug = ?'\n )\n const existing = await duplicateCheck.bind(collectionId, finalSlug).first()\n\n if (existing) {\n return c.json({ error: 'A content item with this slug already exists in this collection' }, 409)\n }\n\n // Create new content\n const contentId = crypto.randomUUID()\n const now = Date.now()\n\n const insertStmt = db.prepare(`\n INSERT INTO content (\n id, collection_id, slug, title, data, status,\n author_id, created_at, updated_at\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n\n await insertStmt.bind(\n contentId,\n collectionId,\n finalSlug,\n title,\n JSON.stringify(data || {}),\n status || 'draft',\n user?.userId || 'unknown',\n now,\n now\n ).run()\n\n // Invalidate cache\n const cache = getCacheService(CACHE_CONFIGS.api!)\n await cache.invalidate(`content:list:${collectionId}:*`)\n await cache.invalidate('content-filtered:*')\n\n // Get the created content\n const getStmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const createdContent = await getStmt.bind(contentId).first() as any\n\n return c.json({\n data: {\n id: createdContent.id,\n title: createdContent.title,\n slug: createdContent.slug,\n status: createdContent.status,\n collectionId: createdContent.collection_id,\n data: createdContent.data ? JSON.parse(createdContent.data) : {},\n created_at: createdContent.created_at,\n updated_at: createdContent.updated_at\n }\n }, 201)\n } catch (error) {\n console.error('Error creating content:', error)\n return c.json({\n error: 'Failed to create content',\n details: error instanceof Error ? error.message : String(error)\n }, 500)\n }\n})\n\n// PUT /api/content/:id - Update content (requires authentication)\napiContentCrudRoutes.put('/:id', requireAuth(), async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n const body = await c.req.json()\n\n // Check if content exists\n const existingStmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const existing = await existingStmt.bind(id).first() as any\n\n if (!existing) {\n return c.json({ error: 'Content not found' }, 404)\n }\n\n // Build update fields dynamically\n const updates: string[] = []\n const params: any[] = []\n\n if (body.title !== undefined) {\n updates.push('title = ?')\n params.push(body.title)\n }\n\n if (body.slug !== undefined) {\n let finalSlug = body.slug.toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .trim()\n updates.push('slug = ?')\n params.push(finalSlug)\n }\n\n if (body.status !== undefined) {\n updates.push('status = ?')\n params.push(body.status)\n }\n\n if (body.data !== undefined) {\n updates.push('data = ?')\n params.push(JSON.stringify(body.data))\n }\n\n // Always update updated_at\n const now = Date.now()\n updates.push('updated_at = ?')\n params.push(now)\n\n // Add id to params for WHERE clause\n params.push(id)\n\n // Execute update\n const updateStmt = db.prepare(`\n UPDATE content SET ${updates.join(', ')}\n WHERE id = ?\n `)\n\n await updateStmt.bind(...params).run()\n\n // Invalidate cache\n const cache = getCacheService(CACHE_CONFIGS.api!)\n await cache.delete(cache.generateKey('content', id))\n await cache.invalidate(`content:list:${existing.collection_id}:*`)\n await cache.invalidate('content-filtered:*')\n\n // Get updated content\n const getStmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const updatedContent = await getStmt.bind(id).first() as any\n\n return c.json({\n data: {\n id: updatedContent.id,\n title: updatedContent.title,\n slug: updatedContent.slug,\n status: updatedContent.status,\n collectionId: updatedContent.collection_id,\n data: updatedContent.data ? JSON.parse(updatedContent.data) : {},\n created_at: updatedContent.created_at,\n updated_at: updatedContent.updated_at\n }\n })\n } catch (error) {\n console.error('Error updating content:', error)\n return c.json({\n error: 'Failed to update content',\n details: error instanceof Error ? error.message : String(error)\n }, 500)\n }\n})\n\n// DELETE /api/content/:id - Delete content (requires authentication)\napiContentCrudRoutes.delete('/:id', requireAuth(), async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n\n // Check if content exists\n const existingStmt = db.prepare('SELECT collection_id FROM content WHERE id = ?')\n const existing = await existingStmt.bind(id).first() as any\n\n if (!existing) {\n return c.json({ error: 'Content not found' }, 404)\n }\n\n // Delete the content (hard delete for API, soft delete happens in admin routes)\n const deleteStmt = db.prepare('DELETE FROM content WHERE id = ?')\n await deleteStmt.bind(id).run()\n\n // Invalidate cache\n const cache = getCacheService(CACHE_CONFIGS.api!)\n await cache.delete(cache.generateKey('content', id))\n await cache.invalidate(`content:list:${existing.collection_id}:*`)\n await cache.invalidate('content-filtered:*')\n\n return c.json({ success: true })\n } catch (error) {\n console.error('Error deleting content:', error)\n return c.json({\n error: 'Failed to delete content',\n details: error instanceof Error ? error.message : String(error)\n }, 500)\n }\n})\n\nexport default apiContentCrudRoutes\n","import { Hono } from 'hono'\nimport { cors } from 'hono/cors'\nimport { schemaDefinitions } from '../schemas'\nimport { getCacheService, CACHE_CONFIGS } from '../services'\nimport { QueryFilterBuilder, QueryFilter } from '../utils'\nimport { isPluginActive } from '../middleware'\nimport apiContentCrudRoutes from './api-content-crud'\nimport type { Bindings, Variables as AppVariables } from '../app'\n\n// Extend Variables with API-specific fields\ninterface Variables extends AppVariables {\n startTime: number\n cacheEnabled?: boolean\n}\n\nconst apiRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Add timing middleware\napiRoutes.use('*', async (c, next) => {\n const startTime = Date.now()\n c.set('startTime', startTime)\n await next()\n const totalTime = Date.now() - startTime\n c.header('X-Response-Time', `${totalTime}ms`)\n})\n\n// Check if cache plugin is active\napiRoutes.use('*', async (c, next) => {\n const cacheEnabled = await isPluginActive(c.env.DB, 'core-cache')\n c.set('cacheEnabled', cacheEnabled)\n await next()\n})\n\n// Add CORS middleware\napiRoutes.use('*', cors({\n origin: '*',\n allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowHeaders: ['Content-Type', 'Authorization']\n}))\n\n// Helper function to add timing metadata\nfunction addTimingMeta(c: any, meta: any = {}, executionStartTime?: number) {\n const totalTime = Date.now() - c.get('startTime')\n const executionTime = executionStartTime ? Date.now() - executionStartTime : undefined\n\n return {\n ...meta,\n timing: {\n total: totalTime,\n execution: executionTime,\n unit: 'ms'\n }\n }\n}\n\n// Root endpoint - API info\napiRoutes.get('/', (c) => {\n return c.json({\n name: 'SonicJS API',\n version: '2.0.0',\n description: 'RESTful API for SonicJS headless CMS',\n endpoints: {\n health: '/api/health',\n collections: '/api/collections',\n content: '/api/content',\n contentById: '/api/content/:id',\n collectionContent: '/api/collections/:collection/content'\n },\n documentation: '/docs'\n })\n})\n\n// Health check endpoint\napiRoutes.get('/health', (c) => {\n return c.json({\n status: 'healthy',\n timestamp: new Date().toISOString(),\n schemas: schemaDefinitions.map(s => s.name)\n })\n})\n\n// Basic collections endpoint\napiRoutes.get('/collections', async (c) => {\n const executionStart = Date.now()\n\n try {\n const db = c.env.DB\n const cacheEnabled = c.get('cacheEnabled')\n const cache = getCacheService(CACHE_CONFIGS.api!)\n const cacheKey = cache.generateKey('collections', 'all')\n\n // Use cache only if cache plugin is active\n if (cacheEnabled) {\n const cacheResult = await cache.getWithSource<any>(cacheKey)\n if (cacheResult.hit && cacheResult.data) {\n // Add cache headers\n c.header('X-Cache-Status', 'HIT')\n c.header('X-Cache-Source', cacheResult.source)\n if (cacheResult.ttl) {\n c.header('X-Cache-TTL', Math.floor(cacheResult.ttl).toString())\n }\n\n // Add cache info and timing to meta\n const dataWithMeta = {\n ...cacheResult.data,\n meta: addTimingMeta(c, {\n ...cacheResult.data.meta,\n cache: {\n hit: true,\n source: cacheResult.source,\n ttl: cacheResult.ttl ? Math.floor(cacheResult.ttl) : undefined\n }\n }, executionStart)\n }\n\n return c.json(dataWithMeta)\n }\n }\n\n // Cache miss - fetch from database\n c.header('X-Cache-Status', 'MISS')\n c.header('X-Cache-Source', 'database')\n\n const stmt = db.prepare('SELECT * FROM collections WHERE is_active = 1')\n const { results } = await stmt.all()\n\n // Parse schema and format results\n const transformedResults = results.map((row: any) => ({\n ...row,\n schema: row.schema ? JSON.parse(row.schema) : {},\n is_active: row.is_active // Keep as number (1 or 0)\n }))\n\n const responseData = {\n data: transformedResults,\n meta: addTimingMeta(c, {\n count: results.length,\n timestamp: new Date().toISOString(),\n cache: {\n hit: false,\n source: 'database'\n }\n }, executionStart)\n }\n\n // Cache the response only if cache plugin is enabled\n if (cacheEnabled) {\n await cache.set(cacheKey, responseData)\n }\n\n return c.json(responseData)\n } catch (error) {\n console.error('Error fetching collections:', error)\n return c.json({ error: 'Failed to fetch collections' }, 500)\n }\n})\n\n// Basic content endpoint with advanced filtering\napiRoutes.get('/content', async (c) => {\n const executionStart = Date.now()\n\n try {\n const db = c.env.DB\n const queryParams = c.req.query()\n\n // Handle collection parameter - convert collection name to collection_id\n if (queryParams.collection) {\n const collectionName = queryParams.collection\n const collectionStmt = db.prepare('SELECT id FROM collections WHERE name = ? AND is_active = 1')\n const collectionResult = await collectionStmt.bind(collectionName).first()\n\n if (collectionResult) {\n // Replace 'collection' param with 'collection_id' for the filter builder\n queryParams.collection_id = (collectionResult as any).id\n delete queryParams.collection\n } else {\n // Collection not found - return empty result\n return c.json({\n data: [],\n meta: addTimingMeta(c, {\n count: 0,\n timestamp: new Date().toISOString(),\n message: `Collection '${collectionName}' not found`\n }, executionStart)\n })\n }\n }\n\n // Parse filter from query parameters\n const filter: QueryFilter = QueryFilterBuilder.parseFromQuery(queryParams)\n\n // Set default limit if not provided\n if (!filter.limit) {\n filter.limit = 50\n }\n filter.limit = Math.min(filter.limit, 1000) // Max 1000\n\n // Build SQL query from filter\n const builder = new QueryFilterBuilder()\n const queryResult = builder.build('content', filter)\n\n // Check for query building errors\n if (queryResult.errors.length > 0) {\n return c.json({\n error: 'Invalid filter parameters',\n details: queryResult.errors\n }, 400)\n }\n\n // Only use cache if cache plugin is active\n const cacheEnabled = c.get('cacheEnabled')\n const cache = getCacheService(CACHE_CONFIGS.api!)\n const cacheKey = cache.generateKey('content-filtered', JSON.stringify({ filter, query: queryResult.sql }))\n\n if (cacheEnabled) {\n const cacheResult = await cache.getWithSource<any>(cacheKey)\n if (cacheResult.hit && cacheResult.data) {\n // Add cache headers\n c.header('X-Cache-Status', 'HIT')\n c.header('X-Cache-Source', cacheResult.source)\n if (cacheResult.ttl) {\n c.header('X-Cache-TTL', Math.floor(cacheResult.ttl).toString())\n }\n\n // Add cache info and timing to meta\n const dataWithMeta = {\n ...cacheResult.data,\n meta: addTimingMeta(c, {\n ...cacheResult.data.meta,\n cache: {\n hit: true,\n source: cacheResult.source,\n ttl: cacheResult.ttl ? Math.floor(cacheResult.ttl) : undefined\n }\n }, executionStart)\n }\n\n return c.json(dataWithMeta)\n }\n }\n\n // Cache miss - fetch from database\n c.header('X-Cache-Status', 'MISS')\n c.header('X-Cache-Source', 'database')\n\n // Execute query with parameters\n const stmt = db.prepare(queryResult.sql)\n const boundStmt = queryResult.params.length > 0\n ? stmt.bind(...queryResult.params)\n : stmt\n\n const { results } = await boundStmt.all()\n\n // Transform results to match API spec (camelCase)\n const transformedResults = results.map((row: any) => ({\n id: row.id,\n title: row.title,\n slug: row.slug,\n status: row.status,\n collectionId: row.collection_id,\n data: row.data ? JSON.parse(row.data) : {},\n created_at: row.created_at,\n updated_at: row.updated_at\n }))\n\n const responseData = {\n data: transformedResults,\n meta: addTimingMeta(c, {\n count: results.length,\n timestamp: new Date().toISOString(),\n filter: filter,\n query: {\n sql: queryResult.sql,\n params: queryResult.params\n },\n cache: {\n hit: false,\n source: 'database'\n }\n }, executionStart)\n }\n\n // Cache the response only if cache is enabled\n if (cacheEnabled) {\n await cache.set(cacheKey, responseData)\n }\n\n return c.json(responseData)\n } catch (error) {\n console.error('Error fetching content:', error)\n return c.json({\n error: 'Failed to fetch content',\n details: error instanceof Error ? error.message : String(error)\n }, 500)\n }\n})\n\n// Collection-specific routes with advanced filtering\napiRoutes.get('/collections/:collection/content', async (c) => {\n const executionStart = Date.now()\n\n try {\n const collection = c.req.param('collection')\n const db = c.env.DB\n const queryParams = c.req.query()\n\n // First check if collection exists\n const collectionStmt = db.prepare('SELECT * FROM collections WHERE name = ? AND is_active = 1')\n const collectionResult = await collectionStmt.bind(collection).first()\n\n if (!collectionResult) {\n return c.json({ error: 'Collection not found' }, 404)\n }\n\n // Parse filter from query parameters\n const filter: QueryFilter = QueryFilterBuilder.parseFromQuery(queryParams)\n\n // Add collection_id filter to where clause\n if (!filter.where) {\n filter.where = { and: [] }\n }\n\n if (!filter.where.and) {\n filter.where.and = []\n }\n\n // Add collection filter\n filter.where.and.push({\n field: 'collection_id',\n operator: 'equals',\n value: (collectionResult as any).id\n })\n\n // Set default limit if not provided\n if (!filter.limit) {\n filter.limit = 50\n }\n filter.limit = Math.min(filter.limit, 1000)\n\n // Build SQL query from filter\n const builder = new QueryFilterBuilder()\n const queryResult = builder.build('content', filter)\n\n // Check for query building errors\n if (queryResult.errors.length > 0) {\n return c.json({\n error: 'Invalid filter parameters',\n details: queryResult.errors\n }, 400)\n }\n\n // Generate cache key\n const cacheEnabled = c.get('cacheEnabled')\n const cache = getCacheService(CACHE_CONFIGS.api!)\n const cacheKey = cache.generateKey('collection-content-filtered', `${collection}:${JSON.stringify({ filter, query: queryResult.sql })}`)\n\n // Only check cache if plugin is enabled\n if (cacheEnabled) {\n const cacheResult = await cache.getWithSource<any>(cacheKey)\n if (cacheResult.hit && cacheResult.data) {\n // Add cache headers\n c.header('X-Cache-Status', 'HIT')\n c.header('X-Cache-Source', cacheResult.source)\n if (cacheResult.ttl) {\n c.header('X-Cache-TTL', Math.floor(cacheResult.ttl).toString())\n }\n\n // Add cache info and timing to meta\n const dataWithMeta = {\n ...cacheResult.data,\n meta: addTimingMeta(c, {\n ...cacheResult.data.meta,\n cache: {\n hit: true,\n source: cacheResult.source,\n ttl: cacheResult.ttl ? Math.floor(cacheResult.ttl) : undefined\n }\n }, executionStart)\n }\n\n return c.json(dataWithMeta)\n }\n }\n\n // Cache miss - fetch from database\n c.header('X-Cache-Status', 'MISS')\n c.header('X-Cache-Source', 'database')\n\n // Execute query with parameters\n const stmt = db.prepare(queryResult.sql)\n const boundStmt = queryResult.params.length > 0\n ? stmt.bind(...queryResult.params)\n : stmt\n\n const { results } = await boundStmt.all()\n\n // Transform results to match API spec (camelCase)\n const transformedResults = results.map((row: any) => ({\n id: row.id,\n title: row.title,\n slug: row.slug,\n status: row.status,\n collectionId: row.collection_id,\n data: row.data ? JSON.parse(row.data) : {},\n created_at: row.created_at,\n updated_at: row.updated_at\n }))\n\n const responseData = {\n data: transformedResults,\n meta: addTimingMeta(c, {\n collection: {\n ...(collectionResult as any),\n schema: (collectionResult as any).schema ? JSON.parse((collectionResult as any).schema) : {}\n },\n count: results.length,\n timestamp: new Date().toISOString(),\n filter: filter,\n query: {\n sql: queryResult.sql,\n params: queryResult.params\n },\n cache: {\n hit: false,\n source: 'database'\n }\n }, executionStart)\n }\n\n // Cache the response only if cache plugin is enabled\n if (cacheEnabled) {\n await cache.set(cacheKey, responseData)\n }\n\n return c.json(responseData)\n } catch (error) {\n console.error('Error fetching content:', error)\n return c.json({\n error: 'Failed to fetch content',\n details: error instanceof Error ? error.message : String(error)\n }, 500)\n }\n})\n\n// Mount CRUD routes for content\napiRoutes.route('/content', apiContentCrudRoutes)\n\nexport default apiRoutes\n","import { Hono } from 'hono'\nimport { z } from 'zod'\nimport { requireAuth } from '../middleware'\nimport type { Bindings, Variables } from '../app'\n\n// Helper function to generate short IDs (replacement for nanoid)\nfunction generateId(): string {\n return crypto.randomUUID().replace(/-/g, '').substring(0, 21)\n}\n\n// Helper function for emitting events (simplified for core package)\nasync function emitEvent(eventName: string, data: any) {\n console.log(`[Event] ${eventName}:`, data)\n // TODO: Implement proper event system when plugin architecture is ready\n}\n\n// File validation schema\nconst fileValidationSchema = z.object({\n name: z.string().min(1).max(255),\n type: z.string().refine(\n (type) => {\n const allowedTypes = [\n // Images\n 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml',\n // Documents\n 'application/pdf', 'text/plain', 'application/msword', \n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n // Videos\n 'video/mp4', 'video/webm', 'video/ogg', 'video/avi', 'video/mov',\n // Audio\n 'audio/mp3', 'audio/wav', 'audio/ogg', 'audio/m4a'\n ]\n return allowedTypes.includes(type)\n },\n { message: 'Unsupported file type' }\n ),\n size: z.number().min(1).max(50 * 1024 * 1024) // 50MB max\n})\n\nexport const apiMediaRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Apply auth middleware to all routes\napiMediaRoutes.use('*', requireAuth())\n\n// Upload single file\napiMediaRoutes.post('/upload', async (c) => {\n try {\n const user = c.get('user')!\n const formData = await c.req.formData()\n const fileData = formData.get('file')\n\n if (!fileData || typeof fileData === 'string') {\n return c.json({ error: 'No file provided' }, 400)\n }\n\n const file = fileData as File\n\n // Validate file\n const validation = fileValidationSchema.safeParse({\n name: file.name,\n type: file.type,\n size: file.size\n })\n\n if (!validation.success) {\n return c.json({ \n error: 'File validation failed', \n details: validation.error.issues \n }, 400)\n }\n\n // Generate unique filename and R2 key\n const fileId = generateId()\n const fileExtension = file.name.split('.').pop() || ''\n const filename = `${fileId}.${fileExtension}`\n const folder = formData.get('folder') as string || 'uploads'\n const r2Key = `${folder}/${filename}`\n\n // Upload to R2\n const arrayBuffer = await file.arrayBuffer()\n const uploadResult = await c.env.MEDIA_BUCKET.put(r2Key, arrayBuffer, {\n httpMetadata: {\n contentType: file.type,\n contentDisposition: `inline; filename=\"${file.name}\"`\n },\n customMetadata: {\n originalName: file.name,\n uploadedBy: user.userId,\n uploadedAt: new Date().toISOString()\n }\n })\n\n if (!uploadResult) {\n return c.json({ error: 'Failed to upload file to storage' }, 500)\n }\n\n // Generate public URL using environment variable for bucket name\n const bucketName = c.env.BUCKET_NAME || 'sonicjs-media-dev'\n const publicUrl = `https://pub-${bucketName}.r2.dev/${r2Key}`\n \n // Extract image dimensions if it's an image\n let width: number | undefined\n let height: number | undefined\n \n if (file.type.startsWith('image/') && !file.type.includes('svg')) {\n try {\n const dimensions = await getImageDimensions(arrayBuffer)\n width = dimensions.width\n height = dimensions.height\n } catch (error) {\n console.warn('Failed to extract image dimensions:', error)\n }\n }\n\n // Generate thumbnail URL for images\n let thumbnailUrl: string | undefined\n if (file.type.startsWith('image/') && c.env.IMAGES_ACCOUNT_ID) {\n thumbnailUrl = `https://imagedelivery.net/${c.env.IMAGES_ACCOUNT_ID}/${r2Key}/thumbnail`\n }\n\n // Save to database\n const mediaRecord = {\n id: fileId,\n filename: filename,\n original_name: file.name,\n mime_type: file.type,\n size: file.size,\n width,\n height,\n folder,\n r2_key: r2Key,\n public_url: publicUrl,\n thumbnail_url: thumbnailUrl,\n uploaded_by: user.userId,\n uploaded_at: Math.floor(Date.now() / 1000),\n created_at: Math.floor(Date.now() / 1000)\n }\n\n const stmt = c.env.DB.prepare(`\n INSERT INTO media (\n id, filename, original_name, mime_type, size, width, height, \n folder, r2_key, public_url, thumbnail_url, uploaded_by, uploaded_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n \n await stmt.bind(\n mediaRecord.id,\n mediaRecord.filename,\n mediaRecord.original_name,\n mediaRecord.mime_type,\n mediaRecord.size,\n mediaRecord.width ?? null,\n mediaRecord.height ?? null,\n mediaRecord.folder,\n mediaRecord.r2_key,\n mediaRecord.public_url,\n mediaRecord.thumbnail_url ?? null,\n mediaRecord.uploaded_by,\n mediaRecord.uploaded_at\n ).run()\n\n // Emit media upload event\n await emitEvent('media.upload', { id: mediaRecord.id, filename: mediaRecord.filename })\n\n return c.json({\n success: true,\n file: {\n id: mediaRecord.id,\n filename: mediaRecord.filename,\n originalName: mediaRecord.original_name,\n mimeType: mediaRecord.mime_type,\n size: mediaRecord.size,\n width: mediaRecord.width,\n height: mediaRecord.height,\n publicUrl: mediaRecord.public_url,\n thumbnailUrl: mediaRecord.thumbnail_url,\n uploadedAt: new Date(mediaRecord.uploaded_at * 1000).toISOString()\n }\n })\n } catch (error) {\n console.error('Upload error:', error)\n return c.json({ error: 'Upload failed' }, 500)\n }\n})\n\n// Upload multiple files\napiMediaRoutes.post('/upload-multiple', async (c) => {\n try {\n const user = c.get('user')!\n const formData = await c.req.formData()\n const filesData = formData.getAll('files')\n\n // Filter out strings and ensure we only have File objects\n const files: File[] = []\n for (const f of filesData) {\n if (typeof f !== 'string') {\n files.push(f as File)\n }\n }\n\n if (!files || files.length === 0) {\n return c.json({ error: 'No files provided' }, 400)\n }\n\n const uploadResults = []\n const errors = []\n\n for (const file of files) {\n try {\n // Validate file\n const validation = fileValidationSchema.safeParse({\n name: file.name,\n type: file.type,\n size: file.size\n })\n\n if (!validation.success) {\n errors.push({\n filename: file.name,\n error: 'Validation failed',\n details: validation.error.issues\n })\n continue\n }\n\n // Generate unique filename and R2 key\n const fileId = generateId()\n const fileExtension = file.name.split('.').pop() || ''\n const filename = `${fileId}.${fileExtension}`\n const folder = formData.get('folder') as string || 'uploads'\n const r2Key = `${folder}/${filename}`\n\n // Upload to R2\n const arrayBuffer = await file.arrayBuffer()\n const uploadResult = await c.env.MEDIA_BUCKET.put(r2Key, arrayBuffer, {\n httpMetadata: {\n contentType: file.type,\n contentDisposition: `inline; filename=\"${file.name}\"`\n },\n customMetadata: {\n originalName: file.name,\n uploadedBy: user.userId,\n uploadedAt: new Date().toISOString()\n }\n })\n\n if (!uploadResult) {\n errors.push({\n filename: file.name,\n error: 'Failed to upload to storage'\n })\n continue\n }\n\n // Generate public URL using environment variable for bucket name\n const bucketName = c.env.BUCKET_NAME || 'sonicjs-media-dev'\n const publicUrl = `https://pub-${bucketName}.r2.dev/${r2Key}`\n \n // Extract image dimensions if it's an image\n let width: number | undefined\n let height: number | undefined\n \n if (file.type.startsWith('image/') && !file.type.includes('svg')) {\n try {\n const dimensions = await getImageDimensions(arrayBuffer)\n width = dimensions.width\n height = dimensions.height\n } catch (error) {\n console.warn('Failed to extract image dimensions:', error)\n }\n }\n\n // Generate thumbnail URL for images\n let thumbnailUrl: string | undefined\n if (file.type.startsWith('image/') && c.env.IMAGES_ACCOUNT_ID) {\n thumbnailUrl = `https://imagedelivery.net/${c.env.IMAGES_ACCOUNT_ID}/${r2Key}/thumbnail`\n }\n\n // Save to database\n const mediaRecord = {\n id: fileId,\n filename: filename,\n original_name: file.name,\n mime_type: file.type,\n size: file.size,\n width,\n height,\n folder,\n r2_key: r2Key,\n public_url: publicUrl,\n thumbnail_url: thumbnailUrl,\n uploaded_by: user.userId,\n uploaded_at: Math.floor(Date.now() / 1000)\n }\n\n const stmt = c.env.DB.prepare(`\n INSERT INTO media (\n id, filename, original_name, mime_type, size, width, height, \n folder, r2_key, public_url, thumbnail_url, uploaded_by, uploaded_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n \n await stmt.bind(\n mediaRecord.id,\n mediaRecord.filename,\n mediaRecord.original_name,\n mediaRecord.mime_type,\n mediaRecord.size,\n mediaRecord.width ?? null,\n mediaRecord.height ?? null,\n mediaRecord.folder,\n mediaRecord.r2_key,\n mediaRecord.public_url,\n mediaRecord.thumbnail_url ?? null,\n mediaRecord.uploaded_by,\n mediaRecord.uploaded_at\n ).run()\n\n uploadResults.push({\n id: mediaRecord.id,\n filename: mediaRecord.filename,\n originalName: mediaRecord.original_name,\n mimeType: mediaRecord.mime_type,\n size: mediaRecord.size,\n width: mediaRecord.width,\n height: mediaRecord.height,\n publicUrl: mediaRecord.public_url,\n thumbnailUrl: mediaRecord.thumbnail_url,\n uploadedAt: new Date(mediaRecord.uploaded_at * 1000).toISOString()\n })\n } catch (error) {\n errors.push({\n filename: file.name,\n error: 'Upload failed',\n details: error instanceof Error ? error.message : 'Unknown error'\n })\n }\n }\n\n // Emit media upload event if any uploads succeeded\n if (uploadResults.length > 0) {\n await emitEvent('media.upload', { count: uploadResults.length })\n }\n\n return c.json({\n success: uploadResults.length > 0,\n uploaded: uploadResults,\n errors: errors,\n summary: {\n total: files.length,\n successful: uploadResults.length,\n failed: errors.length\n }\n })\n } catch (error) {\n console.error('Multiple upload error:', error)\n return c.json({ error: 'Upload failed' }, 500)\n }\n})\n\n// Bulk delete files\napiMediaRoutes.post('/bulk-delete', async (c) => {\n try {\n const user = c.get('user')!\n const body = await c.req.json()\n const fileIds = body.fileIds as string[]\n \n if (!fileIds || !Array.isArray(fileIds) || fileIds.length === 0) {\n return c.json({ error: 'No file IDs provided' }, 400)\n }\n\n // Limit bulk operations to prevent abuse\n if (fileIds.length > 50) {\n return c.json({ error: 'Too many files selected. Maximum 50 files per operation.' }, 400)\n }\n\n const results = []\n const errors = []\n\n for (const fileId of fileIds) {\n try {\n // Get file record (including already deleted files to check if they exist at all)\n const stmt = c.env.DB.prepare('SELECT * FROM media WHERE id = ?')\n const fileRecord = await stmt.bind(fileId).first() as any\n\n if (!fileRecord) {\n errors.push({ fileId, error: 'File not found' })\n continue\n }\n\n // Skip if already deleted (treat as success)\n if (fileRecord.deleted_at !== null) {\n console.log(`File ${fileId} already deleted, skipping`)\n results.push({\n fileId,\n filename: fileRecord.original_name,\n success: true,\n alreadyDeleted: true\n })\n continue\n }\n\n // Check permissions (only allow deletion by uploader or admin)\n if (fileRecord.uploaded_by !== user.userId && user.role !== 'admin') {\n errors.push({ fileId, error: 'Permission denied' })\n continue\n }\n\n // Delete from R2\n try {\n await c.env.MEDIA_BUCKET.delete(fileRecord.r2_key)\n } catch (error) {\n console.warn(`Failed to delete from R2 for file ${fileId}:`, error)\n // Continue with database deletion even if R2 deletion fails\n }\n\n // Soft delete in database\n const deleteStmt = c.env.DB.prepare('UPDATE media SET deleted_at = ? WHERE id = ?')\n await deleteStmt.bind(Math.floor(Date.now() / 1000), fileId).run()\n\n results.push({\n fileId,\n filename: fileRecord.original_name,\n success: true\n })\n } catch (error) {\n errors.push({\n fileId,\n error: 'Delete failed',\n details: error instanceof Error ? error.message : 'Unknown error'\n })\n }\n }\n\n // Emit media delete event if any deletes succeeded\n if (results.length > 0) {\n await emitEvent('media.delete', { count: results.length, ids: fileIds })\n }\n\n return c.json({\n success: results.length > 0,\n deleted: results,\n errors: errors,\n summary: {\n total: fileIds.length,\n successful: results.length,\n failed: errors.length\n }\n })\n } catch (error) {\n console.error('Bulk delete error:', error)\n return c.json({ error: 'Bulk delete failed' }, 500)\n }\n})\n\n// Create folder\napiMediaRoutes.post('/create-folder', async (c) => {\n try {\n const body = await c.req.json()\n const folderName = body.folderName as string\n\n if (!folderName || typeof folderName !== 'string') {\n return c.json({ success: false, error: 'No folder name provided' }, 400)\n }\n\n // Validate folder name format\n const folderPattern = /^[a-z0-9-_]+$/\n if (!folderPattern.test(folderName)) {\n return c.json({\n success: false,\n error: 'Folder name can only contain lowercase letters, numbers, hyphens, and underscores'\n }, 400)\n }\n\n // Check if folder already exists in the database\n const checkStmt = c.env.DB.prepare('SELECT COUNT(*) as count FROM media WHERE folder = ? AND deleted_at IS NULL')\n const existingFolder = await checkStmt.bind(folderName).first() as any\n\n // Note: We allow folder creation even if it exists, as R2 folders are virtual\n // The folder will be created when files are uploaded to it\n\n return c.json({\n success: true,\n message: `Folder \"${folderName}\" created successfully`,\n folder: folderName\n })\n } catch (error) {\n console.error('Create folder error:', error)\n return c.json({ success: false, error: 'Failed to create folder' }, 500)\n }\n})\n\n// Bulk move files to folder\napiMediaRoutes.post('/bulk-move', async (c) => {\n try {\n const user = c.get('user')!\n const body = await c.req.json()\n const fileIds = body.fileIds as string[]\n const targetFolder = body.folder as string\n\n if (!fileIds || !Array.isArray(fileIds) || fileIds.length === 0) {\n return c.json({ error: 'No file IDs provided' }, 400)\n }\n\n if (!targetFolder || typeof targetFolder !== 'string') {\n return c.json({ error: 'No target folder provided' }, 400)\n }\n\n // Limit bulk operations to prevent abuse\n if (fileIds.length > 50) {\n return c.json({ error: 'Too many files selected. Maximum 50 files per operation.' }, 400)\n }\n\n const results = []\n const errors = []\n\n for (const fileId of fileIds) {\n try {\n // Get file record\n const stmt = c.env.DB.prepare('SELECT * FROM media WHERE id = ? AND deleted_at IS NULL')\n const fileRecord = await stmt.bind(fileId).first() as any\n\n if (!fileRecord) {\n errors.push({ fileId, error: 'File not found' })\n continue\n }\n\n // Check permissions (only allow move by uploader or admin)\n if (fileRecord.uploaded_by !== user.userId && user.role !== 'admin') {\n errors.push({ fileId, error: 'Permission denied' })\n continue\n }\n\n // Skip if already in target folder\n if (fileRecord.folder === targetFolder) {\n results.push({\n fileId,\n filename: fileRecord.original_name,\n success: true,\n skipped: true\n })\n continue\n }\n\n // Generate new R2 key with new folder\n const oldR2Key = fileRecord.r2_key\n const filename = oldR2Key.split('/').pop() || fileRecord.filename\n const newR2Key = `${targetFolder}/${filename}`\n\n // Copy file to new location in R2\n try {\n const object = await c.env.MEDIA_BUCKET.get(oldR2Key)\n if (!object) {\n errors.push({ fileId, error: 'File not found in storage' })\n continue\n }\n\n await c.env.MEDIA_BUCKET.put(newR2Key, object.body, {\n httpMetadata: object.httpMetadata,\n customMetadata: {\n ...object.customMetadata,\n movedBy: user.userId,\n movedAt: new Date().toISOString()\n }\n })\n\n // Delete old file from R2\n await c.env.MEDIA_BUCKET.delete(oldR2Key)\n } catch (error) {\n console.warn(`Failed to move file in R2 for file ${fileId}:`, error)\n errors.push({ fileId, error: 'Failed to move file in storage' })\n continue\n }\n\n // Update database with new folder and R2 key\n const bucketName = c.env.BUCKET_NAME || 'sonicjs-media-dev'\n const newPublicUrl = `https://pub-${bucketName}.r2.dev/${newR2Key}`\n\n const updateStmt = c.env.DB.prepare(`\n UPDATE media\n SET folder = ?, r2_key = ?, public_url = ?, updated_at = ?\n WHERE id = ?\n `)\n await updateStmt.bind(\n targetFolder,\n newR2Key,\n newPublicUrl,\n Math.floor(Date.now() / 1000),\n fileId\n ).run()\n\n results.push({\n fileId,\n filename: fileRecord.original_name,\n success: true,\n skipped: false\n })\n } catch (error) {\n errors.push({\n fileId,\n error: 'Move failed',\n details: error instanceof Error ? error.message : 'Unknown error'\n })\n }\n }\n\n // Emit media move event if any moves succeeded\n if (results.length > 0) {\n await emitEvent('media.move', { count: results.length, targetFolder, ids: fileIds })\n }\n\n return c.json({\n success: results.length > 0,\n moved: results,\n errors: errors,\n summary: {\n total: fileIds.length,\n successful: results.length,\n failed: errors.length\n }\n })\n } catch (error) {\n console.error('Bulk move error:', error)\n return c.json({ error: 'Bulk move failed' }, 500)\n }\n})\n\n// Delete file\napiMediaRoutes.delete('/:id', async (c) => {\n try {\n const user = c.get('user')!\n const fileId = c.req.param('id')\n \n // Get file record\n const stmt = c.env.DB.prepare('SELECT * FROM media WHERE id = ? AND deleted_at IS NULL')\n const fileRecord = await stmt.bind(fileId).first() as any\n \n if (!fileRecord) {\n return c.json({ error: 'File not found' }, 404)\n }\n\n // Check permissions (only allow deletion by uploader or admin)\n if (fileRecord.uploaded_by !== user.userId && user.role !== 'admin') {\n return c.json({ error: 'Permission denied' }, 403)\n }\n\n // Delete from R2\n try {\n await c.env.MEDIA_BUCKET.delete(fileRecord.r2_key)\n } catch (error) {\n console.warn('Failed to delete from R2:', error)\n // Continue with database deletion even if R2 deletion fails\n }\n\n // Soft delete in database\n const deleteStmt = c.env.DB.prepare('UPDATE media SET deleted_at = ? WHERE id = ?')\n await deleteStmt.bind(Math.floor(Date.now() / 1000), fileId).run()\n\n // Emit media delete event\n await emitEvent('media.delete', { id: fileId })\n\n return c.json({ success: true, message: 'File deleted successfully' })\n } catch (error) {\n console.error('Delete error:', error)\n return c.json({ error: 'Delete failed' }, 500)\n }\n})\n\n// Update file metadata\napiMediaRoutes.patch('/:id', async (c) => {\n try {\n const user = c.get('user')!\n const fileId = c.req.param('id')\n const body = await c.req.json()\n \n // Get file record\n const stmt = c.env.DB.prepare('SELECT * FROM media WHERE id = ? AND deleted_at IS NULL')\n const fileRecord = await stmt.bind(fileId).first() as any\n \n if (!fileRecord) {\n return c.json({ error: 'File not found' }, 404)\n }\n\n // Check permissions (only allow updates by uploader or admin)\n if (fileRecord.uploaded_by !== user.userId && user.role !== 'admin') {\n return c.json({ error: 'Permission denied' }, 403)\n }\n\n // Update allowed fields\n const allowedFields = ['alt', 'caption', 'tags', 'folder']\n const updates = []\n const values = []\n \n for (const [key, value] of Object.entries(body)) {\n if (allowedFields.includes(key)) {\n updates.push(`${key} = ?`)\n values.push(key === 'tags' ? JSON.stringify(value) : value)\n }\n }\n\n if (updates.length === 0) {\n return c.json({ error: 'No valid fields to update' }, 400)\n }\n\n updates.push('updated_at = ?')\n values.push(Math.floor(Date.now() / 1000))\n values.push(fileId)\n\n const updateStmt = c.env.DB.prepare(`\n UPDATE media SET ${updates.join(', ')} WHERE id = ?\n `)\n await updateStmt.bind(...values).run()\n\n // Emit media update event\n await emitEvent('media.update', { id: fileId })\n\n return c.json({ success: true, message: 'File updated successfully' })\n } catch (error) {\n console.error('Update error:', error)\n return c.json({ error: 'Update failed' }, 500)\n }\n})\n\n// Helper function to extract image dimensions\nasync function getImageDimensions(arrayBuffer: ArrayBuffer): Promise<{ width: number; height: number }> {\n // This is a simplified implementation\n // In a real-world scenario, you'd use a proper image processing library\n const uint8Array = new Uint8Array(arrayBuffer)\n \n // Check for JPEG\n if (uint8Array[0] === 0xFF && uint8Array[1] === 0xD8) {\n return getJPEGDimensions(uint8Array)\n }\n \n // Check for PNG\n if (uint8Array[0] === 0x89 && uint8Array[1] === 0x50 && uint8Array[2] === 0x4E && uint8Array[3] === 0x47) {\n return getPNGDimensions(uint8Array)\n }\n \n // Default fallback\n return { width: 0, height: 0 }\n}\n\nfunction getJPEGDimensions(uint8Array: Uint8Array): { width: number; height: number } {\n let i = 2\n while (i < uint8Array.length) {\n if (i + 8 >= uint8Array.length) break\n if (uint8Array[i] === 0xFF && uint8Array[i + 1] === 0xC0) {\n if (i + 8 < uint8Array.length) {\n return {\n height: (uint8Array[i + 5]! << 8) | uint8Array[i + 6]!,\n width: (uint8Array[i + 7]! << 8) | uint8Array[i + 8]!\n }\n }\n }\n if (i + 3 < uint8Array.length) {\n i += 2 + ((uint8Array[i + 2]! << 8) | uint8Array[i + 3]!)\n } else {\n break\n }\n }\n return { width: 0, height: 0 }\n}\n\nfunction getPNGDimensions(uint8Array: Uint8Array): { width: number; height: number } {\n if (uint8Array.length < 24) {\n return { width: 0, height: 0 }\n }\n return {\n width: (uint8Array[16]! << 24) | (uint8Array[17]! << 16) | (uint8Array[18]! << 8) | uint8Array[19]!,\n height: (uint8Array[20]! << 24) | (uint8Array[21]! << 16) | (uint8Array[22]! << 8) | uint8Array[23]!\n }\n}\n\nexport default apiMediaRoutes","/**\n * API System Routes\n *\n * Provides system health, status, and metadata endpoints\n * These are lightweight routes without heavy dependencies\n */\n\nimport { Hono } from 'hono'\nimport type { Bindings, Variables } from '../app'\n\nexport const apiSystemRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n/**\n * System health check\n * GET /api/system/health\n */\napiSystemRoutes.get('/health', async (c) => {\n try {\n const startTime = Date.now()\n\n // Check database connectivity\n let dbStatus = 'unknown'\n let dbLatency = 0\n\n try {\n const dbStart = Date.now()\n await c.env.DB.prepare('SELECT 1').first()\n dbLatency = Date.now() - dbStart\n dbStatus = 'healthy'\n } catch (error) {\n console.error('Database health check failed:', error)\n dbStatus = 'unhealthy'\n }\n\n // Check KV connectivity (if available)\n let kvStatus = 'not_configured'\n let kvLatency = 0\n\n if (c.env.CACHE_KV) {\n try {\n const kvStart = Date.now()\n await c.env.CACHE_KV.get('__health_check__')\n kvLatency = Date.now() - kvStart\n kvStatus = 'healthy'\n } catch (error) {\n console.error('KV health check failed:', error)\n kvStatus = 'unhealthy'\n }\n }\n\n // Check R2 connectivity (if available)\n let r2Status = 'not_configured'\n\n if (c.env.MEDIA_BUCKET) {\n try {\n await c.env.MEDIA_BUCKET.head('__health_check__')\n r2Status = 'healthy'\n } catch (error) {\n // R2 head on non-existent key returns null, not an error\n // This is expected, so we consider it healthy\n r2Status = 'healthy'\n }\n }\n\n const totalLatency = Date.now() - startTime\n const overall = dbStatus === 'healthy' ? 'healthy' : 'degraded'\n\n return c.json({\n status: overall,\n timestamp: new Date().toISOString(),\n uptime: totalLatency,\n checks: {\n database: {\n status: dbStatus,\n latency: dbLatency\n },\n cache: {\n status: kvStatus,\n latency: kvLatency\n },\n storage: {\n status: r2Status\n }\n },\n environment: c.env.ENVIRONMENT || 'production'\n })\n } catch (error) {\n console.error('Health check failed:', error)\n return c.json({\n status: 'unhealthy',\n timestamp: new Date().toISOString(),\n error: 'Health check failed'\n }, 503)\n }\n})\n\n/**\n * System information\n * GET /api/system/info\n */\napiSystemRoutes.get('/info', (c) => {\n const appVersion = c.get('appVersion') || '1.0.0'\n\n return c.json({\n name: 'SonicJS',\n version: appVersion,\n description: 'Modern headless CMS built on Cloudflare Workers',\n endpoints: {\n api: '/api',\n auth: '/auth',\n health: '/api/system/health',\n docs: '/docs'\n },\n features: {\n content: true,\n media: true,\n auth: true,\n collections: true,\n caching: !!c.env.CACHE_KV,\n storage: !!c.env.MEDIA_BUCKET\n },\n timestamp: new Date().toISOString()\n })\n})\n\n/**\n * System stats\n * GET /api/system/stats\n */\napiSystemRoutes.get('/stats', async (c) => {\n try {\n const db = c.env.DB\n\n // Get content statistics\n const contentStats = await db.prepare(`\n SELECT COUNT(*) as total_content\n FROM content\n WHERE deleted_at IS NULL\n `).first() as any\n\n // Get media statistics\n const mediaStats = await db.prepare(`\n SELECT\n COUNT(*) as total_files,\n SUM(size) as total_size\n FROM media\n WHERE deleted_at IS NULL\n `).first() as any\n\n // Get user statistics\n const userStats = await db.prepare(`\n SELECT COUNT(*) as total_users\n FROM users\n `).first() as any\n\n return c.json({\n content: {\n total: contentStats?.total_content || 0\n },\n media: {\n total_files: mediaStats?.total_files || 0,\n total_size_bytes: mediaStats?.total_size || 0,\n total_size_mb: Math.round((mediaStats?.total_size || 0) / 1024 / 1024 * 100) / 100\n },\n users: {\n total: userStats?.total_users || 0\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Stats query failed:', error)\n return c.json({ error: 'Failed to fetch system statistics' }, 500)\n }\n})\n\n/**\n * Database ping\n * GET /api/system/ping\n */\napiSystemRoutes.get('/ping', async (c) => {\n try {\n const start = Date.now()\n await c.env.DB.prepare('SELECT 1').first()\n const latency = Date.now() - start\n\n return c.json({\n pong: true,\n latency,\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Ping failed:', error)\n return c.json({\n pong: false,\n error: 'Database connection failed'\n }, 503)\n }\n})\n\n/**\n * Environment check\n * GET /api/system/env\n */\napiSystemRoutes.get('/env', (c) => {\n return c.json({\n environment: c.env.ENVIRONMENT || 'production',\n features: {\n database: !!c.env.DB,\n cache: !!c.env.CACHE_KV,\n media_bucket: !!c.env.MEDIA_BUCKET,\n email_queue: !!c.env.EMAIL_QUEUE,\n sendgrid: !!c.env.SENDGRID_API_KEY,\n cloudflare_images: !!(c.env.IMAGES_ACCOUNT_ID && c.env.IMAGES_API_TOKEN)\n },\n timestamp: new Date().toISOString()\n })\n})\n\nexport default apiSystemRoutes\n","/**\n * Admin API Routes\n *\n * Provides JSON API endpoints for admin operations\n * These routes complement the admin UI and can be used programmatically\n */\n\nimport { Hono } from 'hono'\nimport { z } from 'zod'\nimport { zValidator } from '@hono/zod-validator'\nimport { requireAuth, requireRole } from '../middleware'\nimport type { Bindings, Variables } from '../app'\n\nexport const adminApiRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Apply auth middleware to all admin routes\nadminApiRoutes.use('*', requireAuth())\nadminApiRoutes.use('*', requireRole(['admin', 'editor']))\n\n/**\n * Get dashboard statistics\n * GET /admin/api/stats\n */\nadminApiRoutes.get('/stats', async (c) => {\n try {\n const db = c.env.DB\n\n // Get collections count\n let collectionsCount = 0\n try {\n const collectionsStmt = db.prepare('SELECT COUNT(*) as count FROM collections WHERE is_active = 1')\n const collectionsResult = await collectionsStmt.first()\n collectionsCount = (collectionsResult as any)?.count || 0\n } catch (error) {\n console.error('Error fetching collections count:', error)\n }\n\n // Get content count\n let contentCount = 0\n try {\n const contentStmt = db.prepare('SELECT COUNT(*) as count FROM content WHERE deleted_at IS NULL')\n const contentResult = await contentStmt.first()\n contentCount = (contentResult as any)?.count || 0\n } catch (error) {\n console.error('Error fetching content count:', error)\n }\n\n // Get media count and total size\n let mediaCount = 0\n let mediaSize = 0\n try {\n const mediaStmt = db.prepare('SELECT COUNT(*) as count, COALESCE(SUM(size), 0) as total_size FROM media WHERE deleted_at IS NULL')\n const mediaResult = await mediaStmt.first()\n mediaCount = (mediaResult as any)?.count || 0\n mediaSize = (mediaResult as any)?.total_size || 0\n } catch (error) {\n console.error('Error fetching media count:', error)\n }\n\n // Get users count\n let usersCount = 0\n try {\n const usersStmt = db.prepare('SELECT COUNT(*) as count FROM users WHERE is_active = 1')\n const usersResult = await usersStmt.first()\n usersCount = (usersResult as any)?.count || 0\n } catch (error) {\n console.error('Error fetching users count:', error)\n }\n\n return c.json({\n collections: collectionsCount,\n contentItems: contentCount,\n mediaFiles: mediaCount,\n mediaSize: mediaSize,\n users: usersCount,\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Error fetching stats:', error)\n return c.json({ error: 'Failed to fetch statistics' }, 500)\n }\n})\n\n/**\n * Get storage usage\n * GET /admin/api/storage\n */\nadminApiRoutes.get('/storage', async (c) => {\n try {\n const db = c.env.DB\n\n // Get database size from D1 metadata\n let databaseSize = 0\n try {\n const result = await db.prepare('SELECT 1').run()\n databaseSize = (result as any)?.meta?.size_after || 0\n } catch (error) {\n console.error('Error fetching database size:', error)\n }\n\n // Get media total size\n let mediaSize = 0\n try {\n const mediaStmt = db.prepare('SELECT COALESCE(SUM(size), 0) as total_size FROM media WHERE deleted_at IS NULL')\n const mediaResult = await mediaStmt.first()\n mediaSize = (mediaResult as any)?.total_size || 0\n } catch (error) {\n console.error('Error fetching media size:', error)\n }\n\n return c.json({\n databaseSize,\n mediaSize,\n totalSize: databaseSize + mediaSize,\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Error fetching storage usage:', error)\n return c.json({ error: 'Failed to fetch storage usage' }, 500)\n }\n})\n\n/**\n * Get recent activity\n * GET /admin/api/activity\n */\nadminApiRoutes.get('/activity', async (c) => {\n try {\n const db = c.env.DB\n const limit = parseInt(c.req.query('limit') || '10')\n\n // Get recent activities from activity_logs table\n const activityStmt = db.prepare(`\n SELECT\n a.id,\n a.action,\n a.resource_type,\n a.resource_id,\n a.details,\n a.created_at,\n u.email,\n u.first_name,\n u.last_name\n FROM activity_logs a\n LEFT JOIN users u ON a.user_id = u.id\n WHERE a.resource_type IN ('content', 'collections', 'users', 'media')\n ORDER BY a.created_at DESC\n LIMIT ?\n `)\n\n const { results } = await activityStmt.bind(limit).all()\n\n const recentActivity = (results || []).map((row: any) => {\n const userName = row.first_name && row.last_name\n ? `${row.first_name} ${row.last_name}`\n : row.email || 'System'\n\n let details: any = {}\n try {\n details = row.details ? JSON.parse(row.details) : {}\n } catch (e) {\n console.error('Error parsing activity details:', e)\n }\n\n return {\n id: row.id,\n type: row.resource_type,\n action: row.action,\n resource_id: row.resource_id,\n details,\n timestamp: new Date(Number(row.created_at)).toISOString(),\n user: userName\n }\n })\n\n return c.json({\n data: recentActivity,\n count: recentActivity.length,\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Error fetching recent activity:', error)\n return c.json({ error: 'Failed to fetch recent activity' }, 500)\n }\n})\n\n/**\n * Collection management schema\n */\nconst createCollectionSchema = z.object({\n name: z.string().min(1).max(255).regex(/^[a-z0-9_]+$/, 'Must contain only lowercase letters, numbers, and underscores'),\n display_name: z.string().min(1).max(255),\n description: z.string().optional()\n})\n\nconst updateCollectionSchema = z.object({\n display_name: z.string().min(1).max(255).optional(),\n description: z.string().optional(),\n is_active: z.boolean().optional()\n})\n\n/**\n * Get all collections\n * GET /admin/api/collections\n */\nadminApiRoutes.get('/collections', async (c) => {\n try {\n const db = c.env.DB\n const search = c.req.query('search') || ''\n const includeInactive = c.req.query('includeInactive') === 'true'\n\n let stmt\n let results\n\n if (search) {\n stmt = db.prepare(`\n SELECT id, name, display_name, description, created_at, updated_at, is_active, managed\n FROM collections\n WHERE ${includeInactive ? '1=1' : 'is_active = 1'}\n AND (name LIKE ? OR display_name LIKE ? OR description LIKE ?)\n ORDER BY created_at DESC\n `)\n const searchParam = `%${search}%`\n const queryResults = await stmt.bind(searchParam, searchParam, searchParam).all()\n results = queryResults.results\n } else {\n stmt = db.prepare(`\n SELECT id, name, display_name, description, created_at, updated_at, is_active, managed\n FROM collections\n ${includeInactive ? '' : 'WHERE is_active = 1'}\n ORDER BY created_at DESC\n `)\n const queryResults = await stmt.all()\n results = queryResults.results\n }\n\n // Get field counts\n const fieldCountStmt = db.prepare('SELECT collection_id, COUNT(*) as count FROM content_fields GROUP BY collection_id')\n const { results: fieldCountResults } = await fieldCountStmt.all()\n const fieldCounts = new Map((fieldCountResults || []).map((row: any) => [String(row.collection_id), Number(row.count)]))\n\n const collections = (results || []).map((row: any) => ({\n id: row.id,\n name: row.name,\n display_name: row.display_name,\n description: row.description,\n created_at: Number(row.created_at),\n updated_at: Number(row.updated_at),\n is_active: row.is_active === 1,\n managed: row.managed === 1,\n field_count: fieldCounts.get(String(row.id)) || 0\n }))\n\n return c.json({\n data: collections,\n count: collections.length,\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Error fetching collections:', error)\n return c.json({ error: 'Failed to fetch collections' }, 500)\n }\n})\n\n/**\n * Get single collection\n * GET /admin/api/collections/:id\n */\nadminApiRoutes.get('/collections/:id', async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n\n const stmt = db.prepare('SELECT * FROM collections WHERE id = ?')\n const collection = await stmt.bind(id).first() as any\n\n if (!collection) {\n return c.json({ error: 'Collection not found' }, 404)\n }\n\n // Get collection fields\n const fieldsStmt = db.prepare(`\n SELECT * FROM content_fields\n WHERE collection_id = ?\n ORDER BY field_order ASC\n `)\n const { results: fieldsResults } = await fieldsStmt.bind(id).all()\n\n const fields = (fieldsResults || []).map((row: any) => ({\n id: row.id,\n field_name: row.field_name,\n field_type: row.field_type,\n field_label: row.field_label,\n field_options: row.field_options ? JSON.parse(row.field_options) : {},\n field_order: row.field_order,\n is_required: row.is_required === 1,\n is_searchable: row.is_searchable === 1,\n created_at: Number(row.created_at),\n updated_at: Number(row.updated_at)\n }))\n\n return c.json({\n data: {\n ...collection,\n is_active: collection.is_active === 1,\n managed: collection.managed === 1,\n schema: collection.schema ? JSON.parse(collection.schema) : null,\n created_at: Number(collection.created_at),\n updated_at: Number(collection.updated_at),\n fields\n }\n })\n } catch (error) {\n console.error('Error fetching collection:', error)\n return c.json({ error: 'Failed to fetch collection' }, 500)\n }\n})\n\n/**\n * Create collection\n * POST /admin/api/collections\n */\nadminApiRoutes.post('/collections', async (c) => {\n try {\n const body = await c.req.json()\n const validation = createCollectionSchema.safeParse(body)\n if (!validation.success) {\n return c.json({ error: 'Validation failed', details: validation.error.errors }, 400)\n }\n const validatedData = validation.data\n const db = c.env.DB\n const user = c.get('user')\n\n // Check if collection already exists\n const existingStmt = db.prepare('SELECT id FROM collections WHERE name = ?')\n const existing = await existingStmt.bind(validatedData.name).first()\n\n if (existing) {\n return c.json({ error: 'A collection with this name already exists' }, 400)\n }\n\n // Create basic schema\n const basicSchema = {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n title: \"Title\",\n required: true\n },\n content: {\n type: \"string\",\n title: \"Content\",\n format: \"richtext\"\n },\n status: {\n type: \"string\",\n title: \"Status\",\n enum: [\"draft\", \"published\", \"archived\"],\n default: \"draft\"\n }\n },\n required: [\"title\"]\n }\n\n const collectionId = crypto.randomUUID()\n const now = Date.now()\n\n const insertStmt = db.prepare(`\n INSERT INTO collections (id, name, display_name, description, schema, is_active, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `)\n\n await insertStmt.bind(\n collectionId,\n validatedData.name,\n validatedData.display_name,\n validatedData.description || null,\n JSON.stringify(basicSchema),\n 1, // is_active\n now,\n now\n ).run()\n\n // Clear cache\n try {\n await c.env.CACHE_KV.delete('cache:collections:all')\n await c.env.CACHE_KV.delete(`cache:collection:${validatedData.name}`)\n } catch (e) {\n console.error('Error clearing cache:', e)\n }\n\n return c.json({\n data: {\n id: collectionId,\n name: validatedData.name,\n display_name: validatedData.display_name,\n description: validatedData.description,\n created_at: now\n }\n }, 201)\n } catch (error) {\n console.error('Error creating collection:', error)\n return c.json({ error: 'Failed to create collection' }, 500)\n }\n})\n\n/**\n * Update collection\n * PATCH /admin/api/collections/:id\n */\nadminApiRoutes.patch('/collections/:id', async (c) => {\n try {\n const id = c.req.param('id')\n const body = await c.req.json()\n const validation = updateCollectionSchema.safeParse(body)\n if (!validation.success) {\n return c.json({ error: 'Validation failed', details: validation.error.errors }, 400)\n }\n const validatedData = validation.data\n const db = c.env.DB\n\n // Check if collection exists\n const checkStmt = db.prepare('SELECT * FROM collections WHERE id = ?')\n const existing = await checkStmt.bind(id).first() as any\n\n if (!existing) {\n return c.json({ error: 'Collection not found' }, 404)\n }\n\n // Build update query\n const updateFields: string[] = []\n const updateParams: any[] = []\n\n if (validatedData.display_name !== undefined) {\n updateFields.push('display_name = ?')\n updateParams.push(validatedData.display_name)\n }\n\n if (validatedData.description !== undefined) {\n updateFields.push('description = ?')\n updateParams.push(validatedData.description)\n }\n\n if (validatedData.is_active !== undefined) {\n updateFields.push('is_active = ?')\n updateParams.push(validatedData.is_active ? 1 : 0)\n }\n\n if (updateFields.length === 0) {\n return c.json({ error: 'No fields to update' }, 400)\n }\n\n updateFields.push('updated_at = ?')\n updateParams.push(Date.now())\n updateParams.push(id)\n\n const updateStmt = db.prepare(`\n UPDATE collections\n SET ${updateFields.join(', ')}\n WHERE id = ?\n `)\n\n await updateStmt.bind(...updateParams).run()\n\n // Clear cache\n try {\n await c.env.CACHE_KV.delete('cache:collections:all')\n await c.env.CACHE_KV.delete(`cache:collection:${existing.name}`)\n } catch (e) {\n console.error('Error clearing cache:', e)\n }\n\n return c.json({ message: 'Collection updated successfully' })\n } catch (error) {\n console.error('Error updating collection:', error)\n return c.json({ error: 'Failed to update collection' }, 500)\n }\n})\n\n/**\n * Delete collection\n * DELETE /admin/api/collections/:id\n */\nadminApiRoutes.delete('/collections/:id', async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n\n // Check if collection has content\n const contentStmt = db.prepare('SELECT COUNT(*) as count FROM content WHERE collection_id = ?')\n const contentResult = await contentStmt.bind(id).first() as any\n\n if (contentResult && contentResult.count > 0) {\n return c.json({\n error: `Cannot delete collection: it contains ${contentResult.count} content item(s). Delete all content first.`\n }, 400)\n }\n\n // Get collection name for cache clearing\n const collectionStmt = db.prepare('SELECT name FROM collections WHERE id = ?')\n const collection = await collectionStmt.bind(id).first() as any\n\n // Delete collection fields first\n const deleteFieldsStmt = db.prepare('DELETE FROM content_fields WHERE collection_id = ?')\n await deleteFieldsStmt.bind(id).run()\n\n // Delete collection\n const deleteStmt = db.prepare('DELETE FROM collections WHERE id = ?')\n await deleteStmt.bind(id).run()\n\n // Clear cache\n try {\n await c.env.CACHE_KV.delete('cache:collections:all')\n if (collection) {\n await c.env.CACHE_KV.delete(`cache:collection:${collection.name}`)\n }\n } catch (e) {\n console.error('Error clearing cache:', e)\n }\n\n return c.json({ message: 'Collection deleted successfully' })\n } catch (error) {\n console.error('Error deleting collection:', error)\n return c.json({ error: 'Failed to delete collection' }, 500)\n }\n})\n\nexport default adminApiRoutes\n","import { renderAlert } from '../alert.template'\n\nexport interface LoginPageData {\n error?: string\n message?: string\n version?: string\n}\n\nexport function renderLoginPage(data: LoginPageData, demoLoginActive: boolean = false): string {\n return `\n <!DOCTYPE html>\n <html lang=\"en\" class=\"h-full dark\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Login - SonicJS AI</title>\n <link rel=\"icon\" type=\"image/x-icon\" href=\"https://demo.sonicjs.com/images/favicon.ico\">\n <script src=\"https://unpkg.com/htmx.org@2.0.3\"></script>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <script>\n tailwind.config = {\n darkMode: 'class',\n theme: {\n extend: {\n colors: {\n error: '#ef4444'\n }\n }\n }\n }\n </script>\n <style>\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n\n body {\n font-family: 'Inter', system-ui, -apple-system, sans-serif;\n }\n </style>\n </head>\n <body class=\"h-full bg-zinc-950\">\n <div class=\"flex min-h-full flex-col justify-center py-12 sm:px-6 lg:px-8\">\n <!-- Logo Section -->\n <div class=\"sm:mx-auto sm:w-full sm:max-w-md text-center\">\n <div class=\"mx-auto w-64 mb-8\">\n <svg class=\"w-full h-auto\" viewBox=\"380 1300 2250 400\" aria-hidden=\"true\">\n <path fill=\"#F1F2F2\" d=\"M476.851,1404.673h168.536c4.714,0,8.695-1.618,11.944-4.866c3.241-3.241,4.866-7.222,4.866-11.943 c0-2.357-0.443-4.569-1.327-6.636c-0.885-2.06-2.067-3.829-3.539-5.308c-1.479-1.472-3.249-2.654-5.308-3.538 c-2.067-0.885-4.279-1.327-6.635-1.327H476.851c-20.057,0-37.158,7.154-51.313,21.454c-14.155,14.308-21.233,31.483-21.233,51.534 c0,20.058,7.078,37.234,21.233,51.534c14.155,14.308,31.255,21.454,51.313,21.454h112.357c10.907,0,20.196,3.837,27.868,11.502 c7.666,7.672,11.502,16.885,11.502,27.646c0,10.769-3.836,19.982-11.502,27.647c-7.672,7.673-16.961,11.502-27.868,11.502H421.115 c-4.721,0-8.702,1.624-11.944,4.865c-3.248,3.249-4.866,7.23-4.866,11.944c0,3.248,0.733,6.123,2.212,8.626 c1.472,2.509,3.462,4.499,5.971,5.972c2.502,1.472,5.378,2.212,8.626,2.212h168.094c20.052,0,37.227-7.078,51.534-21.234 c14.3-14.155,21.454-31.331,21.454-51.534c0-20.196-7.154-37.379-21.454-51.534c-14.308-14.156-31.483-21.234-51.534-21.234 H476.851c-10.616,0-19.76-3.905-27.426-11.721c-7.672-7.811-11.501-17.101-11.501-27.87c0-10.761,3.829-19.975,11.501-27.647 C457.091,1408.508,466.235,1404.673,476.851,1404.673z\"></path>\n <path fill=\"#F1F2F2\" d=\"M974.78,1398.211c-5.016,6.574-10.034,13.146-15.048,19.721c-1.828,2.398-3.657,4.796-5.487,7.194 c1.994,1.719,3.958,3.51,5.873,5.424c18.724,18.731,28.089,41.216,28.089,67.459c0,26.251-9.366,48.658-28.089,67.237 c-18.731,18.579-41.215,27.868-67.459,27.868c-9.848,0-19.156-1.308-27.923-3.923l-4.185,3.354 c-8.587,6.885-17.154,13.796-25.725,20.702c17.52,8.967,36.86,13.487,58.054,13.487c35.533,0,65.91-12.608,91.124-37.821 c25.214-25.215,37.821-55.584,37.821-91.125c0-35.534-12.607-65.911-37.821-91.126 C981.004,1403.663,977.926,1400.854,974.78,1398.211z\"></path>\n <path fill=\"#F1F2F2\" d=\"M1364.644,1439.619c-4.72,0-8.702,1.624-11.943,4.865c-3.249,3.249-4.866,7.23-4.866,11.944v138.014 l-167.651-211.003c-0.297-0.586-0.74-1.03-1.327-1.326c-4.721-4.714-10.249-7.742-16.588-9.069 c-6.346-1.326-12.608-0.732-18.801,1.77c-6.192,2.509-11.059,6.49-14.598,11.944c-3.539,5.46-5.308,11.577-5.308,18.357v208.348 c0,4.721,1.618,8.703,4.866,11.944c3.241,3.241,7.222,4.865,11.943,4.865c2.945,0,5.751-0.738,8.405-2.211 c2.654-1.472,4.713-3.463,6.193-5.971c1.473-2.503,2.212-5.378,2.212-8.627v-205.251l166.325,209.675 c2.06,2.654,4.423,4.865,7.078,6.635c5.308,3.829,11.349,5.75,18.137,5.75c5.308,0,10.464-1.182,15.482-3.538 c3.539-1.769,6.56-4.127,9.069-7.078c2.502-2.945,4.491-6.338,5.971-10.175c1.473-3.829,2.212-7.664,2.212-11.501v-141.552 c0-4.714-1.624-8.695-4.865-11.944C1373.339,1441.243,1369.359,1439.619,1364.644,1439.619z\"></path>\n <path fill=\"#F1F2F2\" d=\"M1508.406,1432.983c-2.654-1.472-5.46-2.212-8.404-2.212c-4.721,0-8.703,1.7-11.944,5.087 c-3.249,3.395-4.865,7.3-4.865,11.723v163.228c0,4.721,1.616,8.702,4.865,11.943c3.241,3.249,7.223,4.866,11.944,4.866 c2.944,0,5.751-0.732,8.404-2.212c2.655-1.472,4.714-3.539,6.193-6.194c1.473-2.654,2.213-5.453,2.213-8.404V1447.58 c0-2.945-0.74-5.75-2.213-8.405C1513.12,1436.522,1511.06,1434.462,1508.406,1432.983z\"></path>\n <path fill=\"#F1F2F2\" d=\"M1499.78,1367.957c-4.575,0-8.481,1.625-11.722,4.866c-3.249,3.249-4.865,7.23-4.865,11.943 c0,2.951,0.732,5.75,2.212,8.405c1.472,2.654,3.463,4.721,5.971,6.193c2.503,1.479,5.378,2.212,8.627,2.212 c4.423,0,8.328-1.618,11.721-4.865c3.387-3.243,5.088-7.224,5.088-11.944c0-4.713-1.701-8.694-5.088-11.943 C1508.33,1369.582,1504.349,1367.957,1499.78,1367.957z\"></path>\n <path fill=\"#F1F2F2\" d=\"M1859.627,1369.727H1747.27c-35.388,0-65.69,12.607-90.904,37.821 c-25.213,25.215-37.82,55.591-37.82,91.125c0,35.54,12.607,65.911,37.82,91.125c25.215,25.215,55.516,37.821,90.904,37.821h56.178 c4.714,0,8.695-1.618,11.944-4.866c3.241-3.241,4.865-7.222,4.865-11.943c0-4.714-1.624-8.695-4.865-11.943 c-3.249-3.243-7.23-4.866-11.944-4.866h-56.178c-26.251,0-48.659-9.359-67.237-28.09c-18.579-18.723-27.868-41.207-27.868-67.459 c0-26.243,9.29-48.659,27.868-67.237c18.579-18.579,40.987-27.868,67.237-27.868h112.357c4.714,0,8.696-1.693,11.944-5.087 c3.241-3.387,4.865-7.368,4.865-11.943c0-4.569-1.624-8.475-4.865-11.723C1868.322,1371.351,1864.341,1369.727,1859.627,1369.727z \"></path>\n <path fill=\"#06b6d4\" d=\"M2219.256,1371.054h-112.357c-4.423,0-8.336,1.624-11.723,4.865c-3.393,3.249-5.087,7.23-5.087,11.944 c0,4.721,1.694,8.702,5.087,11.943c3.387,3.249,7.3,4.866,11.723,4.866h95.547v95.105c0,26.251-9.365,48.659-28.088,67.237 c-18.731,18.579-41.215,27.868-67.459,27.868c-26.251,0-48.659-9.289-67.237-27.868c-18.579-18.579-27.868-40.987-27.868-67.237 c0-4.713-1.701-8.771-5.088-12.165c-3.393-3.387-7.374-5.087-11.943-5.087c-4.575,0-8.481,1.7-11.722,5.087 c-3.249,3.393-4.865,7.451-4.865,12.165c0,35.388,12.607,65.69,37.82,90.904c25.215,25.213,55.584,37.82,91.126,37.82 c35.532,0,65.91-12.607,91.125-37.82c25.214-25.215,37.82-55.516,37.82-90.904v-111.915c0-4.714-1.624-8.695-4.865-11.944 C2227.951,1372.678,2223.971,1371.054,2219.256,1371.054z\"></path>\n <path fill=\"#06b6d4\" d=\"M2574.24,1502.875c-14.306-14.156-31.483-21.234-51.533-21.234H2410.35 c-10.617,0-19.762-3.829-27.426-11.501c-7.672-7.664-11.501-16.954-11.501-27.868c0-10.907,3.829-20.196,11.501-27.868 c7.664-7.664,16.809-11.501,27.426-11.501h112.357c4.714,0,8.695-1.617,11.944-4.866c3.241-3.241,4.865-7.222,4.865-11.943 c0-4.714-1.624-8.695-4.865-11.944c-3.249-3.241-7.23-4.865-11.944-4.865H2410.35c-20.058,0-37.158,7.154-51.313,21.454 c-14.156,14.308-21.232,31.483-21.232,51.534c0,20.058,7.077,37.234,21.232,51.534c14.156,14.308,31.255,21.454,51.313,21.454 h112.357c7.078,0,13.637,1.77,19.684,5.308c6.042,3.539,10.838,8.336,14.377,14.377c3.538,6.047,5.307,12.607,5.307,19.685 c0,10.616-3.835,19.76-11.501,27.425c-7.672,7.673-16.961,11.502-27.868,11.502h-168.094c-4.721,0-8.703,1.7-11.944,5.087 c-3.249,3.393-4.865,7.374-4.865,11.943c0,4.576,1.616,8.481,4.865,11.723c3.241,3.249,7.223,4.866,11.944,4.866h168.094 c20.051,0,37.227-7.078,51.533-21.234c14.302-14.155,21.454-31.331,21.454-51.534 C2595.695,1534.213,2588.542,1517.03,2574.24,1502.875z\"></path>\n <path fill=\"#06b6d4\" d=\"M854.024,1585.195l20.001-16.028c16.616-13.507,33.04-27.265,50.086-40.251 c1.13-0.861,2.9-1.686,2.003-3.516c-0.843-1.716-2.481-2.302-4.484-2.123c-8.514,0.765-17.016-0.538-25.537-0.353 c-1.124,0.024-2.768,0.221-3.163-1.25c-0.371-1.369,1.088-2.063,1.919-2.894c6.26-6.242,12.574-12.43,18.816-18.691 c9.303-9.327,18.565-18.714,27.851-28.066c1.848-1.859,3.701-3.713,5.549-5.572c2.655-2.661,5.309-5.315,7.958-7.982 c0.574-0.579,1.259-1.141,1.246-1.94c-0.004-0.257-0.078-0.538-0.254-0.853c-0.556-0.981-1.441-1.1-2.469-0.957 c-0.658,0.096-1.315,0.185-1.973,0.275c-3.844,0.538-7.689,1.076-11.533,1.608c-3.641,0.505-7.281,1.02-10.922,1.529 c-4.162,0.582-8.324,1.158-12.486,1.748c-1.142,0.161-2.409,1.662-3.354,0.508c-0.419-0.508-0.431-1.028-0.251-1.531 c0.269-0.741,0.957-1.441,1.387-2.021c3.414-4.58,6.882-9.124,10.356-13.662c1.74-2.272,3.48-4.544,5.214-6.822 c4.682-6.141,9.369-12.281,14.051-18.422c0.09-0.119,0.181-0.237,0.271-0.355c6.848-8.98,13.7-17.958,20.553-26.936 c0.488-0.64,0.977-1.28,1.465-1.92c2.159-2.828,4.315-5.658,6.476-8.486c4.197-5.501,8.454-10.954,12.67-16.442 c0.263-0.347,0.538-0.718,0.717-1.106c0.269-0.586,0.299-1.196-0.335-1.776c-0.825-0.753-1.8-0.15-2.595,0.419 c-0.67,0.472-1.333,0.957-1.955,1.489c-2.206,1.889-4.401,3.797-6.595,5.698c-3.958,3.438-7.922,6.876-11.976,10.194 c-2.443,2.003-4.865,4.028-7.301,6.038c-18.689-10.581-39.53-15.906-62.549-15.906c-35.54,0-65.911,12.607-91.125,37.82 c-25.214,25.215-37.821,55.592-37.821,91.126c0,35.54,12.607,65.91,37.821,91.125c4.146,4.146,8.445,7.916,12.87,11.381 c-9.015,11.14-18.036,22.277-27.034,33.429c-1.208,1.489-3.755,3.151-2.745,4.891c0.078,0.144,0.173,0.281,0.305,0.425 c1.321,1.429,3.492-1.303,4.933-2.457c6.673-5.333,13.333-10.685,19.982-16.042c3.707-2.984,7.417-5.965,11.124-8.952 c1.474-1.188,2.951-2.373,4.425-3.561c6.41-5.164,12.816-10.333,19.238-15.481L854.024,1585.195z M797.552,1498.009 c0-26.243,9.29-48.728,27.868-67.459c18.579-18.723,40.987-28.089,67.238-28.089c12.273,0,23.712,2.075,34.34,6.171 c-3.37,2.905-6.734,5.816-10.069,8.762c-6.075,5.351-12.365,10.469-18.667,15.564c-4.179,3.378-8.371,6.744-12.514,10.164 c-7.54,6.23-15.037,12.52-22.529,18.804c-7.091,5.955-14.182,11.904-21.19,17.949c-1.136,0.974-3.055,1.907-2.135,3.94 c0.831,1.836,2.774,1.417,4.341,1.578l12.145-0.599l14.151-0.698c1.031-0.102,2.192-0.257,2.89,0.632 c0.034,0.044,0.073,0.078,0.106,0.127c1.017,1.561-0.67,2.105-1.387,2.942c-6.308,7.318-12.616,14.637-18.978,21.907 c-8.161,9.339-16.353,18.649-24.544,27.958c-2.146,2.433-4.275,4.879-6.422,7.312c-1.034,1.172-2.129,2.272-1.238,3.922 c0.933,1.728,2.685,1.752,4.323,1.602c4.134-0.367,8.263-0.489,12.396-0.492c0.242,0,0.485-0.005,0.728-0.004 c2.711,0.009,5.422,0.068,8.134,0.145c2.582,0.074,5.166,0.165,7.752,0.249c0.275,1.62-0.879,2.356-1.62,3.259 c-1.333,1.626-2.667,3.247-4,4.867c-4.315,5.252-8.62,10.514-12.928,15.772c-3.562-2.725-7.007-5.733-10.324-9.051 C806.842,1546.667,797.552,1524.26,797.552,1498.009z\"></path>\n </svg>\n </div>\n <h2 class=\"mt-6 text-xl font-medium text-white\">Welcome Back</h2>\n <p class=\"mt-2 text-sm text-zinc-400\">Sign in to your account to continue</p>\n </div>\n\n <!-- Form Container -->\n <div class=\"mt-8 sm:mx-auto sm:w-full sm:max-w-md\">\n <div class=\"bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10\">\n <!-- Alerts -->\n ${data.error ? `<div class=\"mb-6\">${renderAlert({ type: 'error', message: data.error })}</div>` : ''}\n ${data.message ? `<div class=\"mb-6\">${renderAlert({ type: 'success', message: data.message })}</div>` : ''}\n\n <!-- Form Response (HTMX target) -->\n <div id=\"form-response\" class=\"mb-6\"></div>\n\n <!-- Form -->\n <form\n id=\"login-form\"\n hx-post=\"/auth/login/form\"\n hx-target=\"#form-response\"\n hx-swap=\"innerHTML\"\n class=\"space-y-6\"\n >\n <!-- Email -->\n <div>\n <label for=\"email\" class=\"block text-sm font-medium text-white mb-2\">\n Email Address\n </label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n autocomplete=\"email\"\n required\n class=\"w-full rounded-lg bg-zinc-800 px-3 py-2 text-sm text-white shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white transition-shadow\"\n placeholder=\"Enter your email\"\n >\n </div>\n\n <!-- Password -->\n <div>\n <label for=\"password\" class=\"block text-sm font-medium text-white mb-2\">\n Password\n </label>\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n autocomplete=\"current-password\"\n required\n class=\"w-full rounded-lg bg-zinc-800 px-3 py-2 text-sm text-white shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white transition-shadow\"\n placeholder=\"Enter your password\"\n >\n </div>\n\n <!-- Submit Button -->\n <button\n type=\"submit\"\n class=\"w-full rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-zinc-950 hover:bg-zinc-100 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-zinc-900 transition-colors\"\n >\n Sign In\n </button>\n </form>\n\n <!-- Links -->\n <div class=\"mt-6 text-center\">\n <p class=\"text-sm text-zinc-400\">\n Don't have an account?\n <a href=\"/auth/register\" class=\"font-semibold text-white hover:text-zinc-300 transition-colors\">Create one here</a>\n </p>\n </div>\n </div>\n\n <!-- Version -->\n <div class=\"mt-6 text-center\">\n <span class=\"inline-flex items-center rounded-md px-2.5 py-1 text-xs font-medium bg-cyan-500/10 text-cyan-400 ring-1 ring-inset ring-cyan-500/20\">\n v${data.version || '0.1.0'}\n </span>\n </div>\n </div>\n </div>\n\n ${demoLoginActive ? `\n <script>\n // Demo Login Prefill Script\n (function() {\n 'use strict';\n\n function prefillLoginForm() {\n const emailInput = document.getElementById('email');\n const passwordInput = document.getElementById('password');\n\n if (emailInput && passwordInput) {\n emailInput.value = 'admin@sonicjs.com';\n passwordInput.value = 'admin123';\n\n // Add visual indication that form is prefilled (only if not already present)\n const form = emailInput.closest('form');\n if (form && !form.querySelector('.demo-mode-notice')) {\n const notice = document.createElement('div');\n notice.className = 'demo-mode-notice mb-6 rounded-lg bg-blue-500/10 p-4 ring-1 ring-blue-500/20';\n notice.innerHTML = '<div class=\"flex items-start gap-x-3\"><svg class=\"h-5 w-5 text-blue-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/></svg><div><h3 class=\"text-sm font-semibold text-blue-300\">Demo Mode</h3><p class=\"mt-1 text-sm text-blue-400\">Login form prefilled with demo credentials</p></div></div>';\n form.insertBefore(notice, form.firstChild);\n }\n }\n }\n\n // Prefill on page load\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', prefillLoginForm);\n } else {\n prefillLoginForm();\n }\n\n // Also handle HTMX page changes (for SPA-like navigation)\n document.addEventListener('htmx:afterSwap', function(event) {\n if (event.detail.target.id === 'main-content' ||\n document.getElementById('email')) {\n setTimeout(prefillLoginForm, 100);\n }\n });\n })();\n </script>\n ` : ''}\n </body>\n </html>\n `\n}","import { renderAlert } from '../alert.template'\n\nexport interface RegisterPageData {\n error?: string\n}\n\nexport function renderRegisterPage(data: RegisterPageData): string {\n return `\n <!DOCTYPE html>\n <html lang=\"en\" class=\"h-full dark\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Register - SonicJS AI</title>\n <link rel=\"icon\" type=\"image/x-icon\" href=\"https://demo.sonicjs.com/images/favicon.ico\">\n <script src=\"https://unpkg.com/htmx.org@2.0.3\"></script>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <script>\n tailwind.config = {\n darkMode: 'class',\n theme: {\n extend: {}\n }\n }\n </script>\n <style>\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n\n body {\n font-family: 'Inter', system-ui, -apple-system, sans-serif;\n }\n </style>\n </head>\n <body class=\"h-full bg-zinc-950\">\n <div class=\"flex min-h-full flex-col justify-center py-12 sm:px-6 lg:px-8\">\n <!-- Logo Section -->\n <div class=\"sm:mx-auto sm:w-full sm:max-w-md text-center\">\n <div class=\"mx-auto flex h-12 w-12 items-center justify-center rounded-lg bg-white\">\n <svg class=\"h-7 w-7 text-zinc-950\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 10V3L4 14h7v7l9-11h-7z\"/>\n </svg>\n </div>\n <h1 class=\"mt-6 text-3xl font-semibold tracking-tight text-white\">SonicJS AI</h1>\n <p class=\"mt-2 text-sm text-zinc-400\">Create your account and get started</p>\n </div>\n\n <!-- Form Container -->\n <div class=\"mt-8 sm:mx-auto sm:w-full sm:max-w-md\">\n <div class=\"bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10\">\n <!-- Alerts -->\n ${data.error ? `<div class=\"mb-6\">${renderAlert({ type: 'error', message: data.error })}</div>` : ''}\n\n <!-- Form -->\n <form\n id=\"register-form\"\n hx-post=\"/auth/register/form\"\n hx-target=\"#form-response\"\n hx-swap=\"innerHTML\"\n class=\"space-y-6\"\n >\n <!-- First and Last Name -->\n <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div>\n <label for=\"firstName\" class=\"block text-sm font-medium text-white mb-2\">\n First Name\n </label>\n <input\n id=\"firstName\"\n name=\"firstName\"\n type=\"text\"\n required\n class=\"w-full rounded-lg bg-zinc-800 px-3 py-2 text-sm text-white shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white transition-shadow\"\n placeholder=\"First name\"\n >\n </div>\n <div>\n <label for=\"lastName\" class=\"block text-sm font-medium text-white mb-2\">\n Last Name\n </label>\n <input\n id=\"lastName\"\n name=\"lastName\"\n type=\"text\"\n required\n class=\"w-full rounded-lg bg-zinc-800 px-3 py-2 text-sm text-white shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white transition-shadow\"\n placeholder=\"Last name\"\n >\n </div>\n </div>\n\n <!-- Username -->\n <div>\n <label for=\"username\" class=\"block text-sm font-medium text-white mb-2\">\n Username\n </label>\n <input\n id=\"username\"\n name=\"username\"\n type=\"text\"\n required\n class=\"w-full rounded-lg bg-zinc-800 px-3 py-2 text-sm text-white shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white transition-shadow\"\n placeholder=\"Choose a username\"\n >\n </div>\n\n <!-- Email -->\n <div>\n <label for=\"email\" class=\"block text-sm font-medium text-white mb-2\">\n Email Address\n </label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n autocomplete=\"email\"\n required\n class=\"w-full rounded-lg bg-zinc-800 px-3 py-2 text-sm text-white shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white transition-shadow\"\n placeholder=\"Enter your email\"\n >\n </div>\n\n <!-- Password -->\n <div>\n <label for=\"password\" class=\"block text-sm font-medium text-white mb-2\">\n Password\n </label>\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n autocomplete=\"new-password\"\n required\n minlength=\"8\"\n class=\"w-full rounded-lg bg-zinc-800 px-3 py-2 text-sm text-white shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white transition-shadow\"\n placeholder=\"Create a password (min. 8 characters)\"\n >\n </div>\n\n <!-- Submit Button -->\n <button\n type=\"submit\"\n class=\"w-full rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-zinc-950 hover:bg-zinc-100 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-zinc-900 transition-colors\"\n >\n Create Account\n </button>\n </form>\n\n <!-- Links -->\n <div class=\"mt-6 text-center\">\n <p class=\"text-sm text-zinc-400\">\n Already have an account?\n <a href=\"/auth/login\" class=\"font-semibold text-white hover:text-zinc-300 transition-colors\">Sign in here</a>\n </p>\n </div>\n\n <div id=\"form-response\"></div>\n </div>\n </div>\n </div>\n </body>\n </html>\n `\n}","import { z } from 'zod'\nimport type { D1Database } from '@cloudflare/workers-types'\n\nexport interface FieldConfig {\n required: boolean\n minLength: number\n label: string\n type: string\n}\n\nexport interface AuthSettings {\n requiredFields: {\n email: FieldConfig\n password: FieldConfig\n username: FieldConfig\n firstName: FieldConfig\n lastName: FieldConfig\n }\n validation: {\n emailFormat: boolean\n allowDuplicateUsernames: boolean\n passwordRequirements: {\n requireUppercase: boolean\n requireLowercase: boolean\n requireNumbers: boolean\n requireSpecialChars: boolean\n }\n }\n registration: {\n enabled: boolean\n requireEmailVerification: boolean\n defaultRole: string\n }\n}\n\nexport class AuthValidationService {\n private static instance: AuthValidationService\n private cachedSettings: AuthSettings | null = null\n private cacheExpiry: number = 0\n private readonly CACHE_TTL = 5 * 60 * 1000 // 5 minutes\n\n static getInstance(): AuthValidationService {\n if (!AuthValidationService.instance) {\n AuthValidationService.instance = new AuthValidationService()\n }\n return AuthValidationService.instance\n }\n\n /**\n * Get authentication settings from core-auth plugin\n */\n async getAuthSettings(db: D1Database): Promise<AuthSettings> {\n // Return cached settings if still valid\n if (this.cachedSettings && Date.now() < this.cacheExpiry) {\n return this.cachedSettings\n }\n\n try {\n const plugin = await db\n .prepare('SELECT settings FROM plugins WHERE id = ? AND status = ?')\n .bind('core-auth', 'active')\n .first() as any\n\n if (!plugin || !plugin.settings) {\n console.warn('[AuthValidation] Core-auth plugin not found or not active, using defaults')\n return this.getDefaultSettings()\n }\n\n const settings = typeof plugin.settings === 'string'\n ? JSON.parse(plugin.settings)\n : plugin.settings\n\n // Cache the settings\n this.cachedSettings = settings\n this.cacheExpiry = Date.now() + this.CACHE_TTL\n\n return settings\n } catch (error) {\n console.error('[AuthValidation] Error loading auth settings:', error)\n return this.getDefaultSettings()\n }\n }\n\n /**\n * Get default authentication settings\n */\n private getDefaultSettings(): AuthSettings {\n return {\n requiredFields: {\n email: { required: true, minLength: 5, label: 'Email', type: 'email' },\n password: { required: true, minLength: 8, label: 'Password', type: 'password' },\n username: { required: true, minLength: 3, label: 'Username', type: 'text' },\n firstName: { required: true, minLength: 1, label: 'First Name', type: 'text' },\n lastName: { required: true, minLength: 1, label: 'Last Name', type: 'text' },\n },\n validation: {\n emailFormat: true,\n allowDuplicateUsernames: false,\n passwordRequirements: {\n requireUppercase: false,\n requireLowercase: false,\n requireNumbers: false,\n requireSpecialChars: false,\n },\n },\n registration: {\n enabled: true,\n requireEmailVerification: false,\n defaultRole: 'viewer',\n },\n }\n }\n\n /**\n * Build dynamic Zod schema based on settings\n */\n async buildRegistrationSchema(db: D1Database): Promise<z.ZodObject<any>> {\n const settings = await this.getAuthSettings(db)\n const fields = settings.requiredFields\n const validation = settings.validation\n\n const schemaFields: Record<string, z.ZodTypeAny> = {}\n\n // Email field\n if (fields.email.required) {\n let emailSchema = z.string()\n\n if (validation.emailFormat) {\n emailSchema = emailSchema.email('Valid email is required')\n }\n\n if (fields.email.minLength > 0) {\n emailSchema = emailSchema.min(\n fields.email.minLength,\n `Email must be at least ${fields.email.minLength} characters`\n )\n }\n\n schemaFields.email = emailSchema\n } else {\n schemaFields.email = z.string().email().optional()\n }\n\n // Password field\n if (fields.password.required) {\n let passwordSchema = z.string().min(\n fields.password.minLength,\n `Password must be at least ${fields.password.minLength} characters`\n )\n\n // Add password requirements validation\n if (validation.passwordRequirements.requireUppercase) {\n passwordSchema = passwordSchema.regex(\n /[A-Z]/,\n 'Password must contain at least one uppercase letter'\n )\n }\n\n if (validation.passwordRequirements.requireLowercase) {\n passwordSchema = passwordSchema.regex(\n /[a-z]/,\n 'Password must contain at least one lowercase letter'\n )\n }\n\n if (validation.passwordRequirements.requireNumbers) {\n passwordSchema = passwordSchema.regex(\n /[0-9]/,\n 'Password must contain at least one number'\n )\n }\n\n if (validation.passwordRequirements.requireSpecialChars) {\n passwordSchema = passwordSchema.regex(\n /[!@#$%^&*(),.?\":{}|<>]/,\n 'Password must contain at least one special character'\n )\n }\n\n schemaFields.password = passwordSchema\n } else {\n schemaFields.password = z.string().min(fields.password.minLength).optional()\n }\n\n // Username field\n if (fields.username.required) {\n schemaFields.username = z.string().min(\n fields.username.minLength,\n `Username must be at least ${fields.username.minLength} characters`\n )\n } else {\n schemaFields.username = z.string().min(fields.username.minLength).optional()\n }\n\n // First name field\n if (fields.firstName.required) {\n schemaFields.firstName = z.string().min(\n fields.firstName.minLength,\n `First name must be at least ${fields.firstName.minLength} characters`\n )\n } else {\n schemaFields.firstName = z.string().optional()\n }\n\n // Last name field\n if (fields.lastName.required) {\n schemaFields.lastName = z.string().min(\n fields.lastName.minLength,\n `Last name must be at least ${fields.lastName.minLength} characters`\n )\n } else {\n schemaFields.lastName = z.string().optional()\n }\n\n return z.object(schemaFields)\n }\n\n /**\n * Validate registration data against settings\n */\n async validateRegistration(db: D1Database, data: any): Promise<{ valid: boolean; errors: string[] }> {\n try {\n const schema = await this.buildRegistrationSchema(db)\n await schema.parseAsync(data)\n return { valid: true, errors: [] }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return {\n valid: false,\n errors: error.errors.map(e => e.message),\n }\n }\n return {\n valid: false,\n errors: ['Validation failed'],\n }\n }\n }\n\n /**\n * Clear cached settings (call after updating plugin settings)\n */\n clearCache(): void {\n this.cachedSettings = null\n this.cacheExpiry = 0\n }\n\n /**\n * Get required field names for database insertion\n */\n async getRequiredFieldNames(db: D1Database): Promise<string[]> {\n const settings = await this.getAuthSettings(db)\n const requiredFields: string[] = []\n\n Object.entries(settings.requiredFields).forEach(([key, config]) => {\n if (config.required) {\n requiredFields.push(key)\n }\n })\n\n return requiredFields\n }\n\n /**\n * Generate auto-fill values for optional fields\n */\n generateDefaultValue(fieldName: string, data: any): string {\n switch (fieldName) {\n case 'username':\n // Generate username from email if not provided\n return data.email ? data.email.split('@')[0] : `user_${Date.now()}`\n case 'firstName':\n return data.firstName || 'User'\n case 'lastName':\n return data.lastName || ''\n default:\n return ''\n }\n }\n}\n\n// Export singleton instance\nexport const authValidationService = AuthValidationService.getInstance()\n","import { Hono } from 'hono'\nimport { zValidator } from '@hono/zod-validator'\nimport { z } from 'zod'\nimport { setCookie } from 'hono/cookie'\nimport { html } from 'hono/html'\nimport { AuthManager, requireAuth } from '../middleware'\nimport { renderLoginPage, LoginPageData } from '../templates/pages/auth-login.template'\nimport { renderRegisterPage, RegisterPageData } from '../templates/pages/auth-register.template'\nimport { getCacheService, CACHE_CONFIGS } from '../services'\nimport { authValidationService } from '../services/auth-validation'\nimport type { Bindings, Variables } from '../app'\n\nconst authRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Login page (HTML form)\nauthRoutes.get('/login', async (c) => {\n const error = c.req.query('error')\n const message = c.req.query('message')\n \n const pageData: LoginPageData = {\n error: error || undefined,\n message: message || undefined,\n version: c.get('appVersion')\n }\n \n // Check if demo login plugin is active\n const db = c.env.DB\n let demoLoginActive = false\n try {\n const plugin = await db.prepare('SELECT * FROM plugins WHERE id = ? AND status = ?')\n .bind('demo-login-prefill', 'active')\n .first()\n demoLoginActive = !!plugin\n } catch (error) {\n // Ignore database errors - plugin system might not be initialized\n }\n \n return c.html(renderLoginPage(pageData, demoLoginActive))\n})\n\n// Registration page (HTML form)\nauthRoutes.get('/register', (c) => {\n const error = c.req.query('error')\n \n const pageData: RegisterPageData = {\n error: error || undefined\n }\n \n return c.html(renderRegisterPage(pageData))\n})\n\n// Login schema\nconst loginSchema = z.object({\n email: z.string().email('Valid email is required'),\n password: z.string().min(1, 'Password is required')\n})\n\n// Register new user\nauthRoutes.post('/register',\n async (c) => {\n try {\n const db = c.env.DB\n const requestData = await c.req.json()\n\n // Build and validate using dynamic schema\n const validationSchema = await authValidationService.buildRegistrationSchema(db)\n const validationResult = await validationSchema.safeParseAsync(requestData)\n\n if (!validationResult.success) {\n return c.json({\n error: 'Validation failed',\n details: validationResult.error.errors.map(e => e.message)\n }, 400)\n }\n\n const validatedData = validationResult.data\n\n // Extract fields with defaults for optional ones\n const email = validatedData.email\n const password = validatedData.password\n const username = validatedData.username || authValidationService.generateDefaultValue('username', validatedData)\n const firstName = validatedData.firstName || authValidationService.generateDefaultValue('firstName', validatedData)\n const lastName = validatedData.lastName || authValidationService.generateDefaultValue('lastName', validatedData)\n \n // Normalize email to lowercase\n const normalizedEmail = email.toLowerCase()\n \n // Check if user already exists\n const existingUser = await db.prepare('SELECT id FROM users WHERE email = ? OR username = ?')\n .bind(normalizedEmail, username)\n .first()\n \n if (existingUser) {\n return c.json({ error: 'User with this email or username already exists' }, 400)\n }\n \n // Hash password\n const passwordHash = await AuthManager.hashPassword(password)\n \n // Create user\n const userId = crypto.randomUUID()\n const now = new Date()\n \n await db.prepare(`\n INSERT INTO users (id, email, username, first_name, last_name, password_hash, role, is_active, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).bind(\n userId,\n normalizedEmail,\n username,\n firstName,\n lastName,\n passwordHash,\n 'viewer', // Default role\n 1, // is_active\n now.getTime(),\n now.getTime()\n ).run()\n \n // Generate JWT token\n const token = await AuthManager.generateToken(userId, normalizedEmail, 'viewer')\n \n // Set HTTP-only cookie\n setCookie(c, 'auth_token', token, {\n httpOnly: true,\n secure: true,\n sameSite: 'Strict',\n maxAge: 60 * 60 * 24 // 24 hours\n })\n \n return c.json({\n user: {\n id: userId,\n email: normalizedEmail,\n username,\n firstName,\n lastName,\n role: 'viewer'\n },\n token\n }, 201)\n } catch (error) {\n console.error('Registration error:', error)\n return c.json({ error: 'Registration failed' }, 500)\n }\n }\n)\n\n// Login user\nauthRoutes.post('/login', async (c) => {\n try {\n const body = await c.req.json()\n const validation = loginSchema.safeParse(body)\n if (!validation.success) {\n return c.json({ error: 'Validation failed', details: validation.error.errors }, 400)\n }\n const { email, password } = validation.data\n const db = c.env.DB\n \n // Normalize email to lowercase\n const normalizedEmail = email.toLowerCase()\n \n // Find user with caching\n const cache = getCacheService(CACHE_CONFIGS.user!)\n let user = await cache.get<any>(cache.generateKey('user', `email:${normalizedEmail}`))\n\n if (!user) {\n user = await db.prepare('SELECT * FROM users WHERE email = ? AND is_active = 1')\n .bind(normalizedEmail)\n .first() as any\n\n if (user) {\n // Cache the user for faster subsequent lookups\n await cache.set(cache.generateKey('user', `email:${normalizedEmail}`), user)\n await cache.set(cache.generateKey('user', user.id), user)\n }\n }\n\n if (!user) {\n return c.json({ error: 'Invalid email or password' }, 401)\n }\n \n // Verify password\n const isValidPassword = await AuthManager.verifyPassword(password, user.password_hash)\n if (!isValidPassword) {\n return c.json({ error: 'Invalid email or password' }, 401)\n }\n \n // Generate JWT token\n const token = await AuthManager.generateToken(user.id, user.email, user.role)\n \n // Set HTTP-only cookie\n setCookie(c, 'auth_token', token, {\n httpOnly: true,\n secure: true,\n sameSite: 'Strict',\n maxAge: 60 * 60 * 24 // 24 hours\n })\n \n // Update last login\n await db.prepare('UPDATE users SET last_login_at = ? WHERE id = ?')\n .bind(new Date().getTime(), user.id)\n .run()\n\n // Invalidate user cache on login\n await cache.delete(cache.generateKey('user', user.id))\n await cache.delete(cache.generateKey('user', `email:${normalizedEmail}`))\n\n return c.json({\n user: {\n id: user.id,\n email: user.email,\n username: user.username,\n firstName: user.firstName,\n lastName: user.lastName,\n role: user.role\n },\n token\n })\n } catch (error) {\n console.error('Login error:', error)\n return c.json({ error: 'Login failed' }, 500)\n }\n})\n\n// Logout user (both GET and POST for convenience)\nauthRoutes.post('/logout', (c) => {\n // Clear the auth cookie\n setCookie(c, 'auth_token', '', {\n httpOnly: true,\n secure: false, // Set to true in production with HTTPS\n sameSite: 'Strict',\n maxAge: 0 // Expire immediately\n })\n \n return c.json({ message: 'Logged out successfully' })\n})\n\nauthRoutes.get('/logout', (c) => {\n // Clear the auth cookie\n setCookie(c, 'auth_token', '', {\n httpOnly: true,\n secure: false, // Set to true in production with HTTPS\n sameSite: 'Strict',\n maxAge: 0 // Expire immediately\n })\n \n return c.redirect('/auth/login?message=You have been logged out successfully')\n})\n\n// Get current user\nauthRoutes.get('/me', requireAuth(), async (c) => {\n try {\n // This would need the auth middleware applied\n const user = c.get('user')\n \n if (!user) {\n return c.json({ error: 'Not authenticated' }, 401)\n }\n \n const db = c.env.DB\n const userData = await db.prepare('SELECT id, email, username, first_name, last_name, role, created_at FROM users WHERE id = ?')\n .bind(user.userId)\n .first()\n \n if (!userData) {\n return c.json({ error: 'User not found' }, 404)\n }\n \n return c.json({ user: userData })\n } catch (error) {\n console.error('Get user error:', error)\n return c.json({ error: 'Failed to get user' }, 500)\n }\n})\n\n// Refresh token\nauthRoutes.post('/refresh', requireAuth(), async (c) => {\n try {\n const user = c.get('user')\n \n if (!user) {\n return c.json({ error: 'Not authenticated' }, 401)\n }\n \n // Generate new token\n const token = await AuthManager.generateToken(user.userId, user.email, user.role)\n \n // Set new cookie\n setCookie(c, 'auth_token', token, {\n httpOnly: true,\n secure: true,\n sameSite: 'Strict',\n maxAge: 60 * 60 * 24 // 24 hours\n })\n \n return c.json({ token })\n } catch (error) {\n console.error('Token refresh error:', error)\n return c.json({ error: 'Token refresh failed' }, 500)\n }\n})\n\n// Form-based registration handler (for HTML forms)\nauthRoutes.post('/register/form', async (c) => {\n try {\n const db = c.env.DB\n const formData = await c.req.formData()\n\n // Extract form data\n const requestData = {\n email: formData.get('email') as string,\n password: formData.get('password') as string,\n username: formData.get('username') as string,\n firstName: formData.get('firstName') as string,\n lastName: formData.get('lastName') as string,\n }\n\n // Normalize email to lowercase\n const normalizedEmail = requestData.email?.toLowerCase()\n requestData.email = normalizedEmail\n\n // Build and validate using dynamic schema\n const validationSchema = await authValidationService.buildRegistrationSchema(db)\n const validation = await validationSchema.safeParseAsync(requestData)\n\n if (!validation.success) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n ${validation.error.errors.map(err => err.message).join(', ')}\n </div>\n `)\n }\n\n const validatedData = validation.data\n\n // Extract fields with defaults for optional ones\n const email = validatedData.email\n const password = validatedData.password\n const username = validatedData.username || authValidationService.generateDefaultValue('username', validatedData)\n const firstName = validatedData.firstName || authValidationService.generateDefaultValue('firstName', validatedData)\n const lastName = validatedData.lastName || authValidationService.generateDefaultValue('lastName', validatedData)\n \n // Check if user already exists\n const existingUser = await db.prepare('SELECT id FROM users WHERE email = ? OR username = ?')\n .bind(normalizedEmail, username)\n .first()\n \n if (existingUser) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n User with this email or username already exists\n </div>\n `)\n }\n \n // Hash password\n const passwordHash = await AuthManager.hashPassword(password)\n \n // Create user\n const userId = crypto.randomUUID()\n const now = new Date()\n \n await db.prepare(`\n INSERT INTO users (id, email, username, first_name, last_name, password_hash, role, is_active, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).bind(\n userId,\n normalizedEmail,\n username,\n firstName,\n lastName,\n passwordHash,\n 'admin', // First user gets admin role\n 1, // is_active\n now.getTime(),\n now.getTime()\n ).run()\n \n // Generate JWT token\n const token = await AuthManager.generateToken(userId, normalizedEmail, 'admin')\n \n // Set HTTP-only cookie\n setCookie(c, 'auth_token', token, {\n httpOnly: true,\n secure: false, // Set to true in production with HTTPS\n sameSite: 'Strict',\n maxAge: 60 * 60 * 24 // 24 hours\n })\n \n return c.html(html`\n <div class=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded\">\n Account created successfully! Redirecting to admin dashboard...\n <script>\n setTimeout(() => {\n window.location.href = '/admin/content';\n }, 2000);\n </script>\n </div>\n `)\n } catch (error) {\n console.error('Registration error:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Registration failed. Please try again.\n </div>\n `)\n }\n})\n\n// Form-based login handler (for HTML forms)\nauthRoutes.post('/login/form', async (c) => {\n try {\n const formData = await c.req.formData()\n const email = formData.get('email') as string\n const password = formData.get('password') as string\n\n // Normalize email to lowercase\n const normalizedEmail = email.toLowerCase()\n\n // Validate the data\n const validation = loginSchema.safeParse({ email: normalizedEmail, password })\n\n if (!validation.success) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n ${validation.error.errors.map(err => err.message).join(', ')}\n </div>\n `)\n }\n\n const db = c.env.DB\n \n // Find user\n const user = await db.prepare('SELECT * FROM users WHERE email = ? AND is_active = 1')\n .bind(normalizedEmail)\n .first() as any\n \n if (!user) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Invalid email or password\n </div>\n `)\n }\n \n // Verify password\n const isValidPassword = await AuthManager.verifyPassword(password, user.password_hash)\n if (!isValidPassword) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Invalid email or password\n </div>\n `)\n }\n \n // Generate JWT token\n const token = await AuthManager.generateToken(user.id, user.email, user.role)\n \n // Set HTTP-only cookie\n setCookie(c, 'auth_token', token, {\n httpOnly: true,\n secure: false, // Set to true in production with HTTPS\n sameSite: 'Strict',\n maxAge: 60 * 60 * 24 // 24 hours\n })\n \n // Update last login\n await db.prepare('UPDATE users SET last_login_at = ? WHERE id = ?')\n .bind(new Date().getTime(), user.id)\n .run()\n \n return c.html(html`\n <div id=\"form-response\">\n <div class=\"rounded-lg bg-green-100 dark:bg-lime-500/10 p-4 ring-1 ring-green-400 dark:ring-lime-500/20\">\n <div class=\"flex items-start gap-x-3\">\n <svg class=\"h-5 w-5 text-green-600 dark:text-lime-400 shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"/>\n </svg>\n <div class=\"flex-1\">\n <p class=\"text-sm font-medium text-green-700 dark:text-lime-300\">Login successful! Redirecting to admin dashboard...</p>\n </div>\n </div>\n <script>\n setTimeout(() => {\n window.location.href = '/admin/content';\n }, 2000);\n </script>\n </div>\n </div>\n `)\n } catch (error) {\n console.error('Login error:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Login failed. Please try again.\n </div>\n `)\n }\n})\n\n// Test seeding endpoint (only for development/testing)\nauthRoutes.post('/seed-admin', async (c) => {\n try {\n const db = c.env.DB\n \n // First ensure the users table exists\n await db.prepare(`\n CREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n username TEXT NOT NULL UNIQUE,\n first_name TEXT NOT NULL,\n last_name TEXT NOT NULL,\n password_hash TEXT,\n role TEXT NOT NULL DEFAULT 'viewer',\n avatar TEXT,\n is_active INTEGER NOT NULL DEFAULT 1,\n last_login_at INTEGER,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n )\n `).run()\n \n // Check if admin user already exists\n const existingAdmin = await db.prepare('SELECT id FROM users WHERE email = ? OR username = ?')\n .bind('admin@sonicjs.com', 'admin')\n .first()\n \n if (existingAdmin) {\n return c.json({ \n message: 'Admin user already exists',\n user: {\n id: existingAdmin.id,\n email: 'admin@sonicjs.com',\n username: 'admin',\n role: 'admin'\n }\n })\n }\n \n // Hash password\n const passwordHash = await AuthManager.hashPassword('admin123')\n \n // Create admin user\n const userId = 'admin-user-id'\n const now = Date.now()\n const adminEmail = 'admin@sonicjs.com'.toLowerCase()\n \n await db.prepare(`\n INSERT INTO users (id, email, username, first_name, last_name, password_hash, role, is_active, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).bind(\n userId,\n adminEmail,\n 'admin',\n 'Admin',\n 'User',\n passwordHash,\n 'admin',\n 1, // is_active\n now,\n now\n ).run()\n \n return c.json({ \n message: 'Admin user created successfully',\n user: {\n id: userId,\n email: adminEmail,\n username: 'admin',\n role: 'admin'\n },\n passwordHash: passwordHash // For debugging\n })\n } catch (error) {\n console.error('Seed admin error:', error)\n return c.json({ error: 'Failed to create admin user', details: error instanceof Error ? error.message : String(error) }, 500)\n }\n})\n\n\n// Accept invitation page\nauthRoutes.get('/accept-invitation', async (c) => {\n try {\n const token = c.req.query('token')\n \n if (!token) {\n return c.html(`\n <html>\n <head><title>Invalid Invitation</title></head>\n <body>\n <h1>Invalid Invitation</h1>\n <p>The invitation link is invalid or has expired.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n\n const db = c.env.DB\n \n // Check if invitation token is valid\n const userStmt = db.prepare(`\n SELECT id, email, first_name, last_name, role, invited_at\n FROM users \n WHERE invitation_token = ? AND is_active = 0\n `)\n const invitedUser = await userStmt.bind(token).first() as any\n\n if (!invitedUser) {\n return c.html(`\n <html>\n <head><title>Invalid Invitation</title></head>\n <body>\n <h1>Invalid Invitation</h1>\n <p>The invitation link is invalid or has expired.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n\n // Check if invitation is expired (7 days)\n const invitationAge = Date.now() - invitedUser.invited_at\n const maxAge = 7 * 24 * 60 * 60 * 1000 // 7 days\n \n if (invitationAge > maxAge) {\n return c.html(`\n <html>\n <head><title>Invitation Expired</title></head>\n <body>\n <h1>Invitation Expired</h1>\n <p>This invitation has expired. Please contact your administrator for a new invitation.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n\n // Show invitation acceptance form\n return c.html(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Accept Invitation - SonicJS AI</title>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <style>\n body {\n background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);\n min-height: 100vh;\n }\n </style>\n </head>\n <body class=\"bg-gray-900 text-white\">\n <div class=\"min-h-screen flex items-center justify-center px-4\">\n <div class=\"max-w-md w-full space-y-8\">\n <div class=\"text-center\">\n <div class=\"mx-auto w-16 h-16 bg-blue-600 rounded-2xl flex items-center justify-center mb-6\">\n <svg class=\"w-8 h-8 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z\"/>\n </svg>\n </div>\n <h2 class=\"text-3xl font-bold\">Accept Invitation</h2>\n <p class=\"mt-2 text-gray-400\">Complete your account setup</p>\n <p class=\"mt-4 text-sm\">\n You've been invited as <strong>${invitedUser.first_name} ${invitedUser.last_name}</strong><br>\n <span class=\"text-gray-400\">${invitedUser.email}</span><br>\n <span class=\"text-blue-400 capitalize\">${invitedUser.role}</span>\n </p>\n </div>\n\n <form method=\"POST\" action=\"/auth/accept-invitation\" class=\"mt-8 space-y-6\">\n <input type=\"hidden\" name=\"token\" value=\"${token}\" />\n \n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Username</label>\n <input \n type=\"text\" \n name=\"username\" \n required\n class=\"w-full px-4 py-3 bg-gray-800 border border-gray-700 rounded-xl text-white focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-500 transition-all\"\n placeholder=\"Enter your username\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Password</label>\n <input \n type=\"password\" \n name=\"password\" \n required\n minlength=\"8\"\n class=\"w-full px-4 py-3 bg-gray-800 border border-gray-700 rounded-xl text-white focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-500 transition-all\"\n placeholder=\"Enter your password\"\n >\n <p class=\"text-xs text-gray-400 mt-1\">Password must be at least 8 characters long</p>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Confirm Password</label>\n <input \n type=\"password\" \n name=\"confirm_password\" \n required\n minlength=\"8\"\n class=\"w-full px-4 py-3 bg-gray-800 border border-gray-700 rounded-xl text-white focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-500 transition-all\"\n placeholder=\"Confirm your password\"\n >\n </div>\n\n <button \n type=\"submit\"\n class=\"w-full py-3 px-4 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-semibold rounded-xl hover:from-blue-700 hover:to-purple-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-900 transition-all\"\n >\n Accept Invitation & Create Account\n </button>\n </form>\n </div>\n </div>\n </body>\n </html>\n `)\n\n } catch (error) {\n console.error('Accept invitation page error:', error)\n return c.html(`\n <html>\n <head><title>Error</title></head>\n <body>\n <h1>Error</h1>\n <p>An error occurred while processing your invitation.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n})\n\n// Process invitation acceptance\nauthRoutes.post('/accept-invitation', async (c) => {\n try {\n const formData = await c.req.formData()\n const token = formData.get('token')?.toString()\n const username = formData.get('username')?.toString()?.trim()\n const password = formData.get('password')?.toString()\n const confirmPassword = formData.get('confirm_password')?.toString()\n\n if (!token || !username || !password || !confirmPassword) {\n return c.json({ error: 'All fields are required' }, 400)\n }\n\n if (password !== confirmPassword) {\n return c.json({ error: 'Passwords do not match' }, 400)\n }\n\n if (password.length < 8) {\n return c.json({ error: 'Password must be at least 8 characters long' }, 400)\n }\n\n const db = c.env.DB\n\n // Check if invitation token is valid\n const userStmt = db.prepare(`\n SELECT id, email, first_name, last_name, role, invited_at\n FROM users \n WHERE invitation_token = ? AND is_active = 0\n `)\n const invitedUser = await userStmt.bind(token).first() as any\n\n if (!invitedUser) {\n return c.json({ error: 'Invalid or expired invitation' }, 400)\n }\n\n // Check if invitation is expired (7 days)\n const invitationAge = Date.now() - invitedUser.invited_at\n const maxAge = 7 * 24 * 60 * 60 * 1000 // 7 days\n \n if (invitationAge > maxAge) {\n return c.json({ error: 'Invitation has expired' }, 400)\n }\n\n // Check if username is available\n const existingUsernameStmt = db.prepare(`\n SELECT id FROM users WHERE username = ? AND id != ?\n `)\n const existingUsername = await existingUsernameStmt.bind(username, invitedUser.id).first()\n\n if (existingUsername) {\n return c.json({ error: 'Username is already taken' }, 400)\n }\n\n // Hash password\n const passwordHash = await AuthManager.hashPassword(password)\n\n // Activate user account\n const updateStmt = db.prepare(`\n UPDATE users SET \n username = ?,\n password_hash = ?,\n is_active = 1,\n email_verified = 1,\n invitation_token = NULL,\n accepted_invitation_at = ?,\n updated_at = ?\n WHERE id = ?\n `)\n\n await updateStmt.bind(\n username,\n passwordHash,\n Date.now(),\n Date.now(),\n invitedUser.id\n ).run()\n\n // Generate JWT token for auto-login\n const authToken = await AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role)\n \n // Set HTTP-only cookie\n setCookie(c, 'auth_token', authToken, {\n httpOnly: true,\n secure: true,\n sameSite: 'Strict',\n maxAge: 60 * 60 * 24 // 24 hours\n })\n\n // Log the activity (TODO: implement activity logging)\n // Activity logging is deferred until utils/log-activity is implemented\n\n // Redirect to admin dashboard\n return c.redirect('/admin/content?welcome=true')\n\n } catch (error) {\n console.error('Accept invitation error:', error)\n return c.json({ error: 'Failed to accept invitation' }, 500)\n }\n})\n\n// Request password reset\nauthRoutes.post('/request-password-reset', async (c) => {\n try {\n const formData = await c.req.formData()\n const email = formData.get('email')?.toString()?.trim()?.toLowerCase()\n\n if (!email) {\n return c.json({ error: 'Email is required' }, 400)\n }\n\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n if (!emailRegex.test(email)) {\n return c.json({ error: 'Please enter a valid email address' }, 400)\n }\n\n const db = c.env.DB\n\n // Check if user exists and is active\n const userStmt = db.prepare(`\n SELECT id, email, first_name, last_name FROM users \n WHERE email = ? AND is_active = 1\n `)\n const user = await userStmt.bind(email).first() as any\n\n // Always return success to prevent email enumeration\n if (!user) {\n return c.json({\n success: true,\n message: 'If an account with this email exists, a password reset link has been sent.'\n })\n }\n\n // Generate password reset token (expires in 1 hour)\n const resetToken = crypto.randomUUID()\n const resetExpires = Date.now() + (60 * 60 * 1000) // 1 hour\n\n // Update user with reset token\n const updateStmt = db.prepare(`\n UPDATE users SET \n password_reset_token = ?,\n password_reset_expires = ?,\n updated_at = ?\n WHERE id = ?\n `)\n\n await updateStmt.bind(\n resetToken,\n resetExpires,\n Date.now(),\n user.id\n ).run()\n\n // Log the activity (TODO: implement activity logging)\n // Activity logging is deferred until utils/log-activity is implemented\n\n // In a real implementation, you would send an email here\n // For now, we'll return the reset link for development\n const resetLink = `${c.req.header('origin') || 'http://localhost:8787'}/auth/reset-password?token=${resetToken}`\n\n return c.json({\n success: true,\n message: 'If an account with this email exists, a password reset link has been sent.',\n reset_link: resetLink // In production, this would be sent via email\n })\n\n } catch (error) {\n console.error('Password reset request error:', error)\n return c.json({ error: 'Failed to process password reset request' }, 500)\n }\n})\n\n// Show password reset form\nauthRoutes.get('/reset-password', async (c) => {\n try {\n const token = c.req.query('token')\n \n if (!token) {\n return c.html(`\n <html>\n <head><title>Invalid Reset Link</title></head>\n <body>\n <h1>Invalid Reset Link</h1>\n <p>The password reset link is invalid or has expired.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n\n const db = c.env.DB\n \n // Check if reset token is valid and not expired\n const userStmt = db.prepare(`\n SELECT id, email, first_name, last_name, password_reset_expires\n FROM users \n WHERE password_reset_token = ? AND is_active = 1\n `)\n const user = await userStmt.bind(token).first() as any\n\n if (!user) {\n return c.html(`\n <html>\n <head><title>Invalid Reset Link</title></head>\n <body>\n <h1>Invalid Reset Link</h1>\n <p>The password reset link is invalid or has already been used.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n\n // Check if token is expired\n if (Date.now() > user.password_reset_expires) {\n return c.html(`\n <html>\n <head><title>Reset Link Expired</title></head>\n <body>\n <h1>Reset Link Expired</h1>\n <p>The password reset link has expired. Please request a new one.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n\n // Show password reset form\n return c.html(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Reset Password - SonicJS AI</title>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <style>\n body {\n background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);\n min-height: 100vh;\n }\n </style>\n </head>\n <body class=\"bg-gray-900 text-white\">\n <div class=\"min-h-screen flex items-center justify-center px-4\">\n <div class=\"max-w-md w-full space-y-8\">\n <div class=\"text-center\">\n <div class=\"mx-auto w-16 h-16 bg-blue-600 rounded-2xl flex items-center justify-center mb-6\">\n <svg class=\"w-8 h-8 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-3.586l4.293-4.293A6 6 0 0119 9z\"/>\n </svg>\n </div>\n <h2 class=\"text-3xl font-bold\">Reset Password</h2>\n <p class=\"mt-2 text-gray-400\">Choose a new password for your account</p>\n <p class=\"mt-4 text-sm\">\n Reset password for <strong>${user.first_name} ${user.last_name}</strong><br>\n <span class=\"text-gray-400\">${user.email}</span>\n </p>\n </div>\n\n <form method=\"POST\" action=\"/auth/reset-password\" class=\"mt-8 space-y-6\">\n <input type=\"hidden\" name=\"token\" value=\"${token}\" />\n \n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">New Password</label>\n <input \n type=\"password\" \n name=\"password\" \n required\n minlength=\"8\"\n class=\"w-full px-4 py-3 bg-gray-800 border border-gray-700 rounded-xl text-white focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-500 transition-all\"\n placeholder=\"Enter your new password\"\n >\n <p class=\"text-xs text-gray-400 mt-1\">Password must be at least 8 characters long</p>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Confirm New Password</label>\n <input \n type=\"password\" \n name=\"confirm_password\" \n required\n minlength=\"8\"\n class=\"w-full px-4 py-3 bg-gray-800 border border-gray-700 rounded-xl text-white focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-500 transition-all\"\n placeholder=\"Confirm your new password\"\n >\n </div>\n\n <button \n type=\"submit\"\n class=\"w-full py-3 px-4 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-semibold rounded-xl hover:from-blue-700 hover:to-purple-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-900 transition-all\"\n >\n Reset Password\n </button>\n </form>\n\n <div class=\"text-center\">\n <a href=\"/auth/login\" class=\"text-sm text-blue-400 hover:text-blue-300\">\n Back to Login\n </a>\n </div>\n </div>\n </div>\n </body>\n </html>\n `)\n\n } catch (error) {\n console.error('Password reset page error:', error)\n return c.html(`\n <html>\n <head><title>Error</title></head>\n <body>\n <h1>Error</h1>\n <p>An error occurred while processing your password reset.</p>\n <a href=\"/auth/login\">Go to Login</a>\n </body>\n </html>\n `)\n }\n})\n\n// Process password reset\nauthRoutes.post('/reset-password', async (c) => {\n try {\n const formData = await c.req.formData()\n const token = formData.get('token')?.toString()\n const password = formData.get('password')?.toString()\n const confirmPassword = formData.get('confirm_password')?.toString()\n\n if (!token || !password || !confirmPassword) {\n return c.json({ error: 'All fields are required' }, 400)\n }\n\n if (password !== confirmPassword) {\n return c.json({ error: 'Passwords do not match' }, 400)\n }\n\n if (password.length < 8) {\n return c.json({ error: 'Password must be at least 8 characters long' }, 400)\n }\n\n const db = c.env.DB\n\n // Check if reset token is valid and not expired\n const userStmt = db.prepare(`\n SELECT id, email, password_hash, password_reset_expires\n FROM users\n WHERE password_reset_token = ? AND is_active = 1\n `)\n const user = await userStmt.bind(token).first() as any\n\n if (!user) {\n return c.json({ error: 'Invalid or expired reset token' }, 400)\n }\n\n // Check if token is expired\n if (Date.now() > user.password_reset_expires) {\n return c.json({ error: 'Reset token has expired' }, 400)\n }\n\n // Hash new password\n const newPasswordHash = await AuthManager.hashPassword(password)\n\n // Store old password in history (skip if table doesn't exist)\n try {\n const historyStmt = db.prepare(`\n INSERT INTO password_history (id, user_id, password_hash, created_at)\n VALUES (?, ?, ?, ?)\n `)\n await historyStmt.bind(\n crypto.randomUUID(),\n user.id,\n user.password_hash,\n Date.now()\n ).run()\n } catch (historyError) {\n // Password history table may not exist yet\n console.warn('Could not store password history:', historyError)\n }\n\n // Update user password and clear reset token\n const updateStmt = db.prepare(`\n UPDATE users SET\n password_hash = ?,\n password_reset_token = NULL,\n password_reset_expires = NULL,\n updated_at = ?\n WHERE id = ?\n `)\n\n await updateStmt.bind(\n newPasswordHash,\n Date.now(),\n user.id\n ).run()\n\n // Log the activity (TODO: implement activity logging)\n // Activity logging is deferred until utils/log-activity is implemented\n\n // Redirect to login with success message\n return c.redirect('/auth/login?message=Password reset successfully. Please log in with your new password.')\n\n } catch (error) {\n console.error('Password reset error:', error)\n return c.json({ error: 'Failed to reset password' }, 500)\n }\n})\n\nexport default authRoutes","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\nimport { renderAlert } from '../alert.template'\nimport { renderDynamicField, renderFieldGroup, FieldDefinition } from '../components/dynamic-field.template'\nimport { renderConfirmationDialog, getConfirmationDialogScript } from '../confirmation-dialog.template'\n\nexport interface Collection {\n id: string\n name: string\n display_name: string\n description?: string\n schema: any\n}\n\nexport interface ContentFormData {\n id?: string\n title?: string\n slug?: string\n data?: any\n status?: string\n scheduled_publish_at?: number\n scheduled_unpublish_at?: number\n review_status?: string\n meta_title?: string\n meta_description?: string\n collection: Collection\n fields: FieldDefinition[]\n isEdit?: boolean\n error?: string\n success?: string\n validationErrors?: Record<string, string[]>\n workflowEnabled?: boolean // New flag to indicate if workflow plugin is active\n referrerParams?: string // URL parameters to preserve filters when returning to list\n user?: {\n name: string\n email: string\n role: string\n }\n version?: string\n}\n\nexport function renderContentFormPage(data: ContentFormData): string {\n const isEdit = data.isEdit || !!data.id\n const title = isEdit ? `Edit: ${data.title || 'Content'}` : `New ${data.collection.display_name}`\n\n // Construct back URL with preserved filters\n const backUrl = data.referrerParams\n ? `/admin/content?${data.referrerParams}`\n : `/admin/content?collection=${data.collection.id}`\n\n // Group fields by category\n const coreFields = data.fields.filter(f => ['title', 'slug', 'content'].includes(f.field_name))\n const contentFields = data.fields.filter(f => !['title', 'slug', 'content'].includes(f.field_name) && !f.field_name.startsWith('meta_'))\n const metaFields = data.fields.filter(f => f.field_name.startsWith('meta_'))\n \n // Helper function to get field value - title and slug are stored as columns, others in data JSON\n const getFieldValue = (fieldName: string) => {\n if (fieldName === 'title') return data.title || data.data?.[fieldName] || ''\n if (fieldName === 'slug') return data.slug || data.data?.[fieldName] || ''\n return data.data?.[fieldName] || ''\n }\n\n // Render field groups\n const coreFieldsHTML = coreFields\n .sort((a, b) => a.field_order - b.field_order)\n .map(field => renderDynamicField(field, {\n value: getFieldValue(field.field_name),\n errors: data.validationErrors?.[field.field_name] || []\n }))\n \n const contentFieldsHTML = contentFields\n .sort((a, b) => a.field_order - b.field_order)\n .map(field => renderDynamicField(field, {\n value: getFieldValue(field.field_name),\n errors: data.validationErrors?.[field.field_name] || []\n }))\n\n const metaFieldsHTML = metaFields\n .sort((a, b) => a.field_order - b.field_order)\n .map(field => renderDynamicField(field, {\n value: getFieldValue(field.field_name),\n errors: data.validationErrors?.[field.field_name] || []\n }))\n\n const pageContent = `\n <div class=\"space-y-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">${isEdit ? 'Edit Content' : 'New Content'}</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">\n ${data.collection.description || `Manage ${data.collection.display_name.toLowerCase()} content`}\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none\">\n <a href=\"${backUrl}\" class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 19l-7-7m0 0l7-7m-7 7h18\"/>\n </svg>\n Back to Content\n </a>\n </div>\n </div>\n\n <!-- Form Container -->\n <div class=\"rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden\">\n <!-- Form Header -->\n <div class=\"border-b border-zinc-950/5 dark:border-white/10 px-6 py-6\">\n <div class=\"flex items-center gap-x-3\">\n <div class=\"flex h-12 w-12 items-center justify-center rounded-lg bg-zinc-50 dark:bg-zinc-800 ring-1 ring-zinc-950/10 dark:ring-white/10\">\n <svg class=\"h-6 w-6 text-zinc-950 dark:text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z\"/>\n </svg>\n </div>\n <div>\n <h2 class=\"text-base/7 font-semibold text-zinc-950 dark:text-white\">${data.collection.display_name}</h2>\n <p class=\"text-sm/6 text-zinc-500 dark:text-zinc-400\">${isEdit ? 'Update your content' : 'Create new content'}</p>\n </div>\n </div>\n </div>\n\n <!-- Form Content -->\n <div class=\"px-6 py-6\">\n <div id=\"form-messages\">\n ${data.error ? renderAlert({ type: 'error', message: data.error, dismissible: true }) : ''}\n ${data.success ? renderAlert({ type: 'success', message: data.success, dismissible: true }) : ''}\n </div>\n\n <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <!-- Main Content Form -->\n <div class=\"lg:col-span-2\">\n <form\n id=\"content-form\"\n ${isEdit ? `hx-put=\"/admin/content/${data.id}\"` : `hx-post=\"/admin/content\"`}\n hx-target=\"#form-messages\"\n hx-encoding=\"multipart/form-data\"\n class=\"space-y-6\"\n >\n <input type=\"hidden\" name=\"collection_id\" value=\"${data.collection.id}\">\n ${isEdit ? `<input type=\"hidden\" name=\"id\" value=\"${data.id}\">` : ''}\n ${data.referrerParams ? `<input type=\"hidden\" name=\"referrer_params\" value=\"${data.referrerParams}\">` : ''}\n \n <!-- Core Fields -->\n ${renderFieldGroup('Basic Information', coreFieldsHTML)}\n \n <!-- Content Fields -->\n ${contentFields.length > 0 ? renderFieldGroup('Content Details', contentFieldsHTML) : ''}\n \n <!-- SEO & Meta Fields -->\n ${metaFields.length > 0 ? renderFieldGroup('SEO & Metadata', metaFieldsHTML, true) : ''}\n \n <div id=\"form-messages\"></div>\n </form>\n </div>\n\n <!-- Sidebar -->\n <div class=\"lg:col-span-1 space-y-6\">\n <!-- Publishing Options -->\n <div class=\"rounded-lg bg-zinc-50 dark:bg-zinc-800/50 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6\">\n <h3 class=\"text-base/7 font-semibold text-zinc-950 dark:text-white mb-4\">Publishing</h3>\n\n ${data.workflowEnabled ? `\n <!-- Workflow Status (when workflow plugin is enabled) -->\n <div class=\"mb-4\">\n <label for=\"status\" class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">Status</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select\n id=\"status\"\n name=\"status\"\n form=\"content-form\"\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6\"\n >\n <option value=\"draft\" ${data.status === 'draft' ? 'selected' : ''}>Draft</option>\n <option value=\"review\" ${data.status === 'review' ? 'selected' : ''}>Under Review</option>\n <option value=\"published\" ${data.status === 'published' ? 'selected' : ''}>Published</option>\n <option value=\"archived\" ${data.status === 'archived' ? 'selected' : ''}>Archived</option>\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n\n <!-- Scheduled Publishing -->\n <div class=\"mb-4\">\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Schedule Publish</label>\n <input\n type=\"datetime-local\"\n name=\"scheduled_publish_at\"\n form=\"content-form\"\n value=\"${data.scheduled_publish_at ? new Date(data.scheduled_publish_at).toISOString().slice(0, 16) : ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n >\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">Leave empty to publish immediately</p>\n </div>\n\n <!-- Scheduled Unpublishing -->\n <div class=\"mb-6\">\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Schedule Unpublish</label>\n <input\n type=\"datetime-local\"\n name=\"scheduled_unpublish_at\"\n form=\"content-form\"\n value=\"${data.scheduled_unpublish_at ? new Date(data.scheduled_unpublish_at).toISOString().slice(0, 16) : ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n >\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">Automatically unpublish at this time</p>\n </div>\n ` : `\n <!-- Simple Status (when workflow plugin is disabled) -->\n <div class=\"mb-6\">\n <label for=\"status\" class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">Status</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select\n id=\"status\"\n name=\"status\"\n form=\"content-form\"\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6\"\n >\n <option value=\"draft\" ${data.status === 'draft' ? 'selected' : ''}>Draft</option>\n <option value=\"published\" ${data.status === 'published' ? 'selected' : ''}>Published</option>\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">Enable Workflow plugin for advanced status management</p>\n </div>\n `}\n </div>\n\n <!-- Content Info -->\n ${isEdit ? `\n <div class=\"rounded-lg bg-zinc-50 dark:bg-zinc-800/50 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6\">\n <h3 class=\"text-base/7 font-semibold text-zinc-950 dark:text-white mb-4\">Content Info</h3>\n\n <dl class=\"space-y-3 text-sm\">\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Created</dt>\n <dd class=\"mt-1 text-zinc-950 dark:text-white\">${data.data?.created_at ? new Date(data.data.created_at).toLocaleDateString() : 'Unknown'}</dd>\n </div>\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Last Modified</dt>\n <dd class=\"mt-1 text-zinc-950 dark:text-white\">${data.data?.updated_at ? new Date(data.data.updated_at).toLocaleDateString() : 'Unknown'}</dd>\n </div>\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Author</dt>\n <dd class=\"mt-1 text-zinc-950 dark:text-white\">${data.data?.author || 'Unknown'}</dd>\n </div>\n ${data.data?.published_at ? `\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Published</dt>\n <dd class=\"mt-1 text-zinc-950 dark:text-white\">${new Date(data.data.published_at).toLocaleDateString()}</dd>\n </div>\n ` : ''}\n </dl>\n\n <div class=\"mt-4 pt-4 border-t border-zinc-950/5 dark:border-white/10\">\n <button\n type=\"button\"\n onclick=\"showVersionHistory('${data.id}')\"\n class=\"inline-flex items-center gap-x-1.5 text-sm font-medium text-zinc-950 dark:text-white hover:text-zinc-600 dark:hover:text-zinc-300 transition-colors\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z\"/>\n </svg>\n View Version History\n </button>\n </div>\n </div>\n ` : ''}\n\n <!-- Quick Actions -->\n <div class=\"rounded-lg bg-zinc-50 dark:bg-zinc-800/50 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6\">\n <h3 class=\"text-base/7 font-semibold text-zinc-950 dark:text-white mb-4\">Quick Actions</h3>\n\n <div class=\"space-y-2\">\n <button\n type=\"button\"\n onclick=\"previewContent()\"\n class=\"w-full inline-flex items-center gap-x-2 px-3 py-2 text-sm font-medium text-zinc-950 dark:text-white hover:bg-zinc-100 dark:hover:bg-zinc-700 rounded-lg transition-colors\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"></path>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"></path>\n </svg>\n Preview Content\n </button>\n\n <button\n type=\"button\"\n onclick=\"duplicateContent()\"\n class=\"w-full inline-flex items-center gap-x-2 px-3 py-2 text-sm font-medium text-zinc-950 dark:text-white hover:bg-zinc-100 dark:hover:bg-zinc-700 rounded-lg transition-colors\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"></path>\n </svg>\n Duplicate Content\n </button>\n\n ${isEdit ? `\n <button\n type=\"button\"\n onclick=\"deleteContent('${data.id}')\"\n class=\"w-full inline-flex items-center gap-x-2 px-3 py-2 text-sm font-medium text-pink-700 dark:text-pink-300 hover:bg-pink-50 dark:hover:bg-pink-900/20 rounded-lg transition-colors\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0\"/>\n </svg>\n Delete Content\n </button>\n ` : ''}\n </div>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"mt-6 pt-6 border-t border-zinc-950/5 dark:border-white/10 flex items-center justify-between\">\n <a href=\"${backUrl}\" class=\"inline-flex items-center justify-center gap-x-1.5 rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\">\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n Cancel\n </a>\n\n <div class=\"flex items-center gap-x-3\">\n <button\n type=\"submit\"\n form=\"content-form\"\n name=\"action\"\n value=\"save\"\n class=\"inline-flex items-center justify-center gap-x-1.5 rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 13l4 4L19 7\"/>\n </svg>\n ${isEdit ? 'Update' : 'Save'}\n </button>\n\n ${data.user?.role !== 'viewer' ? `\n <button\n type=\"submit\"\n form=\"content-form\"\n name=\"action\"\n value=\"save_and_publish\"\n class=\"inline-flex items-center justify-center gap-x-1.5 rounded-lg bg-lime-600 dark:bg-lime-500 px-3.5 py-2.5 text-sm font-semibold text-white hover:bg-lime-700 dark:hover:bg-lime-600 transition-colors shadow-sm\"\n >\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/>\n </svg>\n ${isEdit ? 'Update' : 'Save'} & Publish\n </button>\n ` : ''}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Confirmation Dialogs -->\n ${renderConfirmationDialog({\n id: 'duplicate-content-confirm',\n title: 'Duplicate Content',\n message: 'Create a copy of this content?',\n confirmText: 'Duplicate',\n cancelText: 'Cancel',\n iconColor: 'blue',\n confirmClass: 'bg-blue-500 hover:bg-blue-400',\n onConfirm: 'performDuplicateContent()'\n })}\n\n ${renderConfirmationDialog({\n id: 'delete-content-confirm',\n title: 'Delete Content',\n message: 'Are you sure you want to delete this content? This action cannot be undone.',\n confirmText: 'Delete',\n cancelText: 'Cancel',\n iconColor: 'red',\n confirmClass: 'bg-red-500 hover:bg-red-400',\n onConfirm: `performDeleteContent('${data.id}')`\n })}\n\n ${getConfirmationDialogScript()}\n\n <!-- TinyMCE CDN -->\n <script src=\"https://cdn.tiny.cloud/1/no-api-key/tinymce/6/tinymce.min.js\" referrerpolicy=\"origin\"></script>\n\n <!-- Dynamic Field Scripts -->\n <script>\n // Field group toggle\n function toggleFieldGroup(groupId) {\n const content = document.getElementById(groupId + '-content');\n const icon = document.getElementById(groupId + '-icon');\n \n if (content.classList.contains('hidden')) {\n content.classList.remove('hidden');\n icon.classList.remove('rotate-[-90deg]');\n } else {\n content.classList.add('hidden');\n icon.classList.add('rotate-[-90deg]');\n }\n }\n\n // Media field functions\n let currentMediaFieldId = null;\n\n function openMediaSelector(fieldId) {\n currentMediaFieldId = fieldId;\n // Store the original value in case user cancels\n const originalValue = document.getElementById(fieldId)?.value || '';\n\n // Open media library modal\n const modal = document.createElement('div');\n modal.className = 'fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50';\n modal.id = 'media-selector-modal';\n modal.innerHTML = \\`\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 w-full max-w-4xl max-h-[90vh] overflow-y-auto\">\n <h3 class=\"text-lg font-semibold text-zinc-950 dark:text-white mb-4\">Select Media</h3>\n <div id=\"media-grid-container\" hx-get=\"/admin/media/selector\" hx-trigger=\"load\"></div>\n <div class=\"mt-4 flex justify-end space-x-2\">\n <button\n onclick=\"cancelMediaSelection('\\${fieldId}', '\\${originalValue}')\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors\">\n Cancel\n </button>\n <button\n onclick=\"closeMediaSelector()\"\n class=\"rounded-lg bg-zinc-950 dark:bg-white px-4 py-2 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors\">\n OK\n </button>\n </div>\n </div>\n \\`;\n document.body.appendChild(modal);\n // Trigger HTMX for the modal content\n if (window.htmx) {\n htmx.process(modal);\n }\n }\n\n function closeMediaSelector() {\n const modal = document.getElementById('media-selector-modal');\n if (modal) {\n modal.remove();\n }\n currentMediaFieldId = null;\n }\n\n function cancelMediaSelection(fieldId, originalValue) {\n // Restore original value\n const hiddenInput = document.getElementById(fieldId);\n if (hiddenInput) {\n hiddenInput.value = originalValue;\n }\n\n // If original value was empty, hide the preview and show select button\n if (!originalValue) {\n const preview = document.getElementById(fieldId + '-preview');\n if (preview) {\n preview.classList.add('hidden');\n }\n }\n\n // Close modal\n closeMediaSelector();\n }\n\n function clearMediaField(fieldId) {\n document.getElementById(fieldId).value = '';\n document.getElementById(fieldId + '-preview').classList.add('hidden');\n }\n\n // Global function called by media selector buttons\n window.selectMediaFile = function(mediaId, mediaUrl, filename) {\n if (!currentMediaFieldId) {\n console.error('No field ID set for media selection');\n return;\n }\n\n const fieldId = currentMediaFieldId;\n\n // Set the hidden input value to the media URL (not ID)\n const hiddenInput = document.getElementById(fieldId);\n if (hiddenInput) {\n hiddenInput.value = mediaUrl;\n }\n\n // Update the preview\n const preview = document.getElementById(fieldId + '-preview');\n if (preview) {\n preview.innerHTML = \\`<img src=\"\\${mediaUrl}\" alt=\"\\${filename}\" class=\"w-32 h-32 object-cover rounded-lg border border-white/20\">\\`;\n preview.classList.remove('hidden');\n }\n\n // Show the remove button by finding the media actions container and updating it\n const mediaField = hiddenInput?.closest('.media-field-container');\n if (mediaField) {\n const actionsDiv = mediaField.querySelector('.media-actions');\n if (actionsDiv && !actionsDiv.querySelector('button:has-text(\"Remove\")')) {\n const removeBtn = document.createElement('button');\n removeBtn.type = 'button';\n removeBtn.onclick = () => clearMediaField(fieldId);\n removeBtn.className = 'inline-flex items-center px-4 py-2 bg-red-600 text-white rounded-xl hover:bg-red-700 transition-all';\n removeBtn.textContent = 'Remove';\n actionsDiv.appendChild(removeBtn);\n }\n }\n\n // DON'T close the modal - let user click OK button\n // Visual feedback: highlight the selected item\n document.querySelectorAll('#media-selector-grid [data-media-id]').forEach(el => {\n el.classList.remove('ring-2', 'ring-lime-500', 'dark:ring-lime-400');\n });\n const selectedItem = document.querySelector(\\`#media-selector-grid [data-media-id=\"\\${mediaId}\"]\\`);\n if (selectedItem) {\n selectedItem.classList.add('ring-2', 'ring-lime-500', 'dark:ring-lime-400');\n }\n };\n\n function setMediaField(fieldId, mediaUrl) {\n document.getElementById(fieldId).value = mediaUrl;\n const preview = document.getElementById(fieldId + '-preview');\n preview.innerHTML = \\`<img src=\"\\${mediaUrl}\" alt=\"Selected media\" class=\"w-32 h-32 object-cover rounded-lg ring-1 ring-zinc-950/10 dark:ring-white/10\">\\`;\n preview.classList.remove('hidden');\n\n // Close modal\n document.querySelector('.fixed.inset-0')?.remove();\n }\n\n // Custom select options\n function addCustomOption(input, selectId) {\n const value = input.value.trim();\n if (value) {\n const select = document.getElementById(selectId);\n const option = document.createElement('option');\n option.value = value;\n option.text = value;\n option.selected = true;\n select.appendChild(option);\n input.value = '';\n }\n }\n\n // Quick actions\n function previewContent() {\n const form = document.getElementById('content-form');\n const formData = new FormData(form);\n \n // Open preview in new window\n const preview = window.open('', '_blank');\n preview.document.write('<p>Loading preview...</p>');\n \n fetch('/admin/content/preview', {\n method: 'POST',\n body: formData\n })\n .then(response => response.text())\n .then(html => {\n preview.document.open();\n preview.document.write(html);\n preview.document.close();\n })\n .catch(error => {\n preview.document.write('<p>Error loading preview</p>');\n });\n }\n\n function duplicateContent() {\n showConfirmDialog('duplicate-content-confirm');\n }\n\n function performDuplicateContent() {\n const form = document.getElementById('content-form');\n const formData = new FormData(form);\n formData.append('action', 'duplicate');\n\n fetch('/admin/content/duplicate', {\n method: 'POST',\n body: formData\n })\n .then(response => response.json())\n .then(data => {\n if (data.success) {\n window.location.href = \\`/admin/content/\\${data.id}/edit\\`;\n } else {\n alert('Error duplicating content');\n }\n });\n }\n\n function deleteContent(contentId) {\n showConfirmDialog('delete-content-confirm');\n }\n\n function performDeleteContent(contentId) {\n fetch(\\`/admin/content/\\${contentId}\\`, {\n method: 'DELETE'\n })\n .then(response => {\n if (response.ok) {\n window.location.href = '/admin/content';\n } else {\n alert('Error deleting content');\n }\n });\n }\n\n function showVersionHistory(contentId) {\n // Create and show version history modal\n const modal = document.createElement('div');\n modal.className = 'fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50';\n modal.innerHTML = \\`\n <div id=\"version-history-content\">\n <div class=\"flex items-center justify-center h-32\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 dark:border-blue-400\"></div>\n </div>\n </div>\n \\`;\n document.body.appendChild(modal);\n\n // Load version history\n fetch(\\`/admin/content/\\${contentId}/versions\\`)\n .then(response => response.text())\n .then(html => {\n document.getElementById('version-history-content').innerHTML = html;\n })\n .catch(error => {\n console.error('Error loading version history:', error);\n document.getElementById('version-history-content').innerHTML = '<p class=\"text-zinc-950 dark:text-white\">Error loading version history</p>';\n });\n }\n\n // Auto-save functionality\n let autoSaveTimeout;\n function scheduleAutoSave() {\n clearTimeout(autoSaveTimeout);\n autoSaveTimeout = setTimeout(() => {\n const form = document.getElementById('content-form');\n const formData = new FormData(form);\n formData.append('action', 'autosave');\n \n fetch(form.action, {\n method: 'POST',\n body: formData\n })\n .then(response => {\n if (response.ok) {\n console.log('Auto-saved');\n }\n })\n .catch(error => console.error('Auto-save failed:', error));\n }, 30000); // Auto-save every 30 seconds\n }\n\n // Bind auto-save to form changes\n document.addEventListener('DOMContentLoaded', function() {\n const form = document.getElementById('content-form');\n form.addEventListener('input', scheduleAutoSave);\n form.addEventListener('change', scheduleAutoSave);\n });\n </script>\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: title,\n pageTitle: 'Content Management',\n currentPath: '/admin/content',\n user: data.user,\n content: pageContent,\n version: data.version\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}","export interface FieldDefinition {\n id: string\n field_name: string\n field_type: string\n field_label: string\n field_options: any // JSON options\n field_order: number\n is_required: boolean\n is_searchable: boolean\n}\n\nexport interface FieldRenderOptions {\n value?: any\n errors?: string[]\n disabled?: boolean\n className?: string\n}\n\nexport function renderDynamicField(field: FieldDefinition, options: FieldRenderOptions = {}): string {\n const { value = '', errors = [], disabled = false, className = '' } = options\n const opts = field.field_options || {}\n const required = field.is_required ? 'required' : ''\n const baseClasses = `w-full rounded-lg px-3 py-2 text-sm text-zinc-950 dark:text-white bg-white dark:bg-zinc-800 shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow ${className}`\n const errorClasses = errors.length > 0 ? 'ring-pink-600 dark:ring-pink-500 focus:ring-pink-600 dark:focus:ring-pink-500' : ''\n\n const fieldId = `field-${field.field_name}`\n const fieldName = field.field_name\n \n let fieldHTML = ''\n \n switch (field.field_type) {\n case 'text':\n let patternHelp = ''\n let autoSlugScript = ''\n \n if (opts.pattern) {\n if (opts.pattern === '^[a-z0-9-]+$' || opts.pattern === '^[a-zA-Z0-9_-]+$') {\n patternHelp = '<p class=\"mt-2 text-xs text-zinc-500 dark:text-zinc-400\">Use letters, numbers, underscores, and hyphens only</p>'\n\n // Add auto-slug generation for slug fields\n if (fieldName === 'slug') {\n patternHelp += '<button type=\"button\" class=\"mt-1 text-xs text-cyan-600 dark:text-cyan-400 hover:text-cyan-700 dark:hover:text-cyan-300\" onclick=\"generateSlugFromTitle(\\'${fieldId}\\')\">Generate from title</button>'\n autoSlugScript = `\n <script>\n function generateSlugFromTitle(slugFieldId) {\n const titleField = document.querySelector('input[name=\"title\"]');\n const slugField = document.getElementById(slugFieldId);\n if (titleField && slugField) {\n const slug = titleField.value\n .toLowerCase()\n .replace(/[^a-z0-9\\\\s_-]/g, '')\n .replace(/\\\\s+/g, '-')\n .replace(/[-_]+/g, '-')\n .replace(/^[-_]|[-_]$/g, '');\n slugField.value = slug;\n }\n }\n \n // Auto-generate slug when title changes\n document.addEventListener('DOMContentLoaded', function() {\n const titleField = document.querySelector('input[name=\"title\"]');\n const slugField = document.getElementById('${fieldId}');\n if (titleField && slugField && !slugField.value) {\n titleField.addEventListener('input', function() {\n if (!slugField.value) {\n generateSlugFromTitle('${fieldId}');\n }\n });\n }\n });\n </script>\n `\n }\n } else {\n patternHelp = '<p class=\"mt-2 text-xs text-zinc-500 dark:text-zinc-400\">Must match required format</p>'\n }\n }\n \n fieldHTML = `\n <input \n type=\"text\" \n id=\"${fieldId}\"\n name=\"${fieldName}\"\n value=\"${escapeHtml(value)}\"\n placeholder=\"${opts.placeholder || ''}\"\n maxlength=\"${opts.maxLength || ''}\"\n ${opts.pattern ? `data-pattern=\"${opts.pattern}\"` : ''}\n class=\"${baseClasses} ${errorClasses}\"\n ${required}\n ${disabled ? 'disabled' : ''}\n >\n ${patternHelp}\n ${autoSlugScript}\n ${opts.pattern ? `\n <script>\n (function() {\n const field = document.getElementById('${fieldId}');\n const pattern = new RegExp('${opts.pattern}');\n \n field.addEventListener('input', function() {\n if (this.value && !pattern.test(this.value)) {\n if ('${opts.pattern}' === '^[a-zA-Z0-9_-]+$' || '${opts.pattern}' === '^[a-z0-9-]+$') {\n this.setCustomValidity('Please use only letters, numbers, underscores, and hyphens.');\n } else {\n this.setCustomValidity('Please enter a valid format.');\n }\n } else {\n this.setCustomValidity('');\n }\n });\n \n field.addEventListener('blur', function() {\n this.reportValidity();\n });\n })();\n </script>\n ` : ''}\n `\n break\n \n case 'richtext':\n fieldHTML = `\n <div class=\"richtext-container\">\n <textarea \n id=\"${fieldId}\"\n name=\"${fieldName}\"\n class=\"${baseClasses} ${errorClasses} min-h-[${opts.height || 300}px]\"\n ${required}\n ${disabled ? 'disabled' : ''}\n >${escapeHtml(value)}</textarea>\n <script>\n // Initialize TinyMCE for this field\n if (typeof tinymce !== 'undefined') {\n tinymce.init({\n selector: '#${fieldId}',\n skin: 'oxide-dark',\n content_css: 'dark',\n height: ${opts.height || 300},\n menubar: false,\n plugins: [\n 'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',\n 'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',\n 'insertdatetime', 'media', 'table', 'help', 'wordcount'\n ],\n toolbar: '${opts.toolbar === 'simple' ? 'bold italic underline | bullist numlist | link' : \n 'undo redo | blocks | bold italic backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | help'}',\n content_style: 'body { font-family: -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif; font-size: 14px; color: #fff; background-color: #1f2937; }',\n setup: function(editor) {\n editor.on('change', function() {\n editor.save();\n });\n }\n });\n }\n </script>\n </div>\n `\n break\n \n case 'number':\n fieldHTML = `\n <input \n type=\"number\" \n id=\"${fieldId}\"\n name=\"${fieldName}\"\n value=\"${value}\"\n min=\"${opts.min || ''}\"\n max=\"${opts.max || ''}\"\n step=\"${opts.step || ''}\"\n placeholder=\"${opts.placeholder || ''}\"\n class=\"${baseClasses} ${errorClasses}\"\n ${required}\n ${disabled ? 'disabled' : ''}\n >\n `\n break\n \n case 'boolean':\n const checked = value === true || value === 'true' || value === '1' ? 'checked' : ''\n fieldHTML = `\n <div class=\"flex items-center space-x-3\">\n <input \n type=\"checkbox\" \n id=\"${fieldId}\"\n name=\"${fieldName}\"\n value=\"true\"\n class=\"w-5 h-5 text-blue-600 bg-white/10 border-white/20 rounded focus:ring-blue-500 focus:ring-2\"\n ${checked}\n ${disabled ? 'disabled' : ''}\n >\n <label for=\"${fieldId}\" class=\"text-sm text-gray-300\">\n ${opts.checkboxLabel || field.field_label}\n </label>\n </div>\n <input type=\"hidden\" name=\"${fieldName}_submitted\" value=\"1\">\n `\n break\n \n case 'date':\n fieldHTML = `\n <input \n type=\"date\" \n id=\"${fieldId}\"\n name=\"${fieldName}\"\n value=\"${value}\"\n min=\"${opts.min || ''}\"\n max=\"${opts.max || ''}\"\n class=\"${baseClasses} ${errorClasses}\"\n ${required}\n ${disabled ? 'disabled' : ''}\n >\n `\n break\n \n case 'select':\n const options = opts.options || []\n const multiple = opts.multiple ? 'multiple' : ''\n const selectedValues = Array.isArray(value) ? value : [value]\n \n fieldHTML = `\n <select \n id=\"${fieldId}\"\n name=\"${fieldName}${opts.multiple ? '[]' : ''}\"\n class=\"${baseClasses} ${errorClasses}\"\n ${multiple}\n ${required}\n ${disabled ? 'disabled' : ''}\n >\n ${!required && !opts.multiple ? '<option value=\"\">Choose an option...</option>' : ''}\n ${options.map((option: any) => {\n const optionValue = typeof option === 'string' ? option : option.value\n const optionLabel = typeof option === 'string' ? option : option.label\n const selected = selectedValues.includes(optionValue) ? 'selected' : ''\n return `<option value=\"${escapeHtml(optionValue)}\" ${selected}>${escapeHtml(optionLabel)}</option>`\n }).join('')}\n </select>\n ${opts.allowCustom ? `\n <div class=\"mt-2\">\n <input \n type=\"text\" \n placeholder=\"Add custom option...\"\n class=\"${baseClasses.replace('border-white/10', 'border-white/5')} text-sm\"\n onkeypress=\"if(event.key==='Enter'){addCustomOption(this, '${fieldId}');event.preventDefault();}\"\n >\n </div>\n ` : ''}\n `\n break\n \n case 'media':\n fieldHTML = `\n <div class=\"media-field-container\">\n <input type=\"hidden\" id=\"${fieldId}\" name=\"${fieldName}\" value=\"${value}\">\n <div class=\"media-preview ${value ? '' : 'hidden'}\" id=\"${fieldId}-preview\">\n ${value ? `<img src=\"${value}\" alt=\"Selected media\" class=\"w-32 h-32 object-cover rounded-lg border border-white/20\">` : ''}\n </div>\n <div class=\"media-actions mt-2 space-x-2\">\n <button\n type=\"button\"\n onclick=\"openMediaSelector('${fieldId}')\"\n class=\"inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-all\"\n ${disabled ? 'disabled' : ''}\n >\n <svg class=\"w-4 h-4 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"></path>\n </svg>\n Select Media\n </button>\n ${value ? `\n <button\n type=\"button\"\n onclick=\"clearMediaField('${fieldId}')\"\n class=\"inline-flex items-center px-4 py-2 bg-red-600 text-white rounded-xl hover:bg-red-700 transition-all\"\n ${disabled ? 'disabled' : ''}\n >\n Remove\n </button>\n ` : ''}\n </div>\n </div>\n `\n break\n\n case 'guid':\n // GUID fields are read-only and auto-generated\n const displayValue = value || '(auto-generated on save)'\n fieldHTML = `\n <div class=\"guid-field-container\">\n <input\n type=\"text\"\n id=\"${fieldId}\"\n name=\"${fieldName}\"\n value=\"${escapeHtml(value)}\"\n class=\"${baseClasses} bg-zinc-100 dark:bg-zinc-800/50 cursor-not-allowed\"\n readonly\n disabled\n >\n <div class=\"mt-2 flex items-start gap-x-2\">\n <svg class=\"h-5 w-5 text-cyan-600 dark:text-cyan-400 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\"/>\n </svg>\n <div class=\"text-xs text-zinc-600 dark:text-zinc-400\">\n ${value\n ? 'This unique identifier was automatically generated and cannot be changed.'\n : 'A unique identifier (UUID) will be automatically generated when you save this content.'}\n </div>\n </div>\n </div>\n `\n break\n\n default:\n fieldHTML = `\n <input \n type=\"text\" \n id=\"${fieldId}\"\n name=\"${fieldName}\"\n value=\"${escapeHtml(value)}\"\n class=\"${baseClasses} ${errorClasses}\"\n ${required}\n ${disabled ? 'disabled' : ''}\n >\n `\n }\n \n return `\n <div class=\"form-group\">\n <label for=\"${fieldId}\" class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2\">\n ${escapeHtml(field.field_label)}\n ${field.is_required ? '<span class=\"text-pink-600 dark:text-pink-400 ml-1\">*</span>' : ''}\n </label>\n ${fieldHTML}\n ${errors.length > 0 ? `\n <div class=\"mt-2 text-sm text-pink-600 dark:text-pink-400\">\n ${errors.map(error => `<div>${escapeHtml(error)}</div>`).join('')}\n </div>\n ` : ''}\n ${opts.helpText ? `\n <div class=\"mt-2 text-xs text-zinc-500 dark:text-zinc-400\">\n ${escapeHtml(opts.helpText)}\n </div>\n ` : ''}\n </div>\n `\n}\n\nexport function renderFieldGroup(title: string, fields: string[], collapsible: boolean = false): string {\n const groupId = title.toLowerCase().replace(/\\s+/g, '-')\n\n return `\n <div class=\"field-group rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 mb-6\">\n <div class=\"field-group-header border-b border-zinc-950/5 dark:border-white/10 px-6 py-4 ${collapsible ? 'cursor-pointer' : ''}\" ${collapsible ? `onclick=\"toggleFieldGroup('${groupId}')\"` : ''}>\n <h3 class=\"text-base/7 font-semibold text-zinc-950 dark:text-white flex items-center\">\n ${escapeHtml(title)}\n ${collapsible ? `\n <svg id=\"${groupId}-icon\" class=\"w-5 h-5 ml-2 transform transition-transform text-zinc-500 dark:text-zinc-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"></path>\n </svg>\n ` : ''}\n </h3>\n </div>\n <div id=\"${groupId}-content\" class=\"field-group-content px-6 py-6 space-y-6 ${collapsible ? 'collapsible' : ''}\">\n ${fields.join('')}\n </div>\n </div>\n `\n}\n\nfunction escapeHtml(text: string): string {\n if (typeof text !== 'string') return String(text || '')\n return text.replace(/[&<>\"']/g, (char) => ({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n }[char] || char))\n}","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\nimport { renderPagination, PaginationData } from '../pagination.template'\nimport { renderTable, TableData, TableColumn } from '../table.template'\nimport { renderFilterBar, FilterBarData } from '../filter-bar.template'\nimport { renderConfirmationDialog, getConfirmationDialogScript } from '../confirmation-dialog.template'\n\nexport interface ContentItem {\n id: string\n title: string\n slug: string\n modelName: string\n statusBadge: string\n authorName: string\n formattedDate: string\n availableActions: string[]\n}\n\nexport interface ContentListPageData {\n modelName: string\n status: string\n page: number\n search?: string\n models: Array<{\n name: string\n displayName: string\n }>\n contentItems: ContentItem[]\n totalItems: number\n itemsPerPage: number\n user?: {\n name: string\n email: string\n role: string\n }\n version?: string\n}\n\nexport function renderContentListPage(data: ContentListPageData): string {\n // Build current URL parameters to pass to edit page\n const urlParams = new URLSearchParams()\n if (data.modelName && data.modelName !== 'all') urlParams.set('model', data.modelName)\n if (data.status && data.status !== 'all') urlParams.set('status', data.status)\n if (data.search) urlParams.set('search', data.search)\n if (data.page && data.page !== 1) urlParams.set('page', data.page.toString())\n const currentParams = urlParams.toString()\n\n // Check if filters are active (not in default state)\n const hasActiveFilters = data.modelName !== 'all' || data.status !== 'all' || !!data.search\n\n // Prepare filter bar data\n const filterBarData: FilterBarData = {\n filters: [\n {\n name: 'model',\n label: 'Model',\n options: [\n { value: 'all', label: 'All Models', selected: data.modelName === 'all' },\n ...data.models.map(model => ({\n value: model.name,\n label: model.displayName,\n selected: data.modelName === model.name\n }))\n ]\n },\n {\n name: 'status',\n label: 'Status',\n options: [\n { value: 'all', label: 'All Status', selected: data.status === 'all' },\n { value: 'draft', label: 'Draft', selected: data.status === 'draft' },\n { value: 'review', label: 'Under Review', selected: data.status === 'review' },\n { value: 'scheduled', label: 'Scheduled', selected: data.status === 'scheduled' },\n { value: 'published', label: 'Published', selected: data.status === 'published' },\n { value: 'archived', label: 'Archived', selected: data.status === 'archived' },\n { value: 'deleted', label: 'Deleted', selected: data.status === 'deleted' }\n ]\n }\n ],\n actions: [\n {\n label: 'Refresh',\n className: 'btn-secondary',\n onclick: 'location.reload()'\n }\n ],\n bulkActions: [\n { label: 'Publish', value: 'publish', icon: 'check-circle' },\n { label: 'Unpublish', value: 'unpublish', icon: 'x-circle' },\n { label: 'Delete', value: 'delete', icon: 'trash', className: 'text-pink-600' }\n ]\n }\n\n // Prepare table data\n const tableColumns: TableColumn[] = [\n {\n key: 'title',\n label: 'Title',\n sortable: true,\n sortType: 'string',\n render: (value, row) => `\n <div class=\"flex items-center\">\n <div>\n <div class=\"text-sm font-medium text-zinc-950 dark:text-white\">\n <a href=\"/content/${row.id}\" class=\"hover:text-blue-600 dark:hover:text-blue-400 transition-colors\">${row.title}</a>\n </div>\n <div class=\"text-sm text-zinc-500 dark:text-zinc-400\">${row.slug}</div>\n </div>\n </div>\n `\n },\n {\n key: 'modelName',\n label: 'Model',\n sortable: true,\n sortType: 'string',\n className: 'text-sm text-zinc-500 dark:text-zinc-400'\n },\n {\n key: 'statusBadge',\n label: 'Status',\n sortable: true,\n sortType: 'string',\n render: (value) => value\n },\n {\n key: 'authorName',\n label: 'Author',\n sortable: true,\n sortType: 'string',\n className: 'text-sm text-zinc-500 dark:text-zinc-400'\n },\n {\n key: 'formattedDate',\n label: 'Updated',\n sortable: true,\n sortType: 'date',\n className: 'text-sm text-zinc-500 dark:text-zinc-400'\n },\n {\n key: 'actions',\n label: 'Actions',\n sortable: false,\n className: 'text-sm font-medium',\n render: (value, row) => `\n <div class=\"flex space-x-2\">\n <button\n class=\"inline-flex items-center justify-center p-1.5 rounded-lg bg-cyan-50 dark:bg-cyan-500/10 text-cyan-700 dark:text-cyan-400 ring-1 ring-inset ring-cyan-600/20 dark:ring-cyan-500/20 hover:bg-cyan-100 dark:hover:bg-cyan-500/20 transition-colors\"\n onclick=\"window.location.href='/admin/content/${row.id}/edit${currentParams ? `?ref=${encodeURIComponent(currentParams)}` : ''}'\"\n title=\"Edit\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z\"/>\n </svg>\n </button>\n <button\n class=\"inline-flex items-center justify-center p-1.5 rounded-lg bg-red-50 dark:bg-red-500/10 text-red-700 dark:text-red-400 ring-1 ring-inset ring-red-600/20 dark:ring-red-500/20 hover:bg-red-100 dark:hover:bg-red-500/20 transition-colors\"\n hx-delete=\"/admin/content/${row.id}\"\n hx-confirm=\"Are you sure you want to delete this content item?\"\n hx-target=\"#content-list\"\n hx-swap=\"outerHTML\"\n title=\"Delete\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"/>\n </svg>\n </button>\n </div>\n `\n }\n ]\n\n const tableData: TableData<ContentItem> = {\n tableId: 'content-table',\n columns: tableColumns,\n rows: data.contentItems,\n selectable: true,\n rowClickable: true,\n rowClickUrl: (row: ContentItem) => `/admin/content/${row.id}/edit${currentParams ? `?ref=${encodeURIComponent(currentParams)}` : ''}`,\n emptyMessage: 'No content found. Create your first content item to get started.'\n }\n\n // Prepare pagination data\n const totalPages = Math.ceil(data.totalItems / data.itemsPerPage)\n const startItem = (data.page - 1) * data.itemsPerPage + 1\n const endItem = Math.min(data.page * data.itemsPerPage, data.totalItems)\n\n const paginationData: PaginationData = {\n currentPage: data.page,\n totalPages,\n totalItems: data.totalItems,\n itemsPerPage: data.itemsPerPage,\n startItem,\n endItem,\n baseUrl: '/admin/content',\n queryParams: {\n model: data.modelName,\n status: data.status,\n ...(data.search ? { search: data.search } : {})\n },\n showPageSizeSelector: true,\n pageSizeOptions: [10, 20, 50, 100]\n }\n\n // Generate page content\n const pageContent = `\n <div>\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">Content Management</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">Manage and organize your content items</p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none\">\n <a href=\"/admin/content/new\" class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n New Content\n </a>\n </div>\n </div>\n <!-- Filters -->\n <div class=\"relative rounded-xl mb-6\">\n <!-- Gradient Background -->\n <div class=\"absolute inset-0 bg-gradient-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10 dark:from-cyan-400/20 dark:via-blue-400/20 dark:to-purple-400/20 rounded-xl\"></div>\n\n <div class=\"relative bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 rounded-xl\">\n <div class=\"px-6 py-5\">\n <div class=\"flex items-center justify-between\">\n <div class=\"flex items-center space-x-4\">\n <!-- Search Input -->\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Search</label>\n <form onsubmit=\"performContentSearch(event)\" class=\"flex items-center space-x-2\">\n <div class=\"relative group\">\n <input\n type=\"text\"\n name=\"search\"\n id=\"content-search-input\"\n value=\"${data.search || ''}\"\n oninput=\"toggleContentClearButton()\"\n placeholder=\"Search content...\"\n class=\"rounded-full bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2.5 pl-11 pr-10 text-sm w-72 text-zinc-950 dark:text-white border-2 border-cyan-200/50 dark:border-cyan-700/50 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:bg-white dark:focus:bg-zinc-800 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n >\n <div class=\"absolute left-3.5 top-2.5 flex items-center justify-center w-5 h-5 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 dark:from-cyan-300 dark:to-blue-400 opacity-90 group-focus-within:opacity-100 transition-opacity\">\n <svg class=\"h-3 w-3 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"/>\n </svg>\n </div>\n <button\n type=\"button\"\n id=\"clear-content-search\"\n onclick=\"clearContentSearch()\"\n class=\"${data.search ? '' : 'hidden'} absolute right-3 top-3 flex items-center justify-center w-5 h-5 rounded-full bg-zinc-400/20 dark:bg-zinc-500/20 hover:bg-zinc-400/30 dark:hover:bg-zinc-500/30 transition-colors\"\n >\n <svg class=\"h-3 w-3 text-zinc-600 dark:text-zinc-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n <button\n type=\"submit\"\n class=\"inline-flex items-center gap-x-1.5 px-4 py-2.5 bg-gradient-to-r from-cyan-500 to-blue-500 dark:from-cyan-400 dark:to-blue-400 text-white text-sm font-medium rounded-full hover:from-cyan-600 hover:to-blue-600 dark:hover:from-cyan-500 dark:hover:to-blue-500 shadow-md hover:shadow-lg transition-all duration-200\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"/>\n </svg>\n Search\n </button>\n </form>\n <script>\n function performContentSearch(event) {\n event.preventDefault();\n const searchInput = document.getElementById('content-search-input');\n const value = searchInput.value.trim();\n const params = new URLSearchParams(window.location.search);\n if (value) {\n params.set('search', value);\n } else {\n params.delete('search');\n }\n params.set('page', '1');\n window.location.href = window.location.pathname + '?' + params.toString();\n }\n\n function clearContentSearch() {\n const params = new URLSearchParams(window.location.search);\n params.delete('search');\n params.set('page', '1');\n window.location.href = window.location.pathname + (params.toString() ? '?' + params.toString() : '');\n }\n\n function toggleContentClearButton() {\n const searchInput = document.getElementById('content-search-input');\n const clearButton = document.getElementById('clear-content-search');\n if (searchInput.value.trim()) {\n clearButton.classList.remove('hidden');\n } else {\n clearButton.classList.add('hidden');\n }\n }\n\n function updateContentFilters(filterName, filterValue) {\n const params = new URLSearchParams(window.location.search);\n params.set(filterName, filterValue);\n params.set('page', '1');\n window.location.href = window.location.pathname + '?' + params.toString();\n }\n\n function clearAllFilters() {\n window.location.href = window.location.pathname;\n }\n </script>\n </div>\n\n ${filterBarData.filters.map(filter => {\n const selectedOption = filter.options.find(opt => opt.selected);\n const selectedColor = selectedOption?.color || 'cyan';\n const colorMap: Record<string, string> = {\n 'cyan': 'bg-cyan-400 dark:bg-cyan-400',\n 'lime': 'bg-lime-400 dark:bg-lime-400',\n 'pink': 'bg-pink-400 dark:bg-pink-400',\n 'purple': 'bg-purple-400 dark:bg-purple-400',\n 'amber': 'bg-amber-400 dark:bg-amber-400',\n 'zinc': 'bg-zinc-400 dark:bg-zinc-400'\n };\n\n return `\n <div>\n <label class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">${filter.label}</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <div class=\"col-start-1 row-start-1 flex items-center gap-3 pl-3 pr-8 pointer-events-none\">\n ${filter.name === 'status' ? `<span class=\"inline-block size-2 shrink-0 rounded-full border border-transparent ${colorMap[selectedColor]}\"></span>` : ''}\n </div>\n <select\n name=\"${filter.name}\"\n onchange=\"updateContentFilters('${filter.name}', this.value)\"\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 ${filter.name === 'status' ? 'pl-8' : 'pl-3'} pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-cyan-500/30 dark:outline-cyan-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-cyan-500 dark:focus-visible:outline-cyan-400 sm:text-sm/6 min-w-48\"\n >\n ${filter.options.map(opt => `\n <option value=\"${opt.value}\" ${opt.selected ? 'selected' : ''}>${opt.label}</option>\n `).join('')}\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-cyan-600 dark:text-cyan-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n `}).join('')}\n\n <!-- Clear Filters Button -->\n ${hasActiveFilters ? `\n <div>\n <label class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2\"> </label>\n <button\n onclick=\"clearAllFilters()\"\n class=\"inline-flex items-center gap-x-1.5 px-3 py-2 bg-pink-50 dark:bg-pink-500/10 text-pink-700 dark:text-pink-300 text-sm font-medium rounded-md ring-1 ring-inset ring-pink-600/20 dark:ring-pink-500/20 hover:bg-pink-100 dark:hover:bg-pink-500/20 transition-colors\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n Clear Filters\n </button>\n </div>\n ` : ''}\n </div>\n <div class=\"flex items-center gap-x-3\">\n <span class=\"text-sm/6 font-medium text-zinc-700 dark:text-zinc-300 px-3 py-1.5 rounded-full bg-white/60 dark:bg-zinc-800/60 backdrop-blur-sm\">${data.totalItems} ${data.totalItems === 1 ? 'item' : 'items'}</span>\n ${filterBarData.actions?.map(action => `\n <button\n ${action.onclick ? `onclick=\"${action.onclick}\"` : ''}\n ${action.hxGet ? `hx-get=\"${action.hxGet}\"` : ''}\n ${action.hxTarget ? `hx-target=\"${action.hxTarget}\"` : ''}\n class=\"inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm text-zinc-950 dark:text-white text-sm font-medium rounded-full ring-1 ring-inset ring-cyan-200/50 dark:ring-cyan-700/50 hover:bg-gradient-to-r hover:from-cyan-50 hover:to-blue-50 dark:hover:from-cyan-900/30 dark:hover:to-blue-900/30 hover:ring-cyan-300 dark:hover:ring-cyan-600 transition-all duration-200\"\n >\n ${action.label === 'Refresh' ? `\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"/>\n </svg>\n ` : ''}\n ${action.label}\n </button>\n `).join('') || ''}\n ${filterBarData.bulkActions && filterBarData.bulkActions.length > 0 ? `\n <div class=\"relative inline-block\" id=\"bulk-actions-dropdown\">\n <button\n id=\"bulk-actions-btn\"\n onclick=\"toggleBulkActionsDropdown()\"\n class=\"inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-zinc-100/60 dark:bg-zinc-800/60 backdrop-blur-sm text-zinc-400 dark:text-zinc-600 text-sm font-medium rounded-full ring-1 ring-inset ring-zinc-200/50 dark:ring-zinc-700/50 cursor-not-allowed\"\n disabled\n >\n Bulk Actions\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"size-4\">\n <path d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </button>\n\n <div\n id=\"bulk-actions-menu\"\n class=\"hidden absolute right-0 mt-2 w-56 origin-top-right divide-y divide-zinc-200 dark:divide-white/10 rounded-lg bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 z-50 transition-all duration-100 scale-95 opacity-0\"\n style=\"transition-behavior: allow-discrete;\"\n >\n <div class=\"py-1\">\n <button\n onclick=\"performBulkAction('publish')\"\n class=\"group/item flex w-full items-center px-4 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-white/5 hover:text-zinc-950 dark:hover:text-white transition-colors\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"mr-3 size-5 text-zinc-400 dark:text-zinc-500 group-hover/item:text-zinc-950 dark:group-hover/item:text-white\">\n <path fill-rule=\"evenodd\" d=\"M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z\" clip-rule=\"evenodd\" />\n </svg>\n Publish Selected\n </button>\n <button\n onclick=\"performBulkAction('draft')\"\n class=\"group/item flex w-full items-center px-4 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-white/5 hover:text-zinc-950 dark:hover:text-white transition-colors\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"mr-3 size-5 text-zinc-400 dark:text-zinc-500 group-hover/item:text-zinc-950 dark:group-hover/item:text-white\">\n <path d=\"m5.433 13.917 1.262-3.155A4 4 0 0 1 7.58 9.42l6.92-6.918a2.121 2.121 0 0 1 3 3l-6.92 6.918c-.383.383-.84.685-1.343.886l-3.154 1.262a.5.5 0 0 1-.65-.65Z\" />\n <path d=\"M3.5 5.75c0-.69.56-1.25 1.25-1.25H10A.75.75 0 0 0 10 3H4.75A2.75 2.75 0 0 0 2 5.75v9.5A2.75 2.75 0 0 0 4.75 18h9.5A2.75 2.75 0 0 0 17 15.25V10a.75.75 0 0 0-1.5 0v5.25c0 .69-.56 1.25-1.25 1.25h-9.5c-.69 0-1.25-.56-1.25-1.25v-9.5Z\" />\n </svg>\n Move to Draft\n </button>\n </div>\n <div class=\"py-1\">\n <button\n onclick=\"performBulkAction('delete')\"\n class=\"group/item flex w-full items-center px-4 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:bg-red-50 dark:hover:bg-red-500/10 hover:text-red-600 dark:hover:text-red-400 transition-colors\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"mr-3 size-5 text-zinc-400 dark:text-zinc-500 group-hover/item:text-red-600 dark:group-hover/item:text-red-400\">\n <path fill-rule=\"evenodd\" d=\"M8.75 1A2.75 2.75 0 0 0 6 3.75v.443c-.795.077-1.584.176-2.365.298a.75.75 0 1 0 .23 1.482l.149-.022.841 10.518A2.75 2.75 0 0 0 7.596 19h4.807a2.75 2.75 0 0 0 2.742-2.53l.841-10.52.149.023a.75.75 0 0 0 .23-1.482A41.03 41.03 0 0 0 14 4.193V3.75A2.75 2.75 0 0 0 11.25 1h-2.5ZM10 4c.84 0 1.673.025 2.5.075V3.75c0-.69-.56-1.25-1.25-1.25h-2.5c-.69 0-1.25.56-1.25 1.25v.325C8.327 4.025 9.16 4 10 4ZM8.58 7.72a.75.75 0 0 0-1.5.06l.3 7.5a.75.75 0 1 0 1.5-.06l-.3-7.5Zm4.34.06a.75.75 0 1 0-1.5-.06l-.3 7.5a.75.75 0 1 0 1.5.06l.3-7.5Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n Delete Selected\n </button>\n </div>\n </div>\n </div>\n ` : ''}\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Content List -->\n <div id=\"content-list\">\n ${renderTable(tableData)}\n ${renderPagination(paginationData)}\n </div>\n \n </div>\n \n <!-- Modals -->\n <div id=\"bulk-actions-modal\"></div>\n <div id=\"versions-modal\"></div>\n \n <script>\n // Update bulk actions button state\n function updateBulkActionsButton() {\n const checkboxes = document.querySelectorAll('input[type=\"checkbox\"].row-checkbox');\n const checkedCount = Array.from(checkboxes).filter(cb => cb.checked).length;\n const btn = document.getElementById('bulk-actions-btn');\n const menu = document.getElementById('bulk-actions-menu');\n\n if (!btn) return;\n\n if (checkedCount > 0) {\n btn.disabled = false;\n btn.className = 'inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm text-zinc-950 dark:text-white text-sm font-medium rounded-full ring-1 ring-inset ring-cyan-200/50 dark:ring-cyan-700/50 hover:bg-gradient-to-r hover:from-cyan-50 hover:to-blue-50 dark:hover:from-cyan-900/30 dark:hover:to-blue-900/30 hover:ring-cyan-300 dark:hover:ring-cyan-600 transition-all duration-200';\n } else {\n btn.disabled = true;\n btn.className = 'inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-zinc-100/60 dark:bg-zinc-800/60 backdrop-blur-sm text-zinc-400 dark:text-zinc-600 text-sm font-medium rounded-full ring-1 ring-inset ring-zinc-200/50 dark:ring-zinc-700/50 cursor-not-allowed';\n // Hide menu when no items selected\n if (menu) {\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0', 'hidden');\n }\n }\n }\n\n // Select all functionality\n document.addEventListener('change', function(e) {\n if (e.target.id === 'select-all') {\n const checkboxes = document.querySelectorAll('.row-checkbox');\n checkboxes.forEach(cb => cb.checked = e.target.checked);\n updateBulkActionsButton();\n } else if (e.target.classList.contains('row-checkbox')) {\n updateBulkActionsButton();\n }\n });\n\n // Initialize button state on page load\n document.addEventListener('DOMContentLoaded', function() {\n updateBulkActionsButton();\n });\n\n // Toggle bulk actions dropdown\n function toggleBulkActionsDropdown() {\n const checkboxes = document.querySelectorAll('input[type=\"checkbox\"].row-checkbox');\n const checkedCount = Array.from(checkboxes).filter(cb => cb.checked).length;\n\n if (checkedCount === 0) return;\n\n const menu = document.getElementById('bulk-actions-menu');\n const isHidden = menu.classList.contains('hidden');\n\n if (isHidden) {\n menu.classList.remove('hidden');\n setTimeout(() => {\n menu.classList.remove('scale-95', 'opacity-0');\n menu.classList.add('scale-100', 'opacity-100');\n }, 10);\n } else {\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0');\n setTimeout(() => {\n menu.classList.add('hidden');\n }, 100);\n }\n }\n\n // Close dropdown when clicking outside\n document.addEventListener('click', function(e) {\n const dropdown = document.getElementById('bulk-actions-dropdown');\n const menu = document.getElementById('bulk-actions-menu');\n if (dropdown && menu && !dropdown.contains(e.target)) {\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0');\n setTimeout(() => {\n menu.classList.add('hidden');\n }, 100);\n }\n });\n\n // Store current bulk action context\n let currentBulkAction = null;\n let currentSelectedIds = [];\n\n // Perform bulk action\n function performBulkAction(action) {\n const selectedIds = Array.from(document.querySelectorAll('input[type=\"checkbox\"].row-checkbox:checked'))\n .map(cb => cb.value)\n .filter(id => id);\n\n if (selectedIds.length === 0) {\n alert('Please select at least one item');\n return;\n }\n\n // Store context for confirmation\n currentBulkAction = action;\n currentSelectedIds = selectedIds;\n\n // Update dialog content based on action\n updateDialogContent(action, selectedIds.length);\n\n // Show confirmation dialog\n showConfirmDialog('bulk-action-confirm');\n }\n\n // Update dialog content dynamically\n function updateDialogContent(action, count) {\n const dialog = document.getElementById('bulk-action-confirm');\n const titleEl = dialog.querySelector('h3');\n const messageEl = dialog.querySelector('p');\n const confirmBtn = dialog.querySelector('.confirm-button');\n\n let title, message, btnText, btnClass;\n\n switch(action) {\n case 'delete':\n title = 'Confirm Bulk Delete';\n message = 'Are you sure you want to delete ' + count + ' selected item' + (count > 1 ? 's' : '') + '? This action cannot be undone.';\n btnText = 'Delete';\n btnClass = 'bg-red-500 hover:bg-red-400';\n break;\n case 'publish':\n title = 'Confirm Bulk Publish';\n message = 'Are you sure you want to publish ' + count + ' selected item' + (count > 1 ? 's' : '') + '? They will become publicly visible.';\n btnText = 'Publish';\n btnClass = 'bg-green-500 hover:bg-green-400';\n break;\n case 'draft':\n title = 'Confirm Bulk Draft';\n message = 'Are you sure you want to move ' + count + ' selected item' + (count > 1 ? 's' : '') + ' to draft status? They will be unpublished.';\n btnText = 'Move to Draft';\n btnClass = 'bg-blue-500 hover:bg-blue-400';\n break;\n default:\n title = 'Confirm Bulk Action';\n message = 'Are you sure you want to perform this action on ' + count + ' selected item' + (count > 1 ? 's' : '') + '?';\n btnText = 'Confirm';\n btnClass = 'bg-blue-500 hover:bg-blue-400';\n }\n\n titleEl.textContent = title;\n messageEl.textContent = message;\n confirmBtn.textContent = btnText;\n confirmBtn.className = confirmBtn.className.replace(/bg-\\w+-\\d+\\s+hover:bg-\\w+-\\d+/, btnClass);\n }\n\n // Execute the bulk action after confirmation\n function executeBulkAction() {\n if (!currentBulkAction || currentSelectedIds.length === 0) return;\n\n // Close dropdown\n const menu = document.getElementById('bulk-actions-menu');\n menu.classList.add('hidden');\n\n fetch('/admin/content/bulk-action', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n action: currentBulkAction,\n ids: currentSelectedIds\n })\n })\n .then(res => res.json())\n .then(data => {\n if (data.success) {\n location.reload();\n } else {\n alert('Error: ' + (data.error || 'Unknown error'));\n }\n })\n .catch(err => {\n console.error('Bulk action error:', err);\n alert('Failed to perform bulk action');\n })\n .finally(() => {\n // Clear context\n currentBulkAction = null;\n currentSelectedIds = [];\n });\n }\n\n // Helper to get action text for display\n function getActionText(action) {\n const actionCount = currentSelectedIds.length;\n switch(action) {\n case 'publish':\n return \\`publish \\${actionCount} item\\${actionCount > 1 ? 's' : ''}\\`;\n case 'draft':\n return \\`move \\${actionCount} item\\${actionCount > 1 ? 's' : ''} to draft\\`;\n case 'delete':\n return \\`delete \\${actionCount} item\\${actionCount > 1 ? 's' : ''}\\`;\n default:\n return \\`perform action on \\${actionCount} item\\${actionCount > 1 ? 's' : ''}\\`;\n }\n }\n\n </script>\n\n <!-- Confirmation Dialog for Bulk Actions -->\n ${renderConfirmationDialog({\n id: 'bulk-action-confirm',\n title: 'Confirm Bulk Action',\n message: 'Are you sure you want to perform this action? This operation will affect multiple items.',\n confirmText: 'Confirm',\n cancelText: 'Cancel',\n confirmClass: 'bg-blue-500 hover:bg-blue-400',\n iconColor: 'blue',\n onConfirm: 'executeBulkAction()'\n })}\n\n <!-- Confirmation Dialog Script -->\n ${getConfirmationDialogScript()}\n `\n\n // Prepare layout data\n const layoutData: AdminLayoutCatalystData = {\n title: 'Content Management',\n pageTitle: 'Content Management',\n currentPath: '/admin/content',\n user: data.user,\n version: data.version,\n content: pageContent\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}","export interface ContentVersion {\n id: string\n version: number\n data: any\n author_id: string\n author_name?: string\n created_at: number\n is_current?: boolean\n}\n\nexport interface VersionHistoryData {\n contentId: string\n versions: ContentVersion[]\n currentVersion: number\n}\n\nexport function renderVersionHistory(data: VersionHistoryData): string {\n return `\n <div class=\"version-history-modal\">\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl w-full max-w-4xl max-h-[90vh] overflow-hidden\">\n <!-- Header -->\n <div class=\"relative px-6 py-4 border-b border-white/10\">\n <div class=\"absolute inset-0 bg-gradient-to-r from-blue-600/10 via-purple-600/10 to-pink-600/10\"></div>\n <div class=\"relative flex items-center justify-between\">\n <h3 class=\"text-lg font-semibold text-white\">Version History</h3>\n <button onclick=\"closeVersionHistory()\" class=\"text-gray-300 hover:text-white\">\n <svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n </div>\n </div>\n \n <!-- Versions List -->\n <div class=\"overflow-y-auto max-h-[calc(90vh-120px)]\">\n <div class=\"p-6 space-y-4\">\n ${data.versions.map((version, index) => `\n <div class=\"version-item backdrop-blur-sm bg-white/5 rounded-xl border border-white/10 p-4 ${version.is_current ? 'ring-2 ring-blue-500/50' : ''}\">\n <div class=\"flex items-center justify-between mb-3\">\n <div class=\"flex items-center space-x-3\">\n <span class=\"inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${version.is_current ? 'bg-blue-500/20 text-blue-300' : 'bg-white/10 text-gray-300'}\">\n Version ${version.version}${version.is_current ? ' (Current)' : ''}\n </span>\n <span class=\"text-sm text-gray-300\">\n ${new Date(version.created_at).toLocaleString()}\n </span>\n </div>\n <div class=\"flex items-center space-x-2\">\n ${!version.is_current ? `\n <button \n onclick=\"restoreVersion('${data.contentId}', ${version.version})\"\n class=\"inline-flex items-center px-3 py-1 bg-green-600 text-white text-sm rounded-xl hover:bg-green-700 transition-all\"\n >\n <svg class=\"w-4 h-4 mr-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6\"></path>\n </svg>\n Restore\n </button>\n ` : ''}\n <button \n onclick=\"previewVersion('${data.contentId}', ${version.version})\"\n class=\"inline-flex items-center px-3 py-1 bg-blue-600 text-white text-sm rounded-xl hover:bg-blue-700 transition-all\"\n >\n <svg class=\"w-4 h-4 mr-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"></path>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"></path>\n </svg>\n Preview\n </button>\n </div>\n </div>\n \n <!-- Version Summary -->\n <div class=\"version-summary text-sm\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <span class=\"text-gray-400\">Title:</span>\n <span class=\"text-white ml-2\">${escapeHtml(version.data?.title || 'Untitled')}</span>\n </div>\n <div>\n <span class=\"text-gray-400\">Author:</span>\n <span class=\"text-white ml-2\">${escapeHtml(version.author_name || 'Unknown')}</span>\n </div>\n ${version.data?.excerpt ? `\n <div class=\"md:col-span-2\">\n <span class=\"text-gray-400\">Excerpt:</span>\n <p class=\"text-white mt-1 text-xs\">${escapeHtml(version.data.excerpt.substring(0, 200))}${version.data.excerpt.length > 200 ? '...' : ''}</p>\n </div>\n ` : ''}\n </div>\n </div>\n \n <!-- Changes Summary (if not current) -->\n ${!version.is_current && index < data.versions.length - 1 ? `\n <div class=\"mt-3 pt-3 border-t border-white/10\">\n <button \n onclick=\"toggleChanges('changes-${version.version}')\"\n class=\"text-sm text-blue-400 hover:text-blue-300 transition-colors\"\n >\n <svg class=\"w-4 h-4 inline mr-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 9l4-4 4 4m0 6l-4 4-4-4\"></path>\n </svg>\n View Changes\n </button>\n <div id=\"changes-${version.version}\" class=\"hidden mt-2 text-xs text-gray-300\">\n <em>Change detection coming soon...</em>\n </div>\n </div>\n ` : ''}\n </div>\n `).join('')}\n </div>\n </div>\n \n <!-- Footer -->\n <div class=\"px-6 py-4 border-t border-white/10 bg-white/5\">\n <div class=\"flex justify-between items-center\">\n <span class=\"text-sm text-gray-400\">\n ${data.versions.length} version${data.versions.length !== 1 ? 's' : ''} total\n </span>\n <button \n onclick=\"closeVersionHistory()\"\n class=\"px-4 py-2 bg-white/10 text-white rounded-xl border border-white/20 hover:bg-white/20 transition-all\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n </div>\n \n <script>\n function closeVersionHistory() {\n document.querySelector('.version-history-modal').closest('.fixed').remove();\n }\n \n function restoreVersion(contentId, version) {\n if (confirm(\\`Are you sure you want to restore to version \\${version}? This will create a new version with the restored content.\\`)) {\n fetch(\\`/admin/content/\\${contentId}/restore/\\${version}\\`, {\n method: 'POST'\n })\n .then(response => response.json())\n .then(data => {\n if (data.success) {\n showNotification('Version restored successfully! Refreshing page...', 'success');\n setTimeout(() => {\n window.location.reload();\n }, 1500);\n } else {\n showNotification('Failed to restore version', 'error');\n }\n })\n .catch(error => {\n console.error('Error restoring version:', error);\n showNotification('Error restoring version', 'error');\n });\n }\n }\n \n function previewVersion(contentId, version) {\n const preview = window.open('', '_blank');\n preview.document.write('<p>Loading version preview...</p>');\n \n fetch(\\`/admin/content/\\${contentId}/version/\\${version}/preview\\`)\n .then(response => response.text())\n .then(html => {\n preview.document.open();\n preview.document.write(html);\n preview.document.close();\n })\n .catch(error => {\n preview.document.write('<p>Error loading preview</p>');\n });\n }\n \n function toggleChanges(elementId) {\n const element = document.getElementById(elementId);\n element.classList.toggle('hidden');\n }\n </script>\n `\n}\n\nfunction escapeHtml(text: string): string {\n if (typeof text !== 'string') return String(text || '')\n return text.replace(/[&<>\"']/g, (char) => ({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n }[char] || char))\n}","import { Hono } from 'hono'\nimport { html } from 'hono/html'\nimport type { D1Database, KVNamespace } from '@cloudflare/workers-types'\nimport { renderContentFormPage, ContentFormData } from '../templates/pages/admin-content-form.template'\nimport { renderContentListPage, ContentListPageData } from '../templates/pages/admin-content-list.template'\nimport { renderVersionHistory, VersionHistoryData, ContentVersion } from '../templates/components/version-history.template'\nimport { isPluginActive } from '../middleware/plugin-middleware'\nimport { getCacheService, CACHE_CONFIGS } from '../services/cache'\nimport type { Bindings, Variables } from '../app'\n\nconst adminContentRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Get collection fields\nasync function getCollectionFields(db: D1Database, collectionId: string) {\n const cache = getCacheService(CACHE_CONFIGS.collection!)\n\n return cache.getOrSet(\n cache.generateKey('fields', collectionId),\n async () => {\n const stmt = db.prepare(`\n SELECT * FROM content_fields\n WHERE collection_id = ?\n ORDER BY field_order ASC\n `)\n const { results } = await stmt.bind(collectionId).all()\n\n return (results || []).map((row: any) => ({\n id: row.id,\n field_name: row.field_name,\n field_type: row.field_type,\n field_label: row.field_label,\n field_options: row.field_options ? JSON.parse(row.field_options) : {},\n field_order: row.field_order,\n is_required: row.is_required === 1,\n is_searchable: row.is_searchable === 1\n }))\n }\n )\n}\n\n// Get collection by ID\nasync function getCollection(db: D1Database, collectionId: string) {\n const cache = getCacheService(CACHE_CONFIGS.collection!)\n\n return cache.getOrSet(\n cache.generateKey('collection', collectionId),\n async () => {\n const stmt = db.prepare('SELECT * FROM collections WHERE id = ? AND is_active = 1')\n const collection = await stmt.bind(collectionId).first() as any\n\n if (!collection) return null\n\n return {\n id: collection.id,\n name: collection.name,\n display_name: collection.display_name,\n description: collection.description,\n schema: collection.schema ? JSON.parse(collection.schema) : {}\n }\n }\n )\n}\n\n// Content list (main page)\nadminContentRoutes.get('/', async (c) => {\n try {\n const user = c.get('user')\n const url = new URL(c.req.url)\n const db = c.env.DB\n \n // Get query parameters\n const page = parseInt(url.searchParams.get('page') || '1')\n const limit = parseInt(url.searchParams.get('limit') || '20')\n const modelName = url.searchParams.get('model') || 'all'\n const status = url.searchParams.get('status') || 'all'\n const search = url.searchParams.get('search') || ''\n const offset = (page - 1) * limit\n \n // Get all collections for filter dropdown\n const collectionsStmt = db.prepare('SELECT id, name, display_name FROM collections WHERE is_active = 1 ORDER BY display_name')\n const { results: collectionsResults } = await collectionsStmt.all()\n const models = (collectionsResults || []).map((row: any) => ({\n name: row.name,\n displayName: row.display_name\n }))\n \n // Build where conditions\n const conditions: string[] = []\n const params: any[] = []\n\n // Always filter out deleted content unless specifically requested\n if (status !== 'deleted') {\n conditions.push(\"c.status != 'deleted'\")\n }\n\n if (search) {\n conditions.push('(c.title LIKE ? OR c.slug LIKE ?)')\n params.push(`%${search}%`, `%${search}%`)\n }\n\n if (modelName !== 'all') {\n conditions.push('col.name = ?')\n params.push(modelName)\n }\n\n if (status !== 'all' && status !== 'deleted') {\n conditions.push('c.status = ?')\n params.push(status)\n } else if (status === 'deleted') {\n conditions.push(\"c.status = 'deleted'\")\n }\n\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''\n \n // Get total count\n const countStmt = db.prepare(`\n SELECT COUNT(*) as count \n FROM content c\n JOIN collections col ON c.collection_id = col.id\n ${whereClause}\n `)\n const countResult = await countStmt.bind(...params).first() as any\n const totalItems = countResult?.count || 0\n \n // Get content items\n const contentStmt = db.prepare(`\n SELECT c.id, c.title, c.slug, c.status, c.created_at, c.updated_at,\n col.name as collection_name, col.display_name as collection_display_name,\n u.first_name, u.last_name, u.email as author_email\n FROM content c\n JOIN collections col ON c.collection_id = col.id\n LEFT JOIN users u ON c.author_id = u.id\n ${whereClause}\n ORDER BY c.updated_at DESC\n LIMIT ? OFFSET ?\n `)\n const { results } = await contentStmt.bind(...params, limit, offset).all()\n \n // Process content items\n const contentItems = (results || []).map((row: any) => {\n const statusConfig: Record<string, { class: string; text: string }> = {\n draft: {\n class: 'bg-zinc-50 dark:bg-zinc-500/10 text-zinc-700 dark:text-zinc-400 ring-1 ring-inset ring-zinc-600/20 dark:ring-zinc-500/20',\n text: 'Draft'\n },\n review: {\n class: 'bg-amber-50 dark:bg-amber-500/10 text-amber-700 dark:text-amber-400 ring-1 ring-inset ring-amber-600/20 dark:ring-amber-500/20',\n text: 'Under Review'\n },\n scheduled: {\n class: 'bg-blue-50 dark:bg-blue-500/10 text-blue-700 dark:text-blue-400 ring-1 ring-inset ring-blue-600/20 dark:ring-blue-500/20',\n text: 'Scheduled'\n },\n published: {\n class: 'bg-green-50 dark:bg-green-500/10 text-green-700 dark:text-green-400 ring-1 ring-inset ring-green-600/20 dark:ring-green-500/20',\n text: 'Published'\n },\n archived: {\n class: 'bg-purple-50 dark:bg-purple-500/10 text-purple-700 dark:text-purple-400 ring-1 ring-inset ring-purple-600/20 dark:ring-purple-500/20',\n text: 'Archived'\n },\n deleted: {\n class: 'bg-red-50 dark:bg-red-500/10 text-red-700 dark:text-red-400 ring-1 ring-inset ring-red-600/20 dark:ring-red-500/20',\n text: 'Deleted'\n }\n }\n\n const config = statusConfig[row.status as keyof typeof statusConfig] || statusConfig.draft\n const statusBadge = `\n <span class=\"inline-flex items-center rounded-md px-2 py-1 text-xs font-medium ${config?.class || ''}\">\n ${config?.text || row.status}\n </span>\n `\n \n const authorName = row.first_name && row.last_name \n ? `${row.first_name} ${row.last_name}`\n : row.author_email || 'Unknown'\n \n const formattedDate = new Date(row.updated_at).toLocaleDateString()\n \n // Determine available workflow actions based on status\n const availableActions: string[] = []\n switch (row.status) {\n case 'draft':\n availableActions.push('submit_for_review', 'publish')\n break\n case 'review':\n availableActions.push('approve', 'request_changes')\n break\n case 'published':\n availableActions.push('unpublish', 'archive')\n break\n case 'scheduled':\n availableActions.push('unschedule')\n break\n }\n \n return {\n id: row.id,\n title: row.title,\n slug: row.slug,\n modelName: row.collection_display_name,\n statusBadge,\n authorName,\n formattedDate,\n availableActions\n }\n })\n \n const pageData: ContentListPageData = {\n modelName,\n status,\n page,\n search,\n models,\n contentItems,\n totalItems,\n itemsPerPage: limit,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n version: c.get('appVersion')\n }\n\n return c.html(renderContentListPage(pageData))\n } catch (error) {\n console.error('Error fetching content list:', error)\n return c.html(`<p>Error loading content: ${error}</p>`)\n }\n})\n\n// New content form\nadminContentRoutes.get('/new', async (c) => {\n try {\n const user = c.get('user')\n const url = new URL(c.req.url)\n const collectionId = url.searchParams.get('collection')\n \n if (!collectionId) {\n // Show collection selection page\n const db = c.env.DB\n const collectionsStmt = db.prepare('SELECT id, name, display_name, description FROM collections WHERE is_active = 1 ORDER BY display_name')\n const { results } = await collectionsStmt.all()\n \n const collections = (results || []).map((row: any) => ({\n id: row.id,\n name: row.name,\n display_name: row.display_name,\n description: row.description\n }))\n \n // Render collection selection page\n const selectionHTML = `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Select Collection - SonicJS AI Admin</title>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n </head>\n <body class=\"bg-gray-900 text-white\">\n <div class=\"min-h-screen flex items-center justify-center\">\n <div class=\"max-w-2xl w-full mx-auto p-8\">\n <h1 class=\"text-3xl font-bold mb-8 text-center\">Create New Content</h1>\n <p class=\"text-gray-300 text-center mb-8\">Select a collection to create content in:</p>\n \n <div class=\"grid gap-4\">\n ${collections.map(collection => `\n <a href=\"/admin/content/new?collection=${collection.id}\" \n class=\"block p-6 bg-gray-800 rounded-lg hover:bg-gray-700 transition-colors border border-gray-700\">\n <h3 class=\"text-xl font-semibold mb-2\">${collection.display_name}</h3>\n <p class=\"text-gray-400\">${collection.description || 'No description'}</p>\n </a>\n `).join('')}\n </div>\n \n <div class=\"mt-8 text-center\">\n <a href=\"/admin/content\" class=\"text-blue-400 hover:text-blue-300\">← Back to Content List</a>\n </div>\n </div>\n </div>\n </body>\n </html>\n `\n \n return c.html(selectionHTML)\n }\n \n const db = c.env.DB\n const collection = await getCollection(db, collectionId)\n \n if (!collection) {\n const formData: ContentFormData = {\n collection: { id: '', name: '', display_name: 'Unknown', schema: {} },\n fields: [],\n error: 'Collection not found.',\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n return c.html(renderContentFormPage(formData))\n }\n \n const fields = await getCollectionFields(db, collectionId)\n \n // Check if workflow plugin is active\n const workflowEnabled = await isPluginActive(db, 'workflow')\n \n const formData: ContentFormData = {\n collection,\n fields,\n isEdit: false,\n workflowEnabled,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n \n return c.html(renderContentFormPage(formData))\n } catch (error) {\n console.error('Error loading new content form:', error)\n const formData: ContentFormData = {\n collection: { id: '', name: '', display_name: 'Unknown', schema: {} },\n fields: [],\n error: 'Failed to load content form.',\n user: c.get('user') ? {\n name: c.get('user')!.email,\n email: c.get('user')!.email,\n role: c.get('user')!.role\n } : undefined\n }\n return c.html(renderContentFormPage(formData))\n }\n})\n\n// Edit content form\nadminContentRoutes.get('/:id/edit', async (c) => {\n try {\n const id = c.req.param('id')\n const user = c.get('user')\n const db = c.env.DB\n const url = new URL(c.req.url)\n\n // Capture referrer parameters to preserve filters when returning to list\n const referrerParams = url.searchParams.get('ref') || ''\n\n // Get content with caching\n const cache = getCacheService(CACHE_CONFIGS.content!)\n const content = await cache.getOrSet(\n cache.generateKey('content', id),\n async () => {\n const contentStmt = db.prepare(`\n SELECT c.*, col.id as collection_id, col.name as collection_name,\n col.display_name as collection_display_name, col.description as collection_description,\n col.schema as collection_schema\n FROM content c\n JOIN collections col ON c.collection_id = col.id\n WHERE c.id = ?\n `)\n return await contentStmt.bind(id).first() as any\n }\n )\n\n if (!content) {\n const formData: ContentFormData = {\n collection: { id: '', name: '', display_name: 'Unknown', schema: {} },\n fields: [],\n error: 'Content not found.',\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n return c.html(renderContentFormPage(formData))\n }\n \n const collection = {\n id: content.collection_id,\n name: content.collection_name,\n display_name: content.collection_display_name,\n description: content.collection_description,\n schema: content.collection_schema ? JSON.parse(content.collection_schema) : {}\n }\n \n const fields = await getCollectionFields(db, content.collection_id)\n const contentData = content.data ? JSON.parse(content.data) : {}\n\n // Check if workflow plugin is active\n const workflowEnabled = await isPluginActive(db, 'workflow')\n\n const formData: ContentFormData = {\n id: content.id,\n title: content.title,\n slug: content.slug,\n data: contentData,\n status: content.status,\n scheduled_publish_at: content.scheduled_publish_at,\n scheduled_unpublish_at: content.scheduled_unpublish_at,\n review_status: content.review_status,\n meta_title: content.meta_title,\n meta_description: content.meta_description,\n collection,\n fields,\n isEdit: true,\n workflowEnabled,\n referrerParams,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n version: c.get('appVersion')\n }\n\n return c.html(renderContentFormPage(formData))\n } catch (error) {\n console.error('Error loading edit content form:', error)\n const formData: ContentFormData = {\n collection: { id: '', name: '', display_name: 'Unknown', schema: {} },\n fields: [],\n error: 'Failed to load content for editing.',\n user: c.get('user') ? {\n name: c.get('user')!.email,\n email: c.get('user')!.email,\n role: c.get('user')!.role\n } : undefined\n }\n return c.html(renderContentFormPage(formData))\n }\n})\n\n// Create content\nadminContentRoutes.post('/', async (c) => {\n try {\n const user = c.get('user')\n const formData = await c.req.formData()\n const collectionId = formData.get('collection_id') as string\n const action = formData.get('action') as string\n \n if (!collectionId) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Collection ID is required.\n </div>\n `)\n }\n \n const db = c.env.DB\n const collection = await getCollection(db, collectionId)\n \n if (!collection) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Collection not found.\n </div>\n `)\n }\n \n const fields = await getCollectionFields(db, collectionId)\n \n // Extract field data\n const data: any = {}\n const errors: Record<string, string[]> = {}\n \n for (const field of fields) {\n const value = formData.get(field.field_name)\n\n // Auto-generate GUID for guid field types\n if (field.field_type === 'guid') {\n const options = field.field_options || {}\n if (options.autoGenerate) {\n data[field.field_name] = crypto.randomUUID()\n continue\n }\n }\n\n // Validation\n if (field.is_required && (!value || value.toString().trim() === '')) {\n errors[field.field_name] = [`${field.field_label} is required`]\n continue\n }\n\n // Type conversion and validation\n switch (field.field_type) {\n case 'number':\n if (value && isNaN(Number(value))) {\n errors[field.field_name] = [`${field.field_label} must be a valid number`]\n } else {\n data[field.field_name] = value ? Number(value) : null\n }\n break\n case 'boolean':\n data[field.field_name] = formData.get(`${field.field_name}_submitted`) ? (value === 'true') : false\n break\n case 'select':\n if (field.field_options?.multiple) {\n data[field.field_name] = formData.getAll(`${field.field_name}[]`)\n } else {\n data[field.field_name] = value\n }\n break\n case 'guid':\n // If guid field is not auto-generated, use provided value\n data[field.field_name] = value || null\n break\n default:\n data[field.field_name] = value\n }\n }\n \n // Check for validation errors\n if (Object.keys(errors).length > 0) {\n const formDataWithErrors: ContentFormData = {\n collection,\n fields,\n data,\n validationErrors: errors,\n error: 'Please fix the validation errors below.',\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n return c.html(renderContentFormPage(formDataWithErrors))\n }\n \n // Generate slug if not provided\n let slug = data.slug || data.title\n if (slug) {\n slug = slug.toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .trim('-')\n }\n \n // Determine status\n let status = formData.get('status') as string || 'draft'\n if (action === 'save_and_publish') {\n status = 'published'\n }\n \n // Handle scheduling\n const scheduledPublishAt = formData.get('scheduled_publish_at') as string\n const scheduledUnpublishAt = formData.get('scheduled_unpublish_at') as string\n \n // Create content\n const contentId = crypto.randomUUID()\n const now = Date.now()\n \n const insertStmt = db.prepare(`\n INSERT INTO content (\n id, collection_id, slug, title, data, status, \n scheduled_publish_at, scheduled_unpublish_at,\n meta_title, meta_description, author_id, created_at, updated_at\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n \n await insertStmt.bind(\n contentId,\n collectionId,\n slug,\n data.title || 'Untitled',\n JSON.stringify(data),\n status,\n scheduledPublishAt ? new Date(scheduledPublishAt).getTime() : null,\n scheduledUnpublishAt ? new Date(scheduledUnpublishAt).getTime() : null,\n data.meta_title || null,\n data.meta_description || null,\n user?.userId || 'unknown',\n now,\n now\n ).run()\n\n // Invalidate collection content list cache\n const cache = getCacheService(CACHE_CONFIGS.content!)\n await cache.invalidate(`content:list:${collectionId}:*`)\n\n // Create initial version\n const versionStmt = db.prepare(`\n INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `)\n \n await versionStmt.bind(\n crypto.randomUUID(),\n contentId,\n 1,\n JSON.stringify(data),\n user?.userId || 'unknown',\n now\n ).run()\n \n // Log workflow action\n const workflowStmt = db.prepare(`\n INSERT INTO workflow_history (id, content_id, action, from_status, to_status, user_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `)\n \n await workflowStmt.bind(\n crypto.randomUUID(),\n contentId,\n 'created',\n 'none',\n status,\n user?.userId || 'unknown',\n now\n ).run()\n \n // Handle different actions\n const referrerParams = formData.get('referrer_params') as string\n const redirectUrl = action === 'save_and_continue'\n ? `/admin/content/${contentId}/edit?success=Content saved successfully!${referrerParams ? `&ref=${encodeURIComponent(referrerParams)}` : ''}`\n : referrerParams\n ? `/admin/content?${referrerParams}&success=Content created successfully!`\n : `/admin/content?collection=${collectionId}&success=Content created successfully!`\n\n // Check if this is an HTMX request\n const isHTMX = c.req.header('HX-Request') === 'true'\n \n if (isHTMX) {\n // For HTMX requests, use HX-Redirect header to trigger client-side redirect\n return c.text('', 200, {\n 'HX-Redirect': redirectUrl\n })\n } else {\n // For regular requests, use server-side redirect\n return c.redirect(redirectUrl)\n }\n \n } catch (error) {\n console.error('Error creating content:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Failed to create content. Please try again.\n </div>\n `)\n }\n})\n\n// Update content\nadminContentRoutes.put('/:id', async (c) => {\n try {\n const id = c.req.param('id')\n const user = c.get('user')\n const formData = await c.req.formData()\n const action = formData.get('action') as string\n \n const db = c.env.DB\n \n // Get existing content\n const contentStmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const existingContent = await contentStmt.bind(id).first() as any\n \n if (!existingContent) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Content not found.\n </div>\n `)\n }\n \n const collection = await getCollection(db, existingContent.collection_id)\n if (!collection) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Collection not found.\n </div>\n `)\n }\n \n const fields = await getCollectionFields(db, existingContent.collection_id)\n \n // Extract and validate field data (same as create)\n const data: any = {}\n const errors: Record<string, string[]> = {}\n \n for (const field of fields) {\n const value = formData.get(field.field_name)\n \n if (field.is_required && (!value || value.toString().trim() === '')) {\n errors[field.field_name] = [`${field.field_label} is required`]\n continue\n }\n \n switch (field.field_type) {\n case 'number':\n if (value && isNaN(Number(value))) {\n errors[field.field_name] = [`${field.field_label} must be a valid number`]\n } else {\n data[field.field_name] = value ? Number(value) : null\n }\n break\n case 'boolean':\n data[field.field_name] = formData.get(`${field.field_name}_submitted`) ? (value === 'true') : false\n break\n case 'select':\n if (field.field_options?.multiple) {\n data[field.field_name] = formData.getAll(`${field.field_name}[]`)\n } else {\n data[field.field_name] = value\n }\n break\n default:\n data[field.field_name] = value\n }\n }\n \n if (Object.keys(errors).length > 0) {\n const formDataWithErrors: ContentFormData = {\n id,\n collection,\n fields,\n data,\n validationErrors: errors,\n error: 'Please fix the validation errors below.',\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n return c.html(renderContentFormPage(formDataWithErrors))\n }\n \n // Update slug if title changed\n let slug = data.slug || data.title\n if (slug) {\n slug = slug.toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .trim('-')\n }\n \n // Determine status\n let status = formData.get('status') as string || existingContent.status\n if (action === 'save_and_publish') {\n status = 'published'\n }\n \n // Handle scheduling\n const scheduledPublishAt = formData.get('scheduled_publish_at') as string\n const scheduledUnpublishAt = formData.get('scheduled_unpublish_at') as string\n \n // Update content\n const now = Date.now()\n \n const updateStmt = db.prepare(`\n UPDATE content SET\n slug = ?, title = ?, data = ?, status = ?,\n scheduled_publish_at = ?, scheduled_unpublish_at = ?,\n meta_title = ?, meta_description = ?, updated_at = ?\n WHERE id = ?\n `)\n \n await updateStmt.bind(\n slug,\n data.title || 'Untitled',\n JSON.stringify(data),\n status,\n scheduledPublishAt ? new Date(scheduledPublishAt).getTime() : null,\n scheduledUnpublishAt ? new Date(scheduledUnpublishAt).getTime() : null,\n data.meta_title || null,\n data.meta_description || null,\n now,\n id\n ).run()\n\n // Invalidate content cache\n const cache = getCacheService(CACHE_CONFIGS.content!)\n await cache.delete(cache.generateKey('content', id))\n await cache.invalidate(`content:list:${existingContent.collection_id}:*`)\n\n // Create new version if content changed\n const existingData = JSON.parse(existingContent.data || '{}')\n if (JSON.stringify(existingData) !== JSON.stringify(data)) {\n // Get next version number\n const versionCountStmt = db.prepare('SELECT MAX(version) as max_version FROM content_versions WHERE content_id = ?')\n const versionResult = await versionCountStmt.bind(id).first() as any\n const nextVersion = (versionResult?.max_version || 0) + 1\n \n const versionStmt = db.prepare(`\n INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `)\n \n await versionStmt.bind(\n crypto.randomUUID(),\n id,\n nextVersion,\n JSON.stringify(data),\n user?.userId || 'unknown',\n now\n ).run()\n }\n \n // Log workflow action if status changed\n if (status !== existingContent.status) {\n const workflowStmt = db.prepare(`\n INSERT INTO workflow_history (id, content_id, action, from_status, to_status, user_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `)\n \n await workflowStmt.bind(\n crypto.randomUUID(),\n id,\n 'status_changed',\n existingContent.status,\n status,\n user?.userId || 'unknown',\n now\n ).run()\n }\n \n // Handle different actions\n const referrerParams = formData.get('referrer_params') as string\n const redirectUrl = action === 'save_and_continue'\n ? `/admin/content/${id}/edit?success=Content updated successfully!${referrerParams ? `&ref=${encodeURIComponent(referrerParams)}` : ''}`\n : referrerParams\n ? `/admin/content?${referrerParams}&success=Content updated successfully!`\n : `/admin/content?collection=${existingContent.collection_id}&success=Content updated successfully!`\n\n // Check if this is an HTMX request\n const isHTMX = c.req.header('HX-Request') === 'true'\n \n if (isHTMX) {\n // For HTMX requests, use HX-Redirect header to trigger client-side redirect\n return c.text('', 200, {\n 'HX-Redirect': redirectUrl\n })\n } else {\n // For regular requests, use server-side redirect\n return c.redirect(redirectUrl)\n }\n \n } catch (error) {\n console.error('Error updating content:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Failed to update content. Please try again.\n </div>\n `)\n }\n})\n\n// Content preview\nadminContentRoutes.post('/preview', async (c) => {\n try {\n const formData = await c.req.formData()\n const collectionId = formData.get('collection_id') as string\n \n const db = c.env.DB\n const collection = await getCollection(db, collectionId)\n \n if (!collection) {\n return c.html('<p>Collection not found</p>')\n }\n \n const fields = await getCollectionFields(db, collectionId)\n \n // Extract field data for preview\n const data: any = {}\n for (const field of fields) {\n const value = formData.get(field.field_name)\n \n switch (field.field_type) {\n case 'number':\n data[field.field_name] = value ? Number(value) : null\n break\n case 'boolean':\n data[field.field_name] = value === 'true'\n break\n case 'select':\n if (field.field_options?.multiple) {\n data[field.field_name] = formData.getAll(`${field.field_name}[]`)\n } else {\n data[field.field_name] = value\n }\n break\n default:\n data[field.field_name] = value\n }\n }\n \n // Generate preview HTML\n const previewHTML = `\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Preview: ${data.title || 'Untitled'}</title>\n <style>\n body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }\n h1 { color: #333; }\n .meta { color: #666; font-size: 14px; margin-bottom: 20px; }\n .content { line-height: 1.6; }\n </style>\n </head>\n <body>\n <h1>${data.title || 'Untitled'}</h1>\n <div class=\"meta\">\n <strong>Collection:</strong> ${collection.display_name}<br>\n <strong>Status:</strong> ${formData.get('status') || 'draft'}<br>\n ${data.meta_description ? `<strong>Description:</strong> ${data.meta_description}<br>` : ''}\n </div>\n <div class=\"content\">\n ${data.content || '<p>No content provided.</p>'}\n </div>\n \n <h3>All Fields:</h3>\n <table border=\"1\" style=\"border-collapse: collapse; width: 100%;\">\n <tr><th>Field</th><th>Value</th></tr>\n ${fields.map(field => `\n <tr>\n <td><strong>${field.field_label}</strong></td>\n <td>${data[field.field_name] || '<em>empty</em>'}</td>\n </tr>\n `).join('')}\n </table>\n </body>\n </html>\n `\n \n return c.html(previewHTML)\n } catch (error) {\n console.error('Error generating preview:', error)\n return c.html('<p>Error generating preview</p>')\n }\n})\n\n// Duplicate content\nadminContentRoutes.post('/duplicate', async (c) => {\n try {\n const user = c.get('user')\n const formData = await c.req.formData()\n const originalId = formData.get('id') as string\n \n if (!originalId) {\n return c.json({ success: false, error: 'Content ID required' })\n }\n \n const db = c.env.DB\n \n // Get original content\n const contentStmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const original = await contentStmt.bind(originalId).first() as any\n \n if (!original) {\n return c.json({ success: false, error: 'Content not found' })\n }\n \n // Create duplicate\n const newId = crypto.randomUUID()\n const now = Date.now()\n const originalData = JSON.parse(original.data || '{}')\n \n // Modify title to indicate it's a copy\n originalData.title = `${originalData.title || 'Untitled'} (Copy)`\n \n const insertStmt = db.prepare(`\n INSERT INTO content (\n id, collection_id, slug, title, data, status, \n author_id, created_at, updated_at\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n \n await insertStmt.bind(\n newId,\n original.collection_id,\n `${original.slug}-copy-${Date.now()}`,\n originalData.title,\n JSON.stringify(originalData),\n 'draft', // Always start as draft\n user?.userId || 'unknown',\n now,\n now\n ).run()\n \n return c.json({ success: true, id: newId })\n } catch (error) {\n console.error('Error duplicating content:', error)\n return c.json({ success: false, error: 'Failed to duplicate content' })\n }\n})\n\n// Get bulk actions modal\nadminContentRoutes.get('/bulk-actions', async (c) => {\n const bulkActionsModal = `\n <div class=\"fixed inset-0 bg-zinc-950/50 dark:bg-zinc-950/80 backdrop-blur-sm z-50 flex items-center justify-center p-4\" onclick=\"this.remove()\">\n <div class=\"bg-white dark:bg-zinc-900 rounded-xl shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 max-w-md w-full\" onclick=\"event.stopPropagation()\">\n <div class=\"flex items-center justify-between mb-4\">\n <h3 class=\"text-lg font-semibold text-zinc-950 dark:text-white\">Bulk Actions</h3>\n <button onclick=\"this.closest('.fixed').remove()\" class=\"text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200\">\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n <p class=\"text-sm text-zinc-600 dark:text-zinc-400 mb-4\">\n Select items from the table below to perform bulk actions.\n </p>\n <div class=\"space-y-2\">\n <button\n onclick=\"performBulkAction('publish')\"\n class=\"w-full inline-flex items-center justify-center gap-x-2 px-4 py-2.5 bg-lime-600 dark:bg-lime-500 text-white rounded-lg hover:bg-lime-700 dark:hover:bg-lime-600 transition-colors\"\n >\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"/>\n </svg>\n Publish Selected\n </button>\n <button\n onclick=\"performBulkAction('draft')\"\n class=\"w-full inline-flex items-center justify-center gap-x-2 px-4 py-2.5 bg-zinc-600 dark:bg-zinc-700 text-white rounded-lg hover:bg-zinc-700 dark:hover:bg-zinc-800 transition-colors\"\n >\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z\"/>\n </svg>\n Move to Draft\n </button>\n <button\n onclick=\"performBulkAction('delete')\"\n class=\"w-full inline-flex items-center justify-center gap-x-2 px-4 py-2.5 bg-red-600 dark:bg-red-500 text-white rounded-lg hover:bg-red-700 dark:hover:bg-red-600 transition-colors\"\n >\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"/>\n </svg>\n Delete Selected\n </button>\n </div>\n </div>\n </div>\n <script>\n function performBulkAction(action) {\n const selectedIds = Array.from(document.querySelectorAll('input[type=\"checkbox\"].row-checkbox:checked'))\n .map(cb => cb.value)\n .filter(id => id)\n\n if (selectedIds.length === 0) {\n alert('Please select at least one item')\n return\n }\n\n const actionText = action === 'publish' ? 'publish' : action === 'draft' ? 'move to draft' : 'delete'\n const confirmed = confirm(\\`Are you sure you want to \\${actionText} \\${selectedIds.length} item(s)?\\`)\n\n if (!confirmed) return\n\n fetch('/admin/content/bulk-action', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n action: action,\n ids: selectedIds\n })\n })\n .then(res => res.json())\n .then(data => {\n if (data.success) {\n document.querySelector('#bulk-actions-modal .fixed').remove()\n location.reload()\n } else {\n alert('Error: ' + (data.error || 'Unknown error'))\n }\n })\n .catch(err => {\n console.error('Bulk action error:', err)\n alert('Failed to perform bulk action')\n })\n }\n </script>\n `\n\n return c.html(bulkActionsModal)\n})\n\n// Perform bulk action\nadminContentRoutes.post('/bulk-action', async (c) => {\n try {\n const user = c.get('user')\n const body = await c.req.json()\n const { action, ids } = body\n\n if (!action || !ids || ids.length === 0) {\n return c.json({ success: false, error: 'Action and IDs required' })\n }\n\n const db = c.env.DB\n const now = Date.now()\n\n if (action === 'delete') {\n // Soft delete by setting status to 'deleted'\n const placeholders = ids.map(() => '?').join(',')\n const stmt = db.prepare(`\n UPDATE content\n SET status = 'deleted', updated_at = ?\n WHERE id IN (${placeholders})\n `)\n await stmt.bind(now, ...ids).run()\n } else if (action === 'publish' || action === 'draft') {\n // Update status\n const placeholders = ids.map(() => '?').join(',')\n const publishedAt = action === 'publish' ? now : null\n const stmt = db.prepare(`\n UPDATE content\n SET status = ?, published_at = ?, updated_at = ?\n WHERE id IN (${placeholders})\n `)\n await stmt.bind(action, publishedAt, now, ...ids).run()\n } else {\n return c.json({ success: false, error: 'Invalid action' })\n }\n\n // Invalidate cache for all affected content items\n const cache = getCacheService(CACHE_CONFIGS.content!)\n for (const contentId of ids) {\n await cache.delete(cache.generateKey('content', contentId))\n }\n // Also invalidate list caches (they contain content from potentially multiple collections)\n await cache.invalidate('content:list:*')\n\n return c.json({ success: true, count: ids.length })\n } catch (error) {\n console.error('Bulk action error:', error)\n return c.json({ success: false, error: 'Failed to perform bulk action' })\n }\n})\n\n// Delete content\nadminContentRoutes.delete('/:id', async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n const user = c.get('user')\n\n // Check if content exists\n const contentStmt = db.prepare('SELECT id, title FROM content WHERE id = ?')\n const content = await contentStmt.bind(id).first() as any\n\n if (!content) {\n return c.json({ success: false, error: 'Content not found' }, 404)\n }\n\n // Soft delete by setting status to 'deleted'\n const now = Date.now()\n const deleteStmt = db.prepare(`\n UPDATE content\n SET status = 'deleted', updated_at = ?\n WHERE id = ?\n `)\n await deleteStmt.bind(now, id).run()\n\n // Invalidate cache\n const cache = getCacheService(CACHE_CONFIGS.content!)\n await cache.delete(cache.generateKey('content', id))\n await cache.invalidate('content:list:*')\n\n // Return success - let HTMX reload the page\n return c.html(`\n <div id=\"content-list\" hx-get=\"/admin/content?model=${c.req.query('model') || 'post'}\" hx-trigger=\"load\" hx-swap=\"outerHTML\">\n <div class=\"flex items-center justify-center p-8\">\n <div class=\"text-center\">\n <svg class=\"mx-auto h-12 w-12 text-lime-500 dark:text-lime-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"/>\n </svg>\n <p class=\"mt-2 text-sm text-zinc-600 dark:text-zinc-400\">Content deleted successfully. Refreshing...</p>\n </div>\n </div>\n </div>\n `)\n } catch (error) {\n console.error('Delete content error:', error)\n return c.json({ success: false, error: 'Failed to delete content' }, 500)\n }\n})\n\n// Get version history\nadminContentRoutes.get('/:id/versions', async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n \n // Get current content\n const contentStmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const content = await contentStmt.bind(id).first() as any\n \n if (!content) {\n return c.html('<p>Content not found</p>')\n }\n \n // Get all versions with author info\n const versionsStmt = db.prepare(`\n SELECT cv.*, u.first_name, u.last_name, u.email\n FROM content_versions cv\n LEFT JOIN users u ON cv.author_id = u.id\n WHERE cv.content_id = ?\n ORDER BY cv.version DESC\n `)\n const { results } = await versionsStmt.bind(id).all()\n \n const versions: ContentVersion[] = (results || []).map((row: any) => ({\n id: row.id,\n version: row.version,\n data: JSON.parse(row.data || '{}'),\n author_id: row.author_id,\n author_name: row.first_name && row.last_name ? `${row.first_name} ${row.last_name}` : row.email,\n created_at: row.created_at,\n is_current: false // Will be set below\n }))\n \n // Mark the latest version as current\n if (versions.length > 0) {\n versions[0]!.is_current = true\n }\n \n const data: VersionHistoryData = {\n contentId: id,\n versions,\n currentVersion: versions.length > 0 ? versions[0]!.version : 1\n }\n \n return c.html(renderVersionHistory(data))\n } catch (error) {\n console.error('Error loading version history:', error)\n return c.html('<p>Error loading version history</p>')\n }\n})\n\n// Restore version\nadminContentRoutes.post('/:id/restore/:version', async (c) => {\n try {\n const id = c.req.param('id')\n const version = parseInt(c.req.param('version'))\n const user = c.get('user')\n const db = c.env.DB\n \n // Get the specific version\n const versionStmt = db.prepare(`\n SELECT * FROM content_versions \n WHERE content_id = ? AND version = ?\n `)\n const versionData = await versionStmt.bind(id, version).first() as any\n \n if (!versionData) {\n return c.json({ success: false, error: 'Version not found' })\n }\n \n // Get current content\n const contentStmt = db.prepare('SELECT * FROM content WHERE id = ?')\n const currentContent = await contentStmt.bind(id).first() as any\n \n if (!currentContent) {\n return c.json({ success: false, error: 'Content not found' })\n }\n \n const restoredData = JSON.parse(versionData.data)\n const now = Date.now()\n \n // Update content with restored data\n const updateStmt = db.prepare(`\n UPDATE content SET\n title = ?, data = ?, updated_at = ?\n WHERE id = ?\n `)\n \n await updateStmt.bind(\n restoredData.title || 'Untitled',\n versionData.data,\n now,\n id\n ).run()\n \n // Create new version for the restoration\n const nextVersionStmt = db.prepare('SELECT MAX(version) as max_version FROM content_versions WHERE content_id = ?')\n const nextVersionResult = await nextVersionStmt.bind(id).first() as any\n const nextVersion = (nextVersionResult?.max_version || 0) + 1\n \n const newVersionStmt = db.prepare(`\n INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `)\n \n await newVersionStmt.bind(\n crypto.randomUUID(),\n id,\n nextVersion,\n versionData.data,\n user?.userId || 'unknown',\n now\n ).run()\n \n // Log workflow action\n const workflowStmt = db.prepare(`\n INSERT INTO workflow_history (id, content_id, action, from_status, to_status, user_id, comment, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `)\n \n await workflowStmt.bind(\n crypto.randomUUID(),\n id,\n 'version_restored',\n currentContent.status,\n currentContent.status,\n user?.userId || 'unknown',\n `Restored to version ${version}`,\n now\n ).run()\n \n return c.json({ success: true })\n } catch (error) {\n console.error('Error restoring version:', error)\n return c.json({ success: false, error: 'Failed to restore version' })\n }\n})\n\n// Preview specific version\nadminContentRoutes.get('/:id/version/:version/preview', async (c) => {\n try {\n const id = c.req.param('id')\n const version = parseInt(c.req.param('version'))\n const db = c.env.DB\n \n // Get the specific version\n const versionStmt = db.prepare(`\n SELECT cv.*, c.collection_id, col.display_name as collection_name\n FROM content_versions cv\n JOIN content c ON cv.content_id = c.id\n JOIN collections col ON c.collection_id = col.id\n WHERE cv.content_id = ? AND cv.version = ?\n `)\n const versionData = await versionStmt.bind(id, version).first() as any\n \n if (!versionData) {\n return c.html('<p>Version not found</p>')\n }\n \n const data = JSON.parse(versionData.data || '{}')\n \n // Generate preview HTML\n const previewHTML = `\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Version ${version} Preview: ${data.title || 'Untitled'}</title>\n <style>\n body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }\n h1 { color: #333; }\n .meta { color: #666; font-size: 14px; margin-bottom: 20px; padding: 10px; background: #f5f5f5; border-radius: 5px; }\n .content { line-height: 1.6; }\n .version-badge { background: #007cba; color: white; padding: 5px 10px; border-radius: 15px; font-size: 12px; }\n </style>\n </head>\n <body>\n <div class=\"meta\">\n <span class=\"version-badge\">Version ${version}</span>\n <strong>Collection:</strong> ${versionData.collection_name}<br>\n <strong>Created:</strong> ${new Date(versionData.created_at).toLocaleString()}<br>\n <em>This is a historical version preview</em>\n </div>\n \n <h1>${data.title || 'Untitled'}</h1>\n \n <div class=\"content\">\n ${data.content || '<p>No content provided.</p>'}\n </div>\n \n ${data.excerpt ? `<h3>Excerpt:</h3><p>${data.excerpt}</p>` : ''}\n \n <h3>All Field Data:</h3>\n <pre style=\"background: #f5f5f5; padding: 15px; border-radius: 5px; overflow-x: auto;\">\n${JSON.stringify(data, null, 2)}\n </pre>\n </body>\n </html>\n `\n \n return c.html(previewHTML)\n } catch (error) {\n console.error('Error generating version preview:', error)\n return c.html('<p>Error generating preview</p>')\n }\n})\nexport default adminContentRoutes\n","import { renderAdminLayout, AdminLayoutData } from '../layouts/admin-layout-v2.template'\nimport { renderAlert } from '../alert.template'\n\nexport interface UserProfile {\n id: string\n email: string\n username: string\n first_name: string\n last_name: string\n phone?: string\n bio?: string\n avatar_url?: string\n timezone: string\n language: string\n theme: string\n email_notifications: boolean\n two_factor_enabled: boolean\n role: string\n created_at: number\n last_login_at?: number\n}\n\nexport interface ProfilePageData {\n profile: UserProfile\n timezones: Array<{ value: string; label: string }>\n languages: Array<{ value: string; label: string }>\n error?: string\n success?: string\n user?: {\n name: string\n email: string\n role: string\n }\n}\n\nexport function renderProfilePage(data: ProfilePageData): string {\n const pageContent = `\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl font-semibold text-white\">User Profile</h1>\n <p class=\"mt-2 text-sm text-gray-300\">Manage your account settings and preferences</p>\n </div>\n </div>\n\n <!-- Breadcrumb -->\n <nav class=\"flex mb-6\" aria-label=\"Breadcrumb\">\n <ol class=\"flex items-center space-x-3\">\n <li>\n <a href=\"/admin\" class=\"text-gray-300 hover:text-white transition-colors\">\n <svg class=\"h-5 w-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z\"/>\n </svg>\n </a>\n </li>\n <li class=\"flex items-center\">\n <svg class=\"h-5 w-5 text-gray-400 mx-2\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\"/>\n </svg>\n <span class=\"text-sm font-medium text-gray-200\">Profile</span>\n </li>\n </ol>\n </nav>\n\n <!-- Alert Messages -->\n ${data.error ? renderAlert({ type: 'error', message: data.error, dismissible: true }) : ''}\n ${data.success ? renderAlert({ type: 'success', message: data.success, dismissible: true }) : ''}\n\n <!-- Profile Form -->\n <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <!-- Main Profile Form -->\n <div class=\"lg:col-span-2\">\n <div class=\"backdrop-blur-xl bg-white/10 rounded-3xl border border-white/20 shadow-2xl overflow-hidden\">\n <!-- Form Header -->\n <div class=\"relative px-8 py-6 border-b border-white/10\">\n <div class=\"absolute inset-0 bg-gradient-to-r from-blue-600/10 via-purple-600/10 to-pink-600/10\"></div>\n <div class=\"relative flex items-center gap-3\">\n <div class=\"w-12 h-12 rounded-xl bg-white/10 backdrop-blur-sm flex items-center justify-center\">\n <svg class=\"w-6 h-6 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"/>\n </svg>\n </div>\n <div>\n <h2 class=\"text-xl font-semibold text-white\">Profile Information</h2>\n <p class=\"text-sm text-gray-300\">Update your account details and preferences</p>\n </div>\n </div>\n </div>\n\n <!-- Form Content -->\n <form id=\"profile-form\" hx-put=\"/admin/profile\" hx-target=\"#form-messages\" class=\"p-8 space-y-6\">\n <div id=\"form-messages\"></div>\n\n <!-- Basic Information -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">First Name</label>\n <input \n type=\"text\" \n name=\"first_name\" \n value=\"${data.profile.first_name}\"\n required\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n placeholder=\"Enter your first name\"\n >\n </div>\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Last Name</label>\n <input \n type=\"text\" \n name=\"last_name\" \n value=\"${data.profile.last_name}\"\n required\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n placeholder=\"Enter your last name\"\n >\n </div>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Username</label>\n <input \n type=\"text\" \n name=\"username\" \n value=\"${data.profile.username}\"\n required\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n placeholder=\"Enter your username\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Email Address</label>\n <input \n type=\"email\" \n name=\"email\" \n value=\"${data.profile.email}\"\n required\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n placeholder=\"Enter your email address\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Phone Number</label>\n <input \n type=\"tel\" \n name=\"phone\" \n value=\"${data.profile.phone || ''}\"\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n placeholder=\"Enter your phone number\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Bio</label>\n <textarea \n name=\"bio\" \n rows=\"3\"\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all resize-none\"\n placeholder=\"Tell us about yourself...\"\n >${data.profile.bio || ''}</textarea>\n </div>\n\n <!-- Preferences -->\n <div class=\"pt-6 border-t border-white/10\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Preferences</h3>\n \n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Timezone</label>\n <select \n name=\"timezone\"\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n >\n ${data.timezones.map(tz => `\n <option value=\"${tz.value}\" ${tz.value === data.profile.timezone ? 'selected' : ''}>${tz.label}</option>\n `).join('')}\n </select>\n </div>\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Language</label>\n <select \n name=\"language\"\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n >\n ${data.languages.map(lang => `\n <option value=\"${lang.value}\" ${lang.value === data.profile.language ? 'selected' : ''}>${lang.label}</option>\n `).join('')}\n </select>\n </div>\n </div>\n </div>\n\n <!-- Notifications -->\n <div class=\"pt-6 border-t border-white/10\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Notifications</h3>\n \n <div class=\"space-y-5\">\n <div class=\"flex gap-3\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input\n type=\"checkbox\"\n id=\"email_notifications\"\n name=\"email_notifications\"\n value=\"1\"\n ${data.profile.email_notifications ? 'checked' : ''}\n class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto\"\n />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n <div class=\"text-sm/6\">\n <label for=\"email_notifications\" class=\"font-medium text-zinc-950 dark:text-white\">Email notifications</label>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Submit Button -->\n <div class=\"pt-6 border-t border-white/10\">\n <button \n type=\"submit\"\n class=\"w-full px-6 py-3 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-semibold rounded-xl hover:from-blue-700 hover:to-purple-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-transparent transition-all\"\n >\n Update Profile\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <!-- Profile Sidebar -->\n <div class=\"lg:col-span-1 space-y-6\">\n <!-- Avatar -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Profile Picture</h3>\n \n <div class=\"text-center\">\n <div class=\"w-24 h-24 rounded-full mx-auto mb-4 overflow-hidden bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center\">\n ${data.profile.avatar_url \n ? `<img src=\"${data.profile.avatar_url}\" alt=\"Profile picture\" class=\"w-full h-full object-cover\">`\n : `<span class=\"text-2xl font-bold text-white\">${data.profile.first_name.charAt(0)}${data.profile.last_name.charAt(0)}</span>`\n }\n </div>\n \n <form id=\"avatar-form\" hx-post=\"/admin/profile/avatar\" hx-target=\"#avatar-messages\" hx-encoding=\"multipart/form-data\">\n <input \n type=\"file\" \n name=\"avatar\" \n accept=\"image/*\"\n class=\"hidden\"\n id=\"avatar-input\"\n onchange=\"document.getElementById('avatar-form').dispatchEvent(new Event('submit'))\"\n >\n <label \n for=\"avatar-input\"\n class=\"inline-block px-4 py-2 bg-white/10 text-white rounded-xl border border-white/20 hover:bg-white/20 transition-all cursor-pointer\"\n >\n Change Picture\n </label>\n </form>\n \n <div id=\"avatar-messages\" class=\"mt-3\"></div>\n </div>\n </div>\n\n <!-- Account Info -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Account Information</h3>\n \n <div class=\"space-y-3 text-sm\">\n <div>\n <span class=\"text-gray-400\">Role:</span>\n <span class=\"text-white ml-2 capitalize\">${data.profile.role}</span>\n </div>\n <div>\n <span class=\"text-gray-400\">Member Since:</span>\n <span class=\"text-white ml-2\">${new Date(data.profile.created_at).toLocaleDateString()}</span>\n </div>\n ${data.profile.last_login_at ? `\n <div>\n <span class=\"text-gray-400\">Last Login:</span>\n <span class=\"text-white ml-2\">${new Date(data.profile.last_login_at).toLocaleDateString()}</span>\n </div>\n ` : ''}\n <div>\n <span class=\"text-gray-400\">Two-Factor Auth:</span>\n <span class=\"text-white ml-2\">${data.profile.two_factor_enabled ? 'Enabled' : 'Disabled'}</span>\n </div>\n </div>\n </div>\n\n <!-- Security Actions -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Security</h3>\n \n <div class=\"space-y-3\">\n <button \n type=\"button\"\n onclick=\"showChangePasswordModal()\"\n class=\"w-full text-left px-3 py-2 text-sm text-gray-300 hover:text-white hover:bg-white/10 rounded-xl transition-all\"\n >\n <svg class=\"w-4 h-4 inline mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-3.586l4.293-4.293A6 6 0 0119 9z\"/>\n </svg>\n Change Password\n </button>\n \n <button \n type=\"button\"\n onclick=\"toggle2FA()\"\n class=\"w-full text-left px-3 py-2 text-sm text-gray-300 hover:text-white hover:bg-white/10 rounded-xl transition-all\"\n >\n <svg class=\"w-4 h-4 inline mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"/>\n </svg>\n ${data.profile.two_factor_enabled ? 'Disable' : 'Enable'} 2FA\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Change Password Modal -->\n <div id=\"password-modal\" class=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 hidden\">\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl w-full max-w-md mx-4\">\n <div class=\"relative px-6 py-4 border-b border-white/10\">\n <div class=\"absolute inset-0 bg-gradient-to-r from-blue-600/10 via-purple-600/10 to-pink-600/10\"></div>\n <div class=\"relative flex items-center justify-between\">\n <h3 class=\"text-lg font-semibold text-white\">Change Password</h3>\n <button onclick=\"closePasswordModal()\" class=\"text-gray-300 hover:text-white\">\n <svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n </div>\n </div>\n \n <form id=\"password-form\" hx-post=\"/admin/profile/password\" hx-target=\"#password-messages\" class=\"p-6 space-y-4\">\n <div id=\"password-messages\"></div>\n \n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Current Password</label>\n <input \n type=\"password\" \n name=\"current_password\" \n required\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">New Password</label>\n <input \n type=\"password\" \n name=\"new_password\" \n required\n minlength=\"8\"\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Confirm New Password</label>\n <input \n type=\"password\" \n name=\"confirm_password\" \n required\n minlength=\"8\"\n class=\"w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all\"\n >\n </div>\n\n <div class=\"flex justify-end space-x-3 pt-4 border-t border-white/10\">\n <button \n type=\"button\" \n onclick=\"closePasswordModal()\"\n class=\"px-4 py-2 bg-white/10 text-white rounded-xl border border-white/20 hover:bg-white/20 transition-all\"\n >\n Cancel\n </button>\n <button \n type=\"submit\"\n class=\"px-4 py-2 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-medium rounded-xl hover:from-blue-700 hover:to-purple-700 transition-all\"\n >\n Update Password\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <script>\n function showChangePasswordModal() {\n document.getElementById('password-modal').classList.remove('hidden');\n }\n\n function closePasswordModal() {\n document.getElementById('password-modal').classList.add('hidden');\n document.getElementById('password-form').reset();\n }\n\n function toggle2FA() {\n // TODO: Implement 2FA toggle\n alert('Two-factor authentication setup coming soon!');\n }\n\n // Close modal on escape key\n document.addEventListener('keydown', function(e) {\n if (e.key === 'Escape' && !document.getElementById('password-modal').classList.contains('hidden')) {\n closePasswordModal();\n }\n });\n\n // Close modal on backdrop click\n document.getElementById('password-modal').addEventListener('click', function(e) {\n if (e.target === this) {\n closePasswordModal();\n }\n });\n </script>\n `\n\n const layoutData: AdminLayoutData = {\n title: 'User Profile',\n pageTitle: 'Profile',\n currentPath: '/admin/profile',\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayout(layoutData)\n}","export type AlertType = 'success' | 'error' | 'warning' | 'info'\n\nexport interface AlertData {\n type: AlertType\n title?: string\n message: string\n dismissible?: boolean\n className?: string\n icon?: boolean\n}\n\nexport function renderAlert(data: AlertData): string {\n const typeClasses = {\n success: 'bg-green-50 dark:bg-green-500/10 border border-green-600/20 dark:border-green-500/20',\n error: 'bg-error/10 border border-red-600/20 dark:border-red-500/20',\n warning: 'bg-amber-50 dark:bg-amber-500/10 border border-amber-600/20 dark:border-amber-500/20',\n info: 'bg-blue-50 dark:bg-blue-500/10 border border-blue-600/20 dark:border-blue-500/20'\n }\n\n const iconClasses = {\n success: 'text-green-600 dark:text-green-400',\n error: 'text-red-600 dark:text-red-400',\n warning: 'text-amber-600 dark:text-amber-400',\n info: 'text-blue-600 dark:text-blue-400'\n }\n\n const textClasses = {\n success: 'text-green-900 dark:text-green-300',\n error: 'text-red-900 dark:text-red-300',\n warning: 'text-amber-900 dark:text-amber-300',\n info: 'text-blue-900 dark:text-blue-300'\n }\n\n const messageTextClasses = {\n success: 'text-green-700 dark:text-green-400',\n error: 'text-red-700 dark:text-red-400',\n warning: 'text-amber-700 dark:text-amber-400',\n info: 'text-blue-700 dark:text-blue-400'\n }\n\n const icons = {\n success: `<path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\" />`,\n error: `<path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\" />`,\n warning: `<path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\" />`,\n info: `<path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\" />`\n }\n\n return `\n <div class=\"rounded-lg p-4 ${typeClasses[data.type]} ${data.className || ''}\" ${data.dismissible ? 'id=\"dismissible-alert\"' : ''}>\n <div class=\"flex\">\n ${data.icon !== false ? `\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 ${iconClasses[data.type]}\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n ${icons[data.type]}\n </svg>\n </div>\n ` : ''}\n <div class=\"${data.icon !== false ? 'ml-3' : ''}\">\n ${data.title ? `\n <h3 class=\"text-sm font-semibold ${textClasses[data.type]}\">\n ${data.title}\n </h3>\n ` : ''}\n <div class=\"${data.title ? 'mt-1 text-sm' : 'text-sm'} ${messageTextClasses[data.type]}\">\n <p>${data.message}</p>\n </div>\n </div>\n ${data.dismissible ? `\n <div class=\"ml-auto pl-3\">\n <div class=\"-mx-1.5 -my-1.5\">\n <button\n type=\"button\"\n class=\"inline-flex rounded-md p-1.5 ${iconClasses[data.type]} hover:bg-opacity-20 focus:outline-none focus:ring-2 focus:ring-offset-2\"\n onclick=\"document.getElementById('dismissible-alert').remove()\"\n >\n <span class=\"sr-only\">Dismiss</span>\n <svg class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n </div>\n ` : ''}\n </div>\n </div>\n `\n}\n\nexport function renderSuccessAlert(message: string, title?: string): string {\n return renderAlert({ type: 'success', message, title })\n}\n\nexport function renderErrorAlert(message: string, title?: string): string {\n return renderAlert({ type: 'error', message, title })\n}\n\nexport function renderWarningAlert(message: string, title?: string): string {\n return renderAlert({ type: 'warning', message, title })\n}\n\nexport function renderInfoAlert(message: string, title?: string): string {\n return renderAlert({ type: 'info', message, title })\n}\n","import { renderAdminLayout, AdminLayoutData } from '../layouts/admin-layout-v2.template'\n\nexport interface ActivityLog {\n id: string\n user_id: string\n action: string\n resource_type?: string\n resource_id?: string\n details?: any\n ip_address?: string\n user_agent?: string\n created_at: number\n user_email?: string\n user_name?: string\n}\n\nexport interface ActivityLogsPageData {\n logs: ActivityLog[]\n pagination: {\n page: number\n limit: number\n total: number\n pages: number\n }\n filters: {\n user_id?: string\n action?: string\n resource_type?: string\n date_from?: string\n date_to?: string\n }\n user?: {\n name: string\n email: string\n role: string\n }\n}\n\nexport function renderActivityLogsPage(data: ActivityLogsPageData): string {\n const pageContent = `\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl font-semibold text-white\">Activity Logs</h1>\n <p class=\"mt-2 text-sm text-gray-300\">Monitor user actions and system activity</p>\n </div>\n </div>\n\n <!-- Breadcrumb -->\n <nav class=\"flex mb-6\" aria-label=\"Breadcrumb\">\n <ol class=\"flex items-center space-x-3\">\n <li>\n <a href=\"/admin\" class=\"text-gray-300 hover:text-white transition-colors\">\n <svg class=\"h-5 w-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z\"/>\n </svg>\n </a>\n </li>\n <li class=\"flex items-center\">\n <svg class=\"h-5 w-5 text-gray-400 mx-2\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\"/>\n </svg>\n <span class=\"text-sm font-medium text-gray-200\">Activity Logs</span>\n </li>\n </ol>\n </nav>\n\n <!-- Filters -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl p-6 mb-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Filters</h3>\n \n <form method=\"GET\" action=\"/admin/activity-logs\" class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Action</label>\n <select name=\"action\" class=\"w-full px-3 py-2 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30\">\n <option value=\"\">All Actions</option>\n <option value=\"user.login\" ${data.filters.action === 'user.login' ? 'selected' : ''}>User Login</option>\n <option value=\"user.logout\" ${data.filters.action === 'user.logout' ? 'selected' : ''}>User Logout</option>\n <option value=\"user.invite_sent\" ${data.filters.action === 'user.invite_sent' ? 'selected' : ''}>User Invited</option>\n <option value=\"user.invitation_accepted\" ${data.filters.action === 'user.invitation_accepted' ? 'selected' : ''}>Invitation Accepted</option>\n <option value=\"profile.update\" ${data.filters.action === 'profile.update' ? 'selected' : ''}>Profile Update</option>\n <option value=\"profile.password_change\" ${data.filters.action === 'profile.password_change' ? 'selected' : ''}>Password Change</option>\n <option value=\"content.create\" ${data.filters.action === 'content.create' ? 'selected' : ''}>Content Created</option>\n <option value=\"content.update\" ${data.filters.action === 'content.update' ? 'selected' : ''}>Content Updated</option>\n <option value=\"content.delete\" ${data.filters.action === 'content.delete' ? 'selected' : ''}>Content Deleted</option>\n <option value=\"collection.create\" ${data.filters.action === 'collection.create' ? 'selected' : ''}>Collection Created</option>\n <option value=\"collection.update\" ${data.filters.action === 'collection.update' ? 'selected' : ''}>Collection Updated</option>\n </select>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Resource Type</label>\n <select name=\"resource_type\" class=\"w-full px-3 py-2 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30\">\n <option value=\"\">All Resources</option>\n <option value=\"users\" ${data.filters.resource_type === 'users' ? 'selected' : ''}>Users</option>\n <option value=\"content\" ${data.filters.resource_type === 'content' ? 'selected' : ''}>Content</option>\n <option value=\"collections\" ${data.filters.resource_type === 'collections' ? 'selected' : ''}>Collections</option>\n <option value=\"media\" ${data.filters.resource_type === 'media' ? 'selected' : ''}>Media</option>\n <option value=\"settings\" ${data.filters.resource_type === 'settings' ? 'selected' : ''}>Settings</option>\n </select>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">From Date</label>\n <input \n type=\"date\" \n name=\"date_from\" \n value=\"${data.filters.date_from || ''}\"\n class=\"w-full px-3 py-2 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">To Date</label>\n <input \n type=\"date\" \n name=\"date_to\" \n value=\"${data.filters.date_to || ''}\"\n class=\"w-full px-3 py-2 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30\"\n >\n </div>\n\n <div class=\"md:col-span-2 lg:col-span-4 flex gap-3\">\n <button \n type=\"submit\"\n class=\"px-6 py-2 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-medium rounded-xl hover:from-blue-700 hover:to-purple-700 transition-all\"\n >\n Apply Filters\n </button>\n <a \n href=\"/admin/activity-logs\"\n class=\"px-6 py-2 bg-white/10 text-white rounded-xl border border-white/20 hover:bg-white/20 transition-all\"\n >\n Clear Filters\n </a>\n </div>\n </form>\n </div>\n\n <!-- Activity Logs Table -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl overflow-hidden\">\n <div class=\"relative px-6 py-4 border-b border-white/10\">\n <div class=\"absolute inset-0 bg-gradient-to-r from-blue-600/10 via-purple-600/10 to-pink-600/10\"></div>\n <div class=\"relative flex items-center justify-between\">\n <h2 class=\"text-xl font-semibold text-white\">Recent Activity</h2>\n <div class=\"text-sm text-gray-300\">\n Showing ${data.logs.length} of ${data.pagination.total} logs\n </div>\n </div>\n </div>\n\n <div class=\"overflow-x-auto\">\n <table class=\"w-full\">\n <thead class=\"bg-white/5\">\n <tr>\n <th class=\"px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider\">Timestamp</th>\n <th class=\"px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider\">User</th>\n <th class=\"px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider\">Action</th>\n <th class=\"px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider\">Resource</th>\n <th class=\"px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider\">IP Address</th>\n <th class=\"px-6 py-3 text-left text-xs font-medium text-gray-300 uppercase tracking-wider\">Details</th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-white/10\">\n ${data.logs.map(log => `\n <tr class=\"hover:bg-white/5 transition-colors\">\n <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-300\">\n ${new Date(log.created_at).toLocaleString()}\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm text-white\">${log.user_name || 'Unknown'}</div>\n <div class=\"text-xs text-gray-400\">${log.user_email || 'N/A'}</div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <span class=\"inline-flex px-2 py-1 text-xs font-medium rounded-full ${getActionBadgeClass(log.action)}\">\n ${formatAction(log.action)}\n </span>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-300\">\n ${log.resource_type ? `\n <div class=\"text-white\">${log.resource_type}</div>\n ${log.resource_id ? `<div class=\"text-xs text-gray-400\">${log.resource_id}</div>` : ''}\n ` : 'N/A'}\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-300\">\n ${log.ip_address || 'N/A'}\n </td>\n <td class=\"px-6 py-4 text-sm text-gray-300\">\n ${log.details ? `\n <details class=\"cursor-pointer\">\n <summary class=\"text-blue-400 hover:text-blue-300\">View Details</summary>\n <pre class=\"mt-2 text-xs bg-black/20 p-2 rounded overflow-x-auto\">${JSON.stringify(log.details, null, 2)}</pre>\n </details>\n ` : 'N/A'}\n </td>\n </tr>\n `).join('')}\n </tbody>\n </table>\n </div>\n\n ${data.logs.length === 0 ? `\n <div class=\"text-center py-12\">\n <svg class=\"mx-auto h-12 w-12 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"/>\n </svg>\n <h3 class=\"mt-2 text-sm font-medium text-gray-300\">No activity logs found</h3>\n <p class=\"mt-1 text-sm text-gray-500\">Try adjusting your filters or check back later.</p>\n </div>\n ` : ''}\n\n <!-- Pagination -->\n ${data.pagination.pages > 1 ? `\n <div class=\"px-6 py-4 border-t border-white/10 flex items-center justify-between\">\n <div class=\"text-sm text-gray-300\">\n Page ${data.pagination.page} of ${data.pagination.pages} (${data.pagination.total} total logs)\n </div>\n <div class=\"flex space-x-2\">\n ${data.pagination.page > 1 ? `\n <a href=\"?page=${data.pagination.page - 1}&${new URLSearchParams(data.filters as Record<string, string>).toString()}\" \n class=\"px-3 py-1 bg-white/10 text-white rounded-lg border border-white/20 hover:bg-white/20 transition-all\">\n Previous\n </a>\n ` : ''}\n ${data.pagination.page < data.pagination.pages ? `\n <a href=\"?page=${data.pagination.page + 1}&${new URLSearchParams(data.filters as Record<string, string>).toString()}\" \n class=\"px-3 py-1 bg-white/10 text-white rounded-lg border border-white/20 hover:bg-white/20 transition-all\">\n Next\n </a>\n ` : ''}\n </div>\n </div>\n ` : ''}\n </div>\n </div>\n `\n\n const layoutData: AdminLayoutData = {\n title: 'Activity Logs',\n pageTitle: 'Activity Logs',\n currentPath: '/admin/activity-logs',\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayout(layoutData)\n}\n\nfunction getActionBadgeClass(action: string): string {\n if (action.includes('login') || action.includes('logout')) {\n return 'bg-blue-500/20 text-blue-300'\n } else if (action.includes('create') || action.includes('invite')) {\n return 'bg-green-500/20 text-green-300'\n } else if (action.includes('update') || action.includes('change')) {\n return 'bg-yellow-500/20 text-yellow-300'\n } else if (action.includes('delete') || action.includes('cancel')) {\n return 'bg-red-500/20 text-red-300'\n } else {\n return 'bg-gray-500/20 text-gray-300'\n }\n}\n\nfunction formatAction(action: string): string {\n // Convert action from dot notation to readable format\n return action\n .split('.')\n .map(part => part.replace(/_/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase()))\n .join(' - ')\n}","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\nimport { renderAlert } from '../alert.template'\nimport { renderConfirmationDialog, getConfirmationDialogScript } from '../components/confirmation-dialog.template'\nimport { escapeHtml } from '../../utils/sanitize'\n\nexport interface UserEditData {\n id: string\n email: string\n username: string\n firstName: string\n lastName: string\n phone?: string\n bio?: string\n avatarUrl?: string\n role: string\n isActive: boolean\n emailVerified: boolean\n twoFactorEnabled: boolean\n createdAt: number\n lastLoginAt?: number\n}\n\nexport interface UserEditPageData {\n userToEdit: UserEditData\n roles: Array<{ value: string; label: string }>\n error?: string\n success?: string\n user?: {\n name: string\n email: string\n role: string\n }\n}\n\nexport function renderUserEditPage(data: UserEditPageData): string {\n const pageContent = `\n <div>\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <div class=\"flex items-center gap-3 mb-2\">\n <a href=\"/admin/users\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors\">\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\"/>\n </svg>\n </a>\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">Edit User</h1>\n </div>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">Update user account and permissions</p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none flex space-x-3\">\n <button\n type=\"submit\"\n form=\"user-edit-form\"\n class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"/>\n </svg>\n Save Changes\n </button>\n <a\n href=\"/admin/users\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n Cancel\n </a>\n </div>\n </div>\n\n <!-- Alert Messages -->\n <div id=\"form-messages\">\n ${data.error ? renderAlert({ type: 'error', message: data.error, dismissible: true }) : ''}\n ${data.success ? renderAlert({ type: 'success', message: data.success, dismissible: true }) : ''}\n </div>\n\n <!-- User Edit Form -->\n <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <!-- Main Form -->\n <div class=\"lg:col-span-2\">\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-8\">\n <form id=\"user-edit-form\" hx-put=\"/admin/users/${data.userToEdit.id}\" hx-target=\"#form-messages\">\n\n <!-- Basic Information -->\n <div class=\"mb-8\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white mb-4\">Basic Information</h3>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">First Name</label>\n <input\n type=\"text\"\n name=\"first_name\"\n value=\"${escapeHtml(data.userToEdit.firstName || '')}\"\n required\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Last Name</label>\n <input\n type=\"text\"\n name=\"last_name\"\n value=\"${escapeHtml(data.userToEdit.lastName || '')}\"\n required\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Username</label>\n <input\n type=\"text\"\n name=\"username\"\n value=\"${escapeHtml(data.userToEdit.username || '')}\"\n required\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Email</label>\n <input\n type=\"email\"\n name=\"email\"\n value=\"${escapeHtml(data.userToEdit.email || '')}\"\n required\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Phone</label>\n <input\n type=\"tel\"\n name=\"phone\"\n value=\"${escapeHtml(data.userToEdit.phone || '')}\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label for=\"role\" class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">Role</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select\n id=\"role\"\n name=\"role\"\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6\"\n >\n ${data.roles.map(role => `\n <option value=\"${escapeHtml(role.value)}\" ${data.userToEdit.role === role.value ? 'selected' : ''}>${escapeHtml(role.label)}</option>\n `).join('')}\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n </div>\n\n <div class=\"mt-6\">\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Bio</label>\n <textarea\n name=\"bio\"\n rows=\"3\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n >${escapeHtml(data.userToEdit.bio || '')}</textarea>\n </div>\n </div>\n\n <!-- Account Status -->\n <div class=\"mb-8\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white mb-4\">Account Status</h3>\n <div class=\"space-y-4\">\n <div class=\"flex gap-3\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input\n type=\"checkbox\"\n id=\"is_active\"\n name=\"is_active\"\n value=\"1\"\n ${data.userToEdit.isActive ? 'checked' : ''}\n class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto\"\n />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n <div class=\"text-sm/6\">\n <label for=\"is_active\" class=\"font-medium text-zinc-950 dark:text-white\">Account Active</label>\n <p class=\"text-zinc-500 dark:text-zinc-400\">User can sign in and access the system</p>\n </div>\n </div>\n\n <div class=\"flex gap-3\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input\n type=\"checkbox\"\n id=\"email_verified\"\n name=\"email_verified\"\n value=\"1\"\n ${data.userToEdit.emailVerified ? 'checked' : ''}\n class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto\"\n />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n <div class=\"text-sm/6\">\n <label for=\"email_verified\" class=\"font-medium text-zinc-950 dark:text-white\">Email Verified</label>\n <p class=\"text-zinc-500 dark:text-zinc-400\">User has verified their email address</p>\n </div>\n </div>\n </div>\n </div>\n\n </form>\n </div>\n </div>\n\n <!-- Sidebar -->\n <div class=\"lg:col-span-1\">\n <!-- User Stats -->\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 mb-6\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white mb-4\">User Details</h3>\n <dl class=\"space-y-4 text-sm\">\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">User ID</dt>\n <dd class=\"mt-1 text-zinc-950 dark:text-white font-mono text-xs\">${data.userToEdit.id}</dd>\n </div>\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Created</dt>\n <dd class=\"mt-1 text-zinc-950 dark:text-white\">${new Date(data.userToEdit.createdAt).toLocaleDateString()}</dd>\n </div>\n ${data.userToEdit.lastLoginAt ? `\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Last Login</dt>\n <dd class=\"mt-1 text-zinc-950 dark:text-white\">${new Date(data.userToEdit.lastLoginAt).toLocaleDateString()}</dd>\n </div>\n ` : ''}\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Status</dt>\n <dd class=\"mt-1\">\n ${data.userToEdit.isActive\n ? '<span class=\"inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium bg-lime-50 dark:bg-lime-500/10 text-lime-700 dark:text-lime-300 ring-1 ring-inset ring-lime-700/10 dark:ring-lime-400/20\">Active</span>'\n : '<span class=\"inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium bg-red-50 dark:bg-red-500/10 text-red-700 dark:text-red-400 ring-1 ring-inset ring-red-700/10 dark:ring-red-500/20\">Inactive</span>'\n }\n </dd>\n </div>\n ${data.userToEdit.twoFactorEnabled ? `\n <div>\n <dt class=\"text-zinc-500 dark:text-zinc-400\">Security</dt>\n <dd class=\"mt-1\">\n <span class=\"inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium bg-blue-50 dark:bg-blue-500/10 text-blue-700 dark:text-blue-400 ring-1 ring-inset ring-blue-700/10 dark:ring-blue-500/20\">2FA Enabled</span>\n </dd>\n </div>\n ` : ''}\n </dl>\n </div>\n\n <!-- Danger Zone -->\n <div class=\"rounded-xl bg-red-50 dark:bg-red-500/10 shadow-sm ring-1 ring-red-600/20 dark:ring-red-500/20 p-6\">\n <h3 class=\"text-base font-semibold text-red-900 dark:text-red-300 mb-2\">Danger Zone</h3>\n <p class=\"text-sm text-red-700 dark:text-red-400 mb-4\">Irreversible and destructive actions</p>\n\n <div class=\"flex gap-3 mb-4\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input\n type=\"checkbox\"\n id=\"hard-delete-checkbox\"\n class=\"col-start-1 row-start-1 appearance-none rounded border border-red-300 dark:border-red-700 bg-white dark:bg-red-950/50 checked:border-red-600 checked:bg-red-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600 disabled:border-red-200 dark:disabled:border-red-900 disabled:bg-red-50 dark:disabled:bg-red-950/30 disabled:checked:bg-red-300 dark:disabled:checked:bg-red-900 forced-colors:appearance-auto\"\n />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-red-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n <div class=\"text-sm/6\">\n <label for=\"hard-delete-checkbox\" class=\"font-medium text-red-900 dark:text-red-300 cursor-pointer\">Hard Delete (Permanent)</label>\n <p class=\"text-red-700 dark:text-red-400\">Permanently remove from database. Unchecked performs soft delete (deactivate only).</p>\n </div>\n </div>\n\n <button\n onclick=\"deleteUser('${data.userToEdit.id}')\"\n class=\"w-full inline-flex items-center justify-center rounded-lg bg-red-600 px-3 py-2 text-sm font-semibold text-white hover:bg-red-700 transition-colors\"\n >\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"/>\n </svg>\n Delete User\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <script>\n let userIdToDelete = null;\n\n function deleteUser(userId) {\n userIdToDelete = userId;\n showConfirmDialog('delete-user-confirm');\n }\n\n function performDeleteUser() {\n if (!userIdToDelete) return;\n\n const checkbox = document.getElementById('hard-delete-checkbox');\n const hardDelete = checkbox ? checkbox.checked : false;\n\n fetch(\\`/admin/users/\\${userIdToDelete}\\`, {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ hardDelete })\n })\n .then(response => response.json())\n .then(data => {\n if (data.success) {\n // Add a small delay to ensure database transaction completes\n // and add cache busting to force refresh\n setTimeout(() => {\n window.location.href = '/admin/users?_t=' + Date.now()\n }, 300)\n } else {\n alert('Error deleting user: ' + (data.error || 'Unknown error'))\n }\n })\n .catch(error => {\n console.error('Error:', error)\n alert('Error deleting user')\n })\n .finally(() => {\n userIdToDelete = null;\n });\n }\n </script>\n\n <!-- Confirmation Dialogs -->\n ${renderConfirmationDialog({\n id: 'delete-user-confirm',\n title: 'Delete User',\n message: 'Are you sure you want to delete this user? Check the \"Hard Delete\" option to permanently remove all data from the database. This action cannot be undone!',\n confirmText: 'Delete',\n cancelText: 'Cancel',\n iconColor: 'red',\n confirmClass: 'bg-red-500 hover:bg-red-400',\n onConfirm: 'performDeleteUser()'\n })}\n\n ${getConfirmationDialogScript()}\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: 'Edit User',\n pageTitle: `Edit User - ${data.userToEdit.firstName} ${data.userToEdit.lastName}`,\n currentPath: '/admin/users',\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}\n","export interface ConfirmationDialogOptions {\n id: string\n title: string\n message: string\n confirmText?: string\n cancelText?: string\n confirmClass?: string\n iconColor?: 'red' | 'yellow' | 'blue'\n onConfirm?: string // JavaScript code to execute on confirm\n}\n\nexport function renderConfirmationDialog(options: ConfirmationDialogOptions): string {\n const {\n id,\n title,\n message,\n confirmText = 'Confirm',\n cancelText = 'Cancel',\n confirmClass = 'bg-red-500 hover:bg-red-400',\n iconColor = 'red',\n onConfirm = ''\n } = options\n\n const iconColorClasses = {\n red: 'bg-red-500/10 text-red-400',\n yellow: 'bg-yellow-500/10 text-yellow-400',\n blue: 'bg-blue-500/10 text-blue-400'\n }\n\n return `\n <el-dialog>\n <dialog\n id=\"${id}\"\n aria-labelledby=\"${id}-title\"\n class=\"fixed inset-0 m-0 size-auto max-h-none max-w-none overflow-y-auto bg-transparent p-0 backdrop:bg-transparent\"\n >\n <el-dialog-backdrop class=\"fixed inset-0 bg-gray-900/50 transition-opacity data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in\"></el-dialog-backdrop>\n\n <div tabindex=\"0\" class=\"flex min-h-full items-end justify-center p-4 text-center focus:outline focus:outline-0 sm:items-center sm:p-0\">\n <el-dialog-panel class=\"relative transform overflow-hidden rounded-lg bg-gray-800 px-4 pb-4 pt-5 text-left shadow-xl outline outline-1 -outline-offset-1 outline-white/10 transition-all data-[closed]:translate-y-4 data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in sm:my-8 sm:w-full sm:max-w-lg sm:p-6 data-[closed]:sm:translate-y-0 data-[closed]:sm:scale-95\">\n <div class=\"sm:flex sm:items-start\">\n <div class=\"mx-auto flex size-12 shrink-0 items-center justify-center rounded-full ${iconColorClasses[iconColor]} sm:mx-0 sm:size-10\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" data-slot=\"icon\" aria-hidden=\"true\" class=\"size-6\">\n <path d=\"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div class=\"mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left\">\n <h3 id=\"${id}-title\" class=\"text-base font-semibold text-white\">${title}</h3>\n <div class=\"mt-2\">\n <p class=\"text-sm text-gray-400\">${message}</p>\n </div>\n </div>\n </div>\n <div class=\"mt-5 sm:mt-4 sm:flex sm:flex-row-reverse\">\n <button\n type=\"button\"\n onclick=\"${onConfirm}; document.getElementById('${id}').close()\"\n command=\"close\"\n commandfor=\"${id}\"\n class=\"confirm-button inline-flex w-full justify-center rounded-md ${confirmClass} px-3 py-2 text-sm font-semibold text-white sm:ml-3 sm:w-auto\"\n >\n ${confirmText}\n </button>\n <button\n type=\"button\"\n command=\"close\"\n commandfor=\"${id}\"\n class=\"mt-3 inline-flex w-full justify-center rounded-md bg-white/10 px-3 py-2 text-sm font-semibold text-white ring-1 ring-inset ring-white/5 hover:bg-white/20 sm:mt-0 sm:w-auto\"\n >\n ${cancelText}\n </button>\n </div>\n </el-dialog-panel>\n </div>\n </dialog>\n </el-dialog>\n `\n}\n\n/**\n * Helper function to show a confirmation dialog programmatically\n * Usage in templates: Add this script and call showConfirmDialog()\n */\nexport function getConfirmationDialogScript(): string {\n return `\n <script src=\"https://cdn.jsdelivr.net/npm/@tailwindplus/elements@1\" type=\"module\"></script>\n <script>\n function showConfirmDialog(dialogId) {\n const dialog = document.getElementById(dialogId);\n if (dialog) {\n dialog.showModal();\n }\n }\n </script>\n `\n}\n","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\nimport { renderAlert } from '../alert.template'\n\nexport interface UserNewPageData {\n roles: Array<{ value: string; label: string }>\n error?: string\n success?: string\n user?: {\n name: string\n email: string\n role: string\n }\n}\n\nexport function renderUserNewPage(data: UserNewPageData): string {\n const pageContent = `\n <div>\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <div class=\"flex items-center gap-3 mb-2\">\n <a href=\"/admin/users\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors\">\n <svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\"/>\n </svg>\n </a>\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">Create New User</h1>\n </div>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">Add a new user account to the system</p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none flex space-x-3\">\n <button\n type=\"submit\"\n form=\"user-new-form\"\n class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n Create User\n </button>\n <a\n href=\"/admin/users\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n Cancel\n </a>\n </div>\n </div>\n\n <!-- Alert Messages -->\n <div id=\"form-messages\">\n ${data.error ? renderAlert({ type: 'error', message: data.error, dismissible: true }) : ''}\n ${data.success ? renderAlert({ type: 'success', message: data.success, dismissible: true }) : ''}\n </div>\n\n <!-- User New Form -->\n <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <!-- Main Form -->\n <div class=\"lg:col-span-2\">\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-8\">\n <form id=\"user-new-form\" hx-post=\"/admin/users/new\" hx-target=\"#form-messages\">\n\n <!-- Basic Information -->\n <div class=\"mb-8\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white mb-4\">Basic Information</h3>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n First Name <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n name=\"first_name\"\n required\n placeholder=\"Enter first name\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Last Name <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n name=\"last_name\"\n required\n placeholder=\"Enter last name\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Username <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n name=\"username\"\n required\n placeholder=\"Enter username\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Email <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"email\"\n name=\"email\"\n required\n placeholder=\"user@example.com\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Phone</label>\n <input\n type=\"tel\"\n name=\"phone\"\n placeholder=\"+1 (555) 000-0000\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label for=\"role\" class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">\n Role <span class=\"text-red-500\">*</span>\n </label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select\n id=\"role\"\n name=\"role\"\n required\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6\"\n >\n ${data.roles.map(role => `\n <option value=\"${role.value}\">${role.label}</option>\n `).join('')}\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n </div>\n\n <div class=\"mt-6\">\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Bio</label>\n <textarea\n name=\"bio\"\n rows=\"3\"\n placeholder=\"Enter a short bio (optional)\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n ></textarea>\n </div>\n </div>\n\n <!-- Password -->\n <div class=\"mb-8\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white mb-4\">Password</h3>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Password <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"password\"\n name=\"password\"\n required\n placeholder=\"Enter password (min 8 characters)\"\n minlength=\"8\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Confirm Password <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"password\"\n name=\"confirm_password\"\n required\n placeholder=\"Confirm password\"\n minlength=\"8\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n />\n </div>\n </div>\n </div>\n\n <!-- Account Status -->\n <div class=\"mb-8\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white mb-4\">Account Status</h3>\n <div class=\"space-y-5\">\n <div class=\"flex gap-3\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input\n type=\"checkbox\"\n id=\"is_active\"\n name=\"is_active\"\n value=\"1\"\n checked\n class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto\"\n />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n <div class=\"text-sm/6\">\n <label for=\"is_active\" class=\"font-medium text-zinc-950 dark:text-white\">Account Active</label>\n <p class=\"text-zinc-500 dark:text-zinc-400\">User can sign in and access the system</p>\n </div>\n </div>\n\n <div class=\"flex gap-3\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input\n type=\"checkbox\"\n id=\"email_verified\"\n name=\"email_verified\"\n value=\"1\"\n class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto\"\n />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n <div class=\"text-sm/6\">\n <label for=\"email_verified\" class=\"font-medium text-zinc-950 dark:text-white\">Email Verified</label>\n <p class=\"text-zinc-500 dark:text-zinc-400\">Mark email as verified</p>\n </div>\n </div>\n </div>\n </div>\n\n </form>\n </div>\n </div>\n\n <!-- Sidebar -->\n <div class=\"lg:col-span-1\">\n <!-- Help Text -->\n <div class=\"rounded-xl bg-blue-50 dark:bg-blue-500/10 shadow-sm ring-1 ring-blue-600/20 dark:ring-blue-500/20 p-6\">\n <h3 class=\"text-base font-semibold text-blue-900 dark:text-blue-300 mb-2\">Creating a User</h3>\n <div class=\"text-sm text-blue-700 dark:text-blue-400 space-y-3\">\n <p>Fill in the required fields marked with <span class=\"text-red-500\">*</span> to create a new user account.</p>\n <p>The password must be at least 8 characters long.</p>\n <p>By default, new users are created as active and can sign in immediately.</p>\n <p>You can edit user details and permissions after creation.</p>\n </div>\n </div>\n\n <!-- Role Descriptions -->\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 mt-6\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white mb-4\">Role Descriptions</h3>\n <dl class=\"space-y-3 text-sm\">\n <div>\n <dt class=\"font-medium text-zinc-950 dark:text-white\">Administrator</dt>\n <dd class=\"text-zinc-500 dark:text-zinc-400\">Full system access and permissions</dd>\n </div>\n <div>\n <dt class=\"font-medium text-zinc-950 dark:text-white\">Editor</dt>\n <dd class=\"text-zinc-500 dark:text-zinc-400\">Can create and edit content</dd>\n </div>\n <div>\n <dt class=\"font-medium text-zinc-950 dark:text-white\">Author</dt>\n <dd class=\"text-zinc-500 dark:text-zinc-400\">Can create own content</dd>\n </div>\n <div>\n <dt class=\"font-medium text-zinc-950 dark:text-white\">Viewer</dt>\n <dd class=\"text-zinc-500 dark:text-zinc-400\">Read-only access</dd>\n </div>\n </dl>\n </div>\n </div>\n </div>\n </div>\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: 'Create User',\n pageTitle: 'Create New User',\n currentPath: '/admin/users',\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}\n","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\nimport { renderPagination, PaginationData } from '../pagination.template'\nimport { renderAlert } from '../alert.template'\nimport { renderTable, TableColumn, TableData } from '../table.template'\nimport { renderConfirmationDialog, getConfirmationDialogScript } from '../components/confirmation-dialog.template'\n\nexport interface User {\n id: string\n email: string\n username: string\n firstName: string\n lastName: string\n role: string\n avatar?: string\n isActive: boolean\n lastLoginAt?: number\n createdAt: number\n updatedAt: number\n formattedLastLogin?: string\n formattedCreatedAt?: string\n}\n\nexport interface UsersListPageData {\n users: User[]\n pagination?: PaginationData\n currentPage: number\n totalPages: number\n totalUsers: number\n statusFilter?: string\n roleFilter?: string\n searchFilter?: string\n error?: string\n success?: string\n user?: {\n name: string\n email: string\n role: string\n }\n version?: string\n}\n\nexport function renderUsersListPage(data: UsersListPageData): string {\n const columns: TableColumn[] = [\n {\n key: 'avatar',\n label: '',\n className: 'w-12',\n sortable: false,\n render: (value: string | null, row: User) => {\n const initials = `${row.firstName.charAt(0)}${row.lastName.charAt(0)}`.toUpperCase()\n if (value) {\n return `<img src=\"${value}\" alt=\"${row.firstName} ${row.lastName}\" class=\"w-8 h-8 rounded-full\">`\n }\n return `\n <div class=\"w-8 h-8 bg-gradient-to-br from-cyan-400 to-blue-500 dark:from-cyan-300 dark:to-blue-400 rounded-full flex items-center justify-center\">\n <span class=\"text-xs font-medium text-white\">${initials}</span>\n </div>\n `\n }\n },\n {\n key: 'name',\n label: 'Name',\n sortable: true,\n sortType: 'string',\n render: (value: any, row: User) => {\n const escapeHtml = (text: string) => text.replace(/[&<>\"']/g, (char) => ({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n }[char] || char))\n \n const truncatedFirstName = row.firstName.length > 25 ? row.firstName.substring(0, 25) + '...' : row.firstName\n const truncatedLastName = row.lastName.length > 25 ? row.lastName.substring(0, 25) + '...' : row.lastName\n const fullName = escapeHtml(`${truncatedFirstName} ${truncatedLastName}`)\n const truncatedUsername = row.username.length > 100 ? row.username.substring(0, 100) + '...' : row.username\n const username = escapeHtml(truncatedUsername)\n const statusBadge = row.isActive ?\n '<span class=\"inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium bg-lime-50 dark:bg-lime-500/10 text-lime-700 dark:text-lime-300 ring-1 ring-inset ring-lime-700/10 dark:ring-lime-400/20 ml-2\">Active</span>' :\n '<span class=\"inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium bg-red-50 dark:bg-red-500/10 text-red-700 dark:text-red-400 ring-1 ring-inset ring-red-700/10 dark:ring-red-500/20 ml-2\">Inactive</span>'\n return `\n <div>\n <div class=\"text-sm font-medium text-zinc-950 dark:text-white\">${fullName}${statusBadge}</div>\n <div class=\"text-sm text-zinc-500 dark:text-zinc-400\">@${username}</div>\n </div>\n `\n }\n },\n {\n key: 'email',\n label: 'Email',\n sortable: true,\n sortType: 'string',\n render: (value: string) => {\n const escapeHtml = (text: string) => text.replace(/[&<>\"']/g, (char) => ({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n }[char] || char))\n const escapedEmail = escapeHtml(value)\n return `<a href=\"mailto:${escapedEmail}\" class=\"text-cyan-600 dark:text-cyan-400 hover:text-cyan-700 dark:hover:text-cyan-300 transition-colors\">${escapedEmail}</a>`\n }\n },\n {\n key: 'role',\n label: 'Role',\n sortable: true,\n sortType: 'string',\n render: (value: string) => {\n const roleColors = {\n admin: 'bg-red-50 dark:bg-red-500/10 text-red-700 dark:text-red-400 ring-1 ring-inset ring-red-700/10 dark:ring-red-500/20',\n editor: 'bg-blue-50 dark:bg-blue-500/10 text-blue-700 dark:text-blue-400 ring-1 ring-inset ring-blue-700/10 dark:ring-blue-500/20',\n author: 'bg-cyan-50 dark:bg-cyan-500/10 text-cyan-700 dark:text-cyan-400 ring-1 ring-inset ring-cyan-700/10 dark:ring-cyan-500/20',\n viewer: 'bg-zinc-50 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 ring-1 ring-inset ring-zinc-500/10 dark:ring-zinc-400/20'\n }\n const colorClass = roleColors[value as keyof typeof roleColors] || 'bg-zinc-50 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 ring-1 ring-inset ring-zinc-500/10 dark:ring-zinc-400/20'\n return `<span class=\"inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium ${colorClass}\">${value.charAt(0).toUpperCase() + value.slice(1)}</span>`\n }\n },\n {\n key: 'lastLoginAt',\n label: 'Last Login',\n sortable: true,\n sortType: 'date',\n render: (value: number | null) => {\n if (!value) return '<span class=\"text-zinc-500 dark:text-zinc-400\">Never</span>'\n return `<span class=\"text-sm text-zinc-500 dark:text-zinc-400\">${new Date(value).toLocaleDateString()}</span>`\n }\n },\n {\n key: 'createdAt',\n label: 'Created',\n sortable: true,\n sortType: 'date',\n render: (value: number) => `<span class=\"text-sm text-zinc-500 dark:text-zinc-400\">${new Date(value).toLocaleDateString()}</span>`\n },\n {\n key: 'actions',\n label: 'Actions',\n className: 'text-right',\n sortable: false,\n render: (value: any, row: User) => `\n <div class=\"flex justify-end space-x-2\">\n ${row.isActive ?\n `<button onclick=\"toggleUserStatus('${row.id}', false)\" title=\"Deactivate user\" class=\"inline-flex items-center justify-center p-2 text-sm font-medium rounded-lg bg-gradient-to-r from-red-500 to-pink-500 dark:from-red-400 dark:to-pink-400 text-white hover:from-red-600 hover:to-pink-600 dark:hover:from-red-500 dark:hover:to-pink-500 shadow-sm transition-all duration-200\">\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636\"/>\n </svg>\n </button>` :\n `<button onclick=\"toggleUserStatus('${row.id}', true)\" title=\"Activate user\" class=\"inline-flex items-center justify-center p-2 text-sm font-medium rounded-lg bg-gradient-to-r from-lime-500 to-green-500 dark:from-lime-400 dark:to-green-400 text-white hover:from-lime-600 hover:to-green-600 dark:hover:from-lime-500 dark:hover:to-green-500 shadow-sm transition-all duration-200\">\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"/>\n </svg>\n </button>`\n }\n </div>\n `\n }\n ]\n\n const tableData: TableData<User> = {\n tableId: 'users-table',\n columns,\n rows: data.users,\n selectable: false,\n rowClickable: true,\n rowClickUrl: (row: User) => `/admin/users/${row.id}/edit`,\n emptyMessage: 'No users found'\n }\n\n const pageContent = `\n <div>\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">User Management</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">Manage user accounts and permissions</p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none flex space-x-3\">\n <a href=\"/admin/users/new\" class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n Add User\n </a>\n <button class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\" onclick=\"exportUsers()\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"></path>\n </svg>\n Export\n </button>\n </div>\n </div>\n\n <!-- Alert Messages -->\n ${data.error ? renderAlert({ type: 'error', message: data.error, dismissible: true }) : ''}\n ${data.success ? renderAlert({ type: 'success', message: data.success, dismissible: true }) : ''}\n\n <!-- Stats -->\n <div class=\"mb-6\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white\">User Statistics</h3>\n <dl class=\"mt-5 grid grid-cols-1 divide-zinc-950/5 dark:divide-white/10 overflow-hidden rounded-lg bg-zinc-800/75 dark:bg-zinc-800/75 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 md:grid-cols-4 md:divide-x md:divide-y-0\">\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Total Users</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-cyan-400\">\n ${data.totalUsers}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-lime-400/10 text-lime-600 dark:text-lime-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Increased by</span>\n 5.2%\n </div>\n </dd>\n </div>\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Active Users</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-lime-400\">\n ${data.users.filter(u => u.isActive).length}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-lime-400/10 text-lime-600 dark:text-lime-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Increased by</span>\n 3.1%\n </div>\n </dd>\n </div>\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Administrators</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-pink-400\">\n ${data.users.filter(u => u.role === 'admin').length}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-lime-400/10 text-lime-600 dark:text-lime-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Increased by</span>\n 1.8%\n </div>\n </dd>\n </div>\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Active This Week</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-purple-400\">\n ${data.users.filter(u => u.lastLoginAt && u.lastLoginAt > Date.now() - 7 * 24 * 60 * 60 * 1000).length}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-pink-400/10 text-pink-600 dark:text-pink-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 3a.75.75 0 0 1 .75.75v10.638l3.96-4.158a.75.75 0 1 1 1.08 1.04l-5.25 5.5a.75.75 0 0 1-1.08 0l-5.25-5.5a.75.75 0 1 1 1.08-1.04l3.96 4.158V3.75A.75.75 0 0 1 10 3Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Decreased by</span>\n 2.3%\n </div>\n </dd>\n </div>\n </dl>\n </div>\n\n <!-- Filters with Gradient Background -->\n <div class=\"relative rounded-xl overflow-hidden mb-6\">\n <!-- Gradient Background Layer -->\n <div class=\"absolute inset-0 bg-gradient-to-r from-purple-500/10 via-pink-500/10 to-blue-500/10 dark:from-purple-400/20 dark:via-pink-400/20 dark:to-blue-400/20\"></div>\n\n <!-- Content Layer with backdrop blur -->\n <div class=\"relative bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10\">\n <div class=\"px-6 py-5\">\n <div class=\"grid grid-cols-1 md:grid-cols-4 gap-4\">\n <!-- Modern Search Input -->\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Search</label>\n <div class=\"relative group\">\n <input\n type=\"text\"\n name=\"search\"\n id=\"user-search-input\"\n value=\"${data.searchFilter || ''}\"\n placeholder=\"Search users...\"\n class=\"rounded-full bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2.5 pl-11 text-sm w-full text-zinc-950 dark:text-white border-2 border-purple-200/50 dark:border-purple-700/50 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:border-purple-500 dark:focus:border-purple-400 focus:bg-white dark:focus:bg-zinc-800 focus:shadow-lg focus:shadow-purple-500/20 dark:focus:shadow-purple-400/20 transition-all duration-300\"\n hx-get=\"/admin/users\"\n hx-trigger=\"keyup changed delay:300ms\"\n hx-target=\"body\"\n hx-include=\"[name='role'], [name='status']\"\n hx-on::after-request=\"\n const input = document.getElementById('user-search-input');\n if (input && document.activeElement === input) {\n const len = input.value.length;\n setTimeout(() => {\n input.focus();\n input.setSelectionRange(len, len);\n }, 10);\n }\n \"\n >\n <!-- Gradient search icon -->\n <div class=\"absolute left-3.5 top-2.5 flex items-center justify-center w-5 h-5 rounded-full bg-gradient-to-br from-purple-400 to-pink-500 dark:from-purple-300 dark:to-pink-400 opacity-90 group-focus-within:opacity-100 transition-opacity\">\n <svg class=\"h-3 w-3 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"/>\n </svg>\n </div>\n </div>\n </div>\n\n <div>\n <label class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">Role</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select\n name=\"role\"\n hx-get=\"/admin/users\"\n hx-trigger=\"change\"\n hx-target=\"body\"\n hx-include=\"[name='search'], [name='status']\"\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-purple-500/30 dark:outline-purple-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-purple-500 dark:focus-visible:outline-purple-400 sm:text-sm/6\"\n >\n <option value=\"\" ${!data.roleFilter ? 'selected' : ''}>All Roles</option>\n <option value=\"admin\" ${data.roleFilter === 'admin' ? 'selected' : ''}>Admin</option>\n <option value=\"editor\" ${data.roleFilter === 'editor' ? 'selected' : ''}>Editor</option>\n <option value=\"author\" ${data.roleFilter === 'author' ? 'selected' : ''}>Author</option>\n <option value=\"viewer\" ${data.roleFilter === 'viewer' ? 'selected' : ''}>Viewer</option>\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-purple-600 dark:text-purple-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n\n <div>\n <label class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">Status</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select\n name=\"status\"\n hx-get=\"/admin/users\"\n hx-trigger=\"change\"\n hx-target=\"body\"\n hx-include=\"[name='search'], [name='role']\"\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-purple-500/30 dark:outline-purple-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-purple-500 dark:focus-visible:outline-purple-400 sm:text-sm/6\"\n >\n <option value=\"active\" ${!data.statusFilter || data.statusFilter === 'active' ? 'selected' : ''}>Active</option>\n <option value=\"inactive\" ${data.statusFilter === 'inactive' ? 'selected' : ''}>Inactive</option>\n <option value=\"all\" ${data.statusFilter === 'all' ? 'selected' : ''}>All Users</option>\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-purple-600 dark:text-purple-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n\n <div>\n <label class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\"> </label>\n <div class=\"mt-2\">\n <button\n class=\"inline-flex items-center gap-x-1.5 justify-center px-4 py-2 bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm text-zinc-950 dark:text-white text-sm font-medium rounded-full ring-1 ring-inset ring-purple-200/50 dark:ring-purple-700/50 hover:bg-gradient-to-r hover:from-purple-50 hover:to-pink-50 dark:hover:from-purple-900/30 dark:hover:to-pink-900/30 hover:ring-purple-300 dark:hover:ring-purple-600 transition-all duration-200 w-full\"\n onclick=\"clearFilters()\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n Clear Filters\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Users Table -->\n ${renderTable(tableData)}\n\n <!-- Pagination -->\n ${data.pagination ? renderPagination(data.pagination) : ''}\n </div>\n\n <script>\n let userStatusData = null;\n\n function toggleUserStatus(userId, activate) {\n userStatusData = { userId, activate };\n showConfirmDialog('toggle-user-status-confirm');\n }\n\n function performToggleUserStatus() {\n if (!userStatusData) return;\n\n const { userId, activate } = userStatusData;\n\n fetch(\\`/admin/users/\\${userId}/toggle\\`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ active: activate })\n })\n .then(response => response.json())\n .then(data => {\n if (data.success) {\n location.reload()\n } else {\n alert('Error updating user status')\n }\n })\n .catch(error => {\n console.error('Error:', error)\n alert('Error updating user status')\n })\n .finally(() => {\n userStatusData = null;\n });\n }\n\n function clearFilters() {\n window.location.href = '/admin/users'\n }\n\n function exportUsers() {\n window.open('/admin/users/export', '_blank')\n }\n </script>\n\n <!-- Confirmation Dialogs -->\n ${renderConfirmationDialog({\n id: 'toggle-user-status-confirm',\n title: 'Toggle User Status',\n message: 'Are you sure you want to activate/deactivate this user?',\n confirmText: 'Confirm',\n cancelText: 'Cancel',\n iconColor: 'yellow',\n confirmClass: 'bg-yellow-500 hover:bg-yellow-400',\n onConfirm: 'performToggleUserStatus()'\n })}\n\n ${getConfirmationDialogScript()}\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: 'Users',\n pageTitle: 'User Management',\n currentPath: '/admin/users',\n user: data.user,\n version: data.version,\n content: pageContent\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n} ","import { Hono } from 'hono'\nimport type { D1Database, KVNamespace, R2Bucket, Queue } from '@cloudflare/workers-types'\nimport { requireAuth, requirePermission, logActivity, AuthManager } from '../middleware'\nimport { sanitizeInput } from '../utils/sanitize'\nimport { renderProfilePage, type UserProfile, type ProfilePageData } from '../templates/pages/admin-profile.template'\nimport { renderAlert } from '../templates/components/alert.template'\nimport { renderActivityLogsPage, type ActivityLogsPageData, type ActivityLog } from '../templates/pages/admin-activity-logs.template'\nimport { renderUserEditPage, type UserEditPageData, type UserEditData } from '../templates/pages/admin-user-edit.template'\nimport { renderUserNewPage, type UserNewPageData } from '../templates/pages/admin-user-new.template'\nimport { renderUsersListPage, type UsersListPageData, type User } from '../templates/pages/admin-users-list.template'\nimport type { Bindings, Variables } from '../app'\n\nconst userRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Apply authentication middleware to all routes\nuserRoutes.use('*', requireAuth())\n\n// Timezone options for profile form\nconst TIMEZONES = [\n { value: 'UTC', label: 'UTC' },\n { value: 'America/New_York', label: 'Eastern Time' },\n { value: 'America/Chicago', label: 'Central Time' },\n { value: 'America/Denver', label: 'Mountain Time' },\n { value: 'America/Los_Angeles', label: 'Pacific Time' },\n { value: 'Europe/London', label: 'London' },\n { value: 'Europe/Paris', label: 'Paris' },\n { value: 'Europe/Berlin', label: 'Berlin' },\n { value: 'Asia/Tokyo', label: 'Tokyo' },\n { value: 'Asia/Shanghai', label: 'Shanghai' },\n { value: 'Australia/Sydney', label: 'Sydney' }\n]\n\n// Language options for profile form\nconst LANGUAGES = [\n { value: 'en', label: 'English' },\n { value: 'es', label: 'Spanish' },\n { value: 'fr', label: 'French' },\n { value: 'de', label: 'German' },\n { value: 'it', label: 'Italian' },\n { value: 'pt', label: 'Portuguese' },\n { value: 'ja', label: 'Japanese' },\n { value: 'ko', label: 'Korean' },\n { value: 'zh', label: 'Chinese' }\n]\n\n// Role options for user form\nconst ROLES = [\n { value: 'admin', label: 'Administrator' },\n { value: 'editor', label: 'Editor' },\n { value: 'author', label: 'Author' },\n { value: 'viewer', label: 'Viewer' }\n]\n\n/**\n * GET /admin/profile - Show user profile page\n */\nuserRoutes.get('/profile', async (c) => {\n const user = c.get('user')\n const db = c.env.DB\n\n try {\n // Get user profile data\n const userStmt = db.prepare(`\n SELECT id, email, username, first_name, last_name, phone, bio, avatar_url,\n timezone, language, theme, email_notifications, two_factor_enabled,\n role, created_at, last_login_at\n FROM users \n WHERE id = ? AND is_active = 1\n `)\n \n const userProfile = await userStmt.bind(user!.userId).first() as any\n\n if (!userProfile) {\n return c.json({ error: 'User not found' }, 404)\n }\n\n // Convert to UserProfile interface\n const profile: UserProfile = {\n id: userProfile.id,\n email: userProfile.email,\n username: userProfile.username || '',\n first_name: userProfile.first_name || '',\n last_name: userProfile.last_name || '',\n phone: userProfile.phone,\n bio: userProfile.bio,\n avatar_url: userProfile.avatar_url,\n timezone: userProfile.timezone || 'UTC',\n language: userProfile.language || 'en',\n theme: userProfile.theme || 'dark',\n email_notifications: Boolean(userProfile.email_notifications),\n two_factor_enabled: Boolean(userProfile.two_factor_enabled),\n role: userProfile.role,\n created_at: userProfile.created_at,\n last_login_at: userProfile.last_login_at\n }\n\n const pageData: ProfilePageData = {\n profile,\n timezones: TIMEZONES,\n languages: LANGUAGES,\n user: {\n name: `${profile.first_name} ${profile.last_name}`.trim() || profile.username || user!.email,\n email: user!.email,\n role: user!.role\n }\n }\n\n return c.html(renderProfilePage(pageData))\n } catch (error) {\n console.error('Profile page error:', error)\n \n const pageData: ProfilePageData = {\n profile: {} as UserProfile,\n timezones: TIMEZONES,\n languages: LANGUAGES,\n error: 'Failed to load profile. Please try again.',\n user: {\n name: user!.email,\n email: user!.email,\n role: user!.role\n }\n }\n\n return c.html(renderProfilePage(pageData))\n }\n})\n\n/**\n * PUT /admin/profile - Update user profile\n */\nuserRoutes.put('/profile', async (c) => {\n const user = c.get('user')\n const db = c.env.DB\n\n try {\n const formData = await c.req.formData()\n\n // Sanitize all user inputs to prevent XSS attacks\n const firstName = sanitizeInput(formData.get('first_name')?.toString())\n const lastName = sanitizeInput(formData.get('last_name')?.toString())\n const username = sanitizeInput(formData.get('username')?.toString())\n const email = formData.get('email')?.toString()?.trim().toLowerCase() || ''\n const phone = sanitizeInput(formData.get('phone')?.toString()) || null\n const bio = sanitizeInput(formData.get('bio')?.toString()) || null\n const timezone = formData.get('timezone')?.toString() || 'UTC'\n const language = formData.get('language')?.toString() || 'en'\n const emailNotifications = formData.get('email_notifications') === '1'\n\n // Validate required fields\n if (!firstName || !lastName || !username || !email) {\n return c.html(renderAlert({\n type: 'error',\n message: 'First name, last name, username, and email are required.',\n dismissible: true\n }))\n }\n\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n if (!emailRegex.test(email)) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'Please enter a valid email address.',\n dismissible: true \n }))\n }\n\n // Check if username/email are taken by another user\n const checkStmt = db.prepare(`\n SELECT id FROM users \n WHERE (username = ? OR email = ?) AND id != ? AND is_active = 1\n `)\n const existingUser = await checkStmt.bind(username, email, user!.userId).first()\n\n if (existingUser) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'Username or email is already taken by another user!.',\n dismissible: true \n }))\n }\n\n // Update user profile\n const updateStmt = db.prepare(`\n UPDATE users SET \n first_name = ?, last_name = ?, username = ?, email = ?,\n phone = ?, bio = ?, timezone = ?, language = ?,\n email_notifications = ?, updated_at = ?\n WHERE id = ?\n `)\n\n await updateStmt.bind(\n firstName, lastName, username, email,\n phone, bio, timezone, language,\n emailNotifications ? 1 : 0, Date.now(),\n user!.userId\n ).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'profile.update', 'users', user!.userId,\n { fields: ['first_name', 'last_name', 'username', 'email', 'phone', 'bio', 'timezone', 'language', 'email_notifications'] },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.html(renderAlert({ \n type: 'success', \n message: 'Profile updated successfully!',\n dismissible: true \n }))\n\n } catch (error) {\n console.error('Profile update error:', error)\n return c.html(renderAlert({ \n type: 'error', \n message: 'Failed to update profile. Please try again.',\n dismissible: true \n }))\n }\n})\n\n/**\n * POST /admin/profile/avatar - Upload user avatar\n */\nuserRoutes.post('/profile/avatar', async (c) => {\n const user = c.get('user')\n const db = c.env.DB\n\n try {\n const formData = await c.req.formData()\n const avatarFile = formData.get('avatar') as File\n\n if (!avatarFile || !avatarFile.name) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'Please select an image file.',\n dismissible: true \n }))\n }\n\n // Validate file type\n const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']\n if (!allowedTypes.includes(avatarFile.type)) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'Please upload a valid image file (JPEG, PNG, GIF, or WebP).',\n dismissible: true \n }))\n }\n\n // Validate file size (5MB max)\n const maxSize = 5 * 1024 * 1024\n if (avatarFile.size > maxSize) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'Image file must be smaller than 5MB.',\n dismissible: true \n }))\n }\n\n // For now, we'll simulate storing the avatar\n // In a real implementation, you'd upload to cloud storage (R2, S3, etc.)\n const avatarUrl = `/uploads/avatars/${user!.userId}-${Date.now()}.${avatarFile.type.split('/')[1]}`\n\n // Update user avatar URL in database\n const updateStmt = db.prepare(`\n UPDATE users SET avatar_url = ?, updated_at = ?\n WHERE id = ?\n `)\n\n await updateStmt.bind(avatarUrl, Date.now(), user!.userId).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'profile.avatar_update', 'users', user!.userId,\n { avatar_url: avatarUrl },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.html(renderAlert({ \n type: 'success', \n message: 'Profile picture updated successfully!',\n dismissible: true \n }))\n\n } catch (error) {\n console.error('Avatar upload error:', error)\n return c.html(renderAlert({ \n type: 'error', \n message: 'Failed to upload profile picture. Please try again.',\n dismissible: true \n }))\n }\n})\n\n/**\n * POST /admin/profile/password - Change user password\n */\nuserRoutes.post('/profile/password', async (c) => {\n const user = c.get('user')\n const db = c.env.DB\n\n try {\n const formData = await c.req.formData()\n \n const currentPassword = formData.get('current_password')?.toString() || ''\n const newPassword = formData.get('new_password')?.toString() || ''\n const confirmPassword = formData.get('confirm_password')?.toString() || ''\n\n // Validate input\n if (!currentPassword || !newPassword || !confirmPassword) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'All password fields are required.',\n dismissible: true \n }))\n }\n\n if (newPassword !== confirmPassword) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'New passwords do not match.',\n dismissible: true \n }))\n }\n\n if (newPassword.length < 8) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'New password must be at least 8 characters long.',\n dismissible: true \n }))\n }\n\n // Get current user data\n const userStmt = db.prepare(`\n SELECT password_hash FROM users WHERE id = ? AND is_active = 1\n `)\n const userData = await userStmt.bind(user!.userId).first() as any\n\n if (!userData) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'User not found.',\n dismissible: true \n }))\n }\n\n // Verify current password\n const validPassword = await AuthManager.verifyPassword(currentPassword, userData.password_hash)\n if (!validPassword) {\n return c.html(renderAlert({ \n type: 'error', \n message: 'Current password is incorrect.',\n dismissible: true \n }))\n }\n\n // Hash new password\n const newPasswordHash = await AuthManager.hashPassword(newPassword)\n\n // Store old password in history\n const historyStmt = db.prepare(`\n INSERT INTO password_history (id, user_id, password_hash, created_at)\n VALUES (?, ?, ?, ?)\n `)\n await historyStmt.bind(\n globalThis.crypto.randomUUID(),\n user!.userId,\n userData.password_hash,\n Date.now()\n ).run()\n\n // Update user password\n const updateStmt = db.prepare(`\n UPDATE users SET password_hash = ?, updated_at = ?\n WHERE id = ?\n `)\n await updateStmt.bind(newPasswordHash, Date.now(), user!.userId).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'profile.password_change', 'users', user!.userId,\n null,\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.html(renderAlert({ \n type: 'success', \n message: 'Password updated successfully!',\n dismissible: true \n }))\n\n } catch (error) {\n console.error('Password change error:', error)\n return c.html(renderAlert({ \n type: 'error', \n message: 'Failed to update password. Please try again.',\n dismissible: true \n }))\n }\n})\n\n/**\n * GET /admin/users - List all users (requires users.read permission)\n * Returns HTML for browser requests and JSON for API requests\n */\nuserRoutes.get('/users', requirePermission('users.read'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n\n try {\n // Get pagination parameters\n const page = parseInt(c.req.query('page') || '1')\n const limit = parseInt(c.req.query('limit') || '20')\n const search = c.req.query('search') || ''\n const roleFilter = c.req.query('role') || ''\n const statusFilter = c.req.query('status') || 'active'\n const offset = (page - 1) * limit\n\n // Build search query\n let whereClause = ''\n let params: any[] = []\n\n // Handle status filter\n if (statusFilter === 'active') {\n whereClause = 'WHERE u.is_active = 1'\n } else if (statusFilter === 'inactive') {\n whereClause = 'WHERE u.is_active = 0'\n } else {\n // 'all' - no filter\n whereClause = 'WHERE 1=1'\n }\n\n if (search) {\n whereClause += ' AND (u.first_name LIKE ? OR u.last_name LIKE ? OR u.email LIKE ? OR u.username LIKE ?)'\n const searchParam = `%${search}%`\n params.push(searchParam, searchParam, searchParam, searchParam)\n }\n\n if (roleFilter) {\n whereClause += ' AND u.role = ?'\n params.push(roleFilter)\n }\n\n // Get users\n const usersStmt = db.prepare(`\n SELECT u.id, u.email, u.username, u.first_name, u.last_name,\n u.role, u.avatar_url, u.created_at, u.last_login_at, u.updated_at,\n u.email_verified, u.two_factor_enabled, u.is_active\n FROM users u\n ${whereClause}\n ORDER BY u.created_at DESC\n LIMIT ? OFFSET ?\n `)\n\n const { results: usersData } = await usersStmt.bind(...params, limit, offset).all()\n\n // Get total count\n const countStmt = db.prepare(`\n SELECT COUNT(*) as total FROM users u ${whereClause}\n `)\n const countResult = await countStmt.bind(...params).first() as any\n const totalUsers = countResult?.total || 0\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'users.list_view', 'users', undefined,\n { search, page, limit },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n // Check if this is an API request (accept header contains 'application/json')\n const acceptHeader = c.req.header('accept') || ''\n const isApiRequest = acceptHeader.includes('application/json')\n\n if (isApiRequest) {\n // Return JSON for API requests\n return c.json({\n users: usersData || [],\n pagination: {\n page,\n limit,\n total: totalUsers,\n pages: Math.ceil(totalUsers / limit)\n }\n })\n }\n\n // Return HTML for browser requests\n const users: User[] = (usersData || []).map((u: any) => ({\n id: u.id,\n email: u.email,\n username: u.username || '',\n firstName: u.first_name || '',\n lastName: u.last_name || '',\n role: u.role,\n avatar: u.avatar_url,\n isActive: Boolean(u.is_active),\n lastLoginAt: u.last_login_at,\n createdAt: u.created_at,\n updatedAt: u.updated_at,\n formattedLastLogin: u.last_login_at ? new Date(u.last_login_at).toLocaleDateString() : undefined,\n formattedCreatedAt: new Date(u.created_at).toLocaleDateString()\n }))\n\n const pageData: UsersListPageData = {\n users,\n currentPage: page,\n totalPages: Math.ceil(totalUsers / limit),\n totalUsers,\n searchFilter: search,\n roleFilter,\n statusFilter,\n pagination: {\n currentPage: page,\n totalPages: Math.ceil(totalUsers / limit),\n totalItems: totalUsers,\n itemsPerPage: limit,\n startItem: offset + 1,\n endItem: Math.min(offset + limit, totalUsers),\n baseUrl: '/admin/users'\n },\n user: {\n name: user!.email.split('@')[0] || user!.email,\n email: user!.email,\n role: user!.role\n }\n }\n\n return c.html(renderUsersListPage(pageData))\n\n } catch (error) {\n console.error('Users list error:', error)\n\n const acceptHeader = c.req.header('accept') || ''\n const isApiRequest = acceptHeader.includes('application/json')\n\n if (isApiRequest) {\n return c.json({ error: 'Failed to load users' }, 500)\n }\n\n return c.html(renderAlert({\n type: 'error',\n message: 'Failed to load users. Please try again.',\n dismissible: true\n }), 500)\n }\n})\n\n/**\n * GET /admin/users/new - Show new user creation page (requires users.create permission)\n */\nuserRoutes.get('/users/new', requirePermission('users.create'), async (c) => {\n const user = c.get('user')\n\n try {\n const pageData: UserNewPageData = {\n roles: ROLES,\n user: {\n name: user!.email.split('@')[0] || user!.email,\n email: user!.email,\n role: user!.role\n }\n }\n\n return c.html(renderUserNewPage(pageData))\n } catch (error) {\n console.error('User new page error:', error)\n\n return c.html(renderAlert({\n type: 'error',\n message: 'Failed to load user creation page. Please try again.',\n dismissible: true\n }), 500)\n }\n})\n\n/**\n * POST /admin/users/new - Create new user (requires users.create permission)\n */\nuserRoutes.post('/users/new', requirePermission('users.create'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n\n try {\n const formData = await c.req.formData()\n\n // Sanitize all user inputs to prevent XSS attacks\n const firstName = sanitizeInput(formData.get('first_name')?.toString())\n const lastName = sanitizeInput(formData.get('last_name')?.toString())\n const username = sanitizeInput(formData.get('username')?.toString())\n const email = formData.get('email')?.toString()?.trim().toLowerCase() || ''\n const phone = sanitizeInput(formData.get('phone')?.toString()) || null\n const bio = sanitizeInput(formData.get('bio')?.toString()) || null\n const role = formData.get('role')?.toString() || 'viewer'\n const password = formData.get('password')?.toString() || ''\n const confirmPassword = formData.get('confirm_password')?.toString() || ''\n const isActive = formData.get('is_active') === '1'\n const emailVerified = formData.get('email_verified') === '1'\n\n // Validate required fields\n if (!firstName || !lastName || !username || !email || !password) {\n return c.html(renderAlert({\n type: 'error',\n message: 'First name, last name, username, email, and password are required.',\n dismissible: true\n }))\n }\n\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n if (!emailRegex.test(email)) {\n return c.html(renderAlert({\n type: 'error',\n message: 'Please enter a valid email address.',\n dismissible: true\n }))\n }\n\n // Validate password\n if (password.length < 8) {\n return c.html(renderAlert({\n type: 'error',\n message: 'Password must be at least 8 characters long.',\n dismissible: true\n }))\n }\n\n if (password !== confirmPassword) {\n return c.html(renderAlert({\n type: 'error',\n message: 'Passwords do not match.',\n dismissible: true\n }))\n }\n\n // Check if username/email are already taken\n const checkStmt = db.prepare(`\n SELECT id FROM users\n WHERE username = ? OR email = ?\n `)\n const existingUser = await checkStmt.bind(username, email).first()\n\n if (existingUser) {\n return c.html(renderAlert({\n type: 'error',\n message: 'Username or email is already taken.',\n dismissible: true\n }))\n }\n\n // Hash password\n const passwordHash = await AuthManager.hashPassword(password)\n\n // Create user\n const userId = globalThis.crypto.randomUUID()\n const createStmt = db.prepare(`\n INSERT INTO users (\n id, email, username, first_name, last_name, phone, bio,\n password_hash, role, is_active, email_verified, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n\n await createStmt.bind(\n userId, email, username, firstName, lastName, phone, bio,\n passwordHash, role, isActive ? 1 : 0, emailVerified ? 1 : 0,\n Date.now(), Date.now()\n ).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.create', 'users', userId,\n { email, username, role },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n // Redirect to user edit page\n return c.redirect(`/admin/users/${userId}/edit?success=User created successfully`)\n\n } catch (error) {\n console.error('User creation error:', error)\n return c.html(renderAlert({\n type: 'error',\n message: 'Failed to create user!. Please try again.',\n dismissible: true\n }))\n }\n})\n\n/**\n * GET /admin/users/:id - Get user by ID (requires users.read permission)\n * Note: This endpoint returns users regardless of is_active status for admin purposes\n */\nuserRoutes.get('/users/:id', requirePermission('users.read'), async (c) => {\n // Check if this is actually the edit route\n if (c.req.path.endsWith('/edit')) {\n return c.notFound()\n }\n\n const db = c.env.DB\n const user = c.get('user')\n const userId = c.req.param('id')\n\n try {\n // Get user data (including inactive users for admin access)\n const userStmt = db.prepare(`\n SELECT id, email, username, first_name, last_name, phone, bio, avatar_url,\n role, is_active, email_verified, two_factor_enabled, created_at, last_login_at\n FROM users\n WHERE id = ?\n `)\n\n const userRecord = await userStmt.bind(userId).first() as any\n\n if (!userRecord) {\n return c.json({ error: 'User not found' }, 404)\n }\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.view', 'users', userId,\n null,\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.json({\n user: {\n id: userRecord.id,\n email: userRecord.email,\n username: userRecord.username,\n first_name: userRecord.first_name,\n last_name: userRecord.last_name,\n phone: userRecord.phone,\n bio: userRecord.bio,\n avatar_url: userRecord.avatar_url,\n role: userRecord.role,\n is_active: userRecord.is_active,\n email_verified: userRecord.email_verified,\n two_factor_enabled: userRecord.two_factor_enabled,\n created_at: userRecord.created_at,\n last_login_at: userRecord.last_login_at\n }\n })\n\n } catch (error) {\n console.error('User fetch error:', error)\n return c.json({ error: 'Failed to fetch user' }, 500)\n }\n})\n\n/**\n * GET /admin/users/:id/edit - Show user edit page (requires users.update permission)\n */\nuserRoutes.get('/users/:id/edit', requirePermission('users.update'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n const userId = c.req.param('id')\n\n try {\n // Get user data\n const userStmt = db.prepare(`\n SELECT id, email, username, first_name, last_name, phone, bio, avatar_url,\n role, is_active, email_verified, two_factor_enabled, created_at, last_login_at\n FROM users\n WHERE id = ?\n `)\n\n const userToEdit = await userStmt.bind(userId).first() as any\n\n if (!userToEdit) {\n return c.html(renderAlert({\n type: 'error',\n message: 'User not found',\n dismissible: true\n }), 404)\n }\n\n // Convert to UserEditData interface\n const editData: UserEditData = {\n id: userToEdit.id,\n email: userToEdit.email,\n username: userToEdit.username || '',\n firstName: userToEdit.first_name || '',\n lastName: userToEdit.last_name || '',\n phone: userToEdit.phone,\n bio: userToEdit.bio,\n avatarUrl: userToEdit.avatar_url,\n role: userToEdit.role,\n isActive: Boolean(userToEdit.is_active),\n emailVerified: Boolean(userToEdit.email_verified),\n twoFactorEnabled: Boolean(userToEdit.two_factor_enabled),\n createdAt: userToEdit.created_at,\n lastLoginAt: userToEdit.last_login_at\n }\n\n const pageData: UserEditPageData = {\n userToEdit: editData,\n roles: ROLES,\n user: {\n name: user!.email.split('@')[0] || user!.email,\n email: user!.email,\n role: user!.role\n }\n }\n\n return c.html(renderUserEditPage(pageData))\n } catch (error) {\n console.error('User edit page error:', error)\n\n return c.html(renderAlert({\n type: 'error',\n message: 'Failed to load user!. Please try again.',\n dismissible: true\n }), 500)\n }\n})\n\n/**\n * PUT /admin/users/:id - Update user (requires users.update permission)\n */\nuserRoutes.put('/users/:id', requirePermission('users.update'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n const userId = c.req.param('id')\n\n try {\n const formData = await c.req.formData()\n\n // Sanitize all user inputs to prevent XSS attacks\n const firstName = sanitizeInput(formData.get('first_name')?.toString())\n const lastName = sanitizeInput(formData.get('last_name')?.toString())\n const username = sanitizeInput(formData.get('username')?.toString())\n const email = formData.get('email')?.toString()?.trim().toLowerCase() || ''\n const phone = sanitizeInput(formData.get('phone')?.toString()) || null\n const bio = sanitizeInput(formData.get('bio')?.toString()) || null\n const role = formData.get('role')?.toString() || 'viewer'\n const isActive = formData.get('is_active') === '1'\n const emailVerified = formData.get('email_verified') === '1'\n\n // Validate required fields\n if (!firstName || !lastName || !username || !email) {\n return c.html(renderAlert({\n type: 'error',\n message: 'First name, last name, username, and email are required.',\n dismissible: true\n }))\n }\n\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n if (!emailRegex.test(email)) {\n return c.html(renderAlert({\n type: 'error',\n message: 'Please enter a valid email address.',\n dismissible: true\n }))\n }\n\n // Check if username/email are taken by another user\n const checkStmt = db.prepare(`\n SELECT id FROM users\n WHERE (username = ? OR email = ?) AND id != ?\n `)\n const existingUser = await checkStmt.bind(username, email, userId).first()\n\n if (existingUser) {\n return c.html(renderAlert({\n type: 'error',\n message: 'Username or email is already taken by another user!.',\n dismissible: true\n }))\n }\n\n // Update user\n const updateStmt = db.prepare(`\n UPDATE users SET\n first_name = ?, last_name = ?, username = ?, email = ?,\n phone = ?, bio = ?, role = ?, is_active = ?, email_verified = ?,\n updated_at = ?\n WHERE id = ?\n `)\n\n await updateStmt.bind(\n firstName, lastName, username, email,\n phone, bio, role, isActive ? 1 : 0, emailVerified ? 1 : 0,\n Date.now(), userId\n ).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.update', 'users', userId,\n { fields: ['first_name', 'last_name', 'username', 'email', 'phone', 'bio', 'role', 'is_active', 'email_verified'] },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.html(renderAlert({\n type: 'success',\n message: 'User updated successfully!',\n dismissible: true\n }))\n\n } catch (error) {\n console.error('User update error:', error)\n return c.html(renderAlert({\n type: 'error',\n message: 'Failed to update user!. Please try again.',\n dismissible: true\n }))\n }\n})\n\n/**\n * DELETE /admin/users/:id - Delete user (requires users.delete permission)\n */\nuserRoutes.delete('/users/:id', requirePermission('users.delete'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n const userId = c.req.param('id')\n\n try {\n // Get request body to check for hard delete option\n const body = await c.req.json().catch(() => ({ hardDelete: false }))\n const hardDelete = body.hardDelete === true\n\n // Prevent self-deletion\n if (userId === user!.userId) {\n return c.json({ error: 'You cannot delete your own account' }, 400)\n }\n\n // Check if user exists\n const userStmt = db.prepare(`\n SELECT id, email FROM users WHERE id = ?\n `)\n const userToDelete = await userStmt.bind(userId).first() as any\n\n if (!userToDelete) {\n return c.json({ error: 'User not found' }, 404)\n }\n\n if (hardDelete) {\n // Hard delete - permanently remove from database\n const deleteStmt = db.prepare(`\n DELETE FROM users WHERE id = ?\n `)\n await deleteStmt.bind(userId).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.hard_delete', 'users', userId,\n { email: userToDelete.email, permanent: true },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.json({\n success: true,\n message: 'User permanently deleted'\n })\n } else {\n // Soft delete - deactivate by setting is_active = 0\n const deleteStmt = db.prepare(`\n UPDATE users SET is_active = 0, updated_at = ? WHERE id = ?\n `)\n await deleteStmt.bind(Date.now(), userId).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.soft_delete', 'users', userId,\n { email: userToDelete.email },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.json({\n success: true,\n message: 'User deactivated successfully'\n })\n }\n\n } catch (error) {\n console.error('User deletion error:', error)\n return c.json({ error: 'Failed to delete user' }, 500)\n }\n})\n\n/**\n * POST /admin/invite-user - Invite a new user (requires users.create permission)\n */\nuserRoutes.post('/invite-user', requirePermission('users.create'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n\n try {\n const formData = await c.req.formData()\n\n // Sanitize all user inputs to prevent XSS attacks\n const email = formData.get('email')?.toString()?.trim().toLowerCase() || ''\n const role = formData.get('role')?.toString()?.trim() || 'viewer'\n const firstName = sanitizeInput(formData.get('first_name')?.toString())\n const lastName = sanitizeInput(formData.get('last_name')?.toString())\n\n // Validate input\n if (!email || !firstName || !lastName) {\n return c.json({ error: 'Email, first name, and last name are required' }, 400)\n }\n\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n if (!emailRegex.test(email)) {\n return c.json({ error: 'Please enter a valid email address' }, 400)\n }\n\n // Check if user already exists\n const existingUserStmt = db.prepare(`\n SELECT id FROM users WHERE email = ?\n `)\n const existingUser = await existingUserStmt.bind(email).first()\n\n if (existingUser) {\n return c.json({ error: 'A user with this email already exists' }, 400)\n }\n\n // Generate invitation token\n const invitationToken = globalThis.crypto.randomUUID()\n const invitationExpires = Date.now() + (7 * 24 * 60 * 60 * 1000) // 7 days\n\n // Create user record with invitation\n const userId = globalThis.crypto.randomUUID()\n const createUserStmt = db.prepare(`\n INSERT INTO users (\n id, email, first_name, last_name, role, \n invitation_token, invited_by, invited_at,\n is_active, email_verified, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n\n await createUserStmt.bind(\n userId, email, firstName, lastName, role,\n invitationToken, user!.userId, Date.now(),\n 0, 0, Date.now(), Date.now()\n ).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.invite_sent', 'users', userId,\n { email, role, invited_user_id: userId },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n // In a real implementation, you would send an email here\n // For now, we'll return the invitation link\n const invitationLink = `${c.req.header('origin') || 'http://localhost:8787'}/auth/accept-invitation?token=${invitationToken}`\n\n return c.json({\n success: true,\n message: 'User invitation sent successfully',\n user: {\n id: userId,\n email,\n first_name: firstName,\n last_name: lastName,\n role\n },\n invitation_link: invitationLink // In production, this would be sent via email\n })\n\n } catch (error) {\n console.error('User invitation error:', error)\n return c.json({ error: 'Failed to send user invitation' }, 500)\n }\n})\n\n/**\n * POST /admin/resend-invitation/:id - Resend invitation (requires users.create permission)\n */\nuserRoutes.post('/resend-invitation/:id', requirePermission('users.create'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n const userId = c.req.param('id')\n\n try {\n // Check if user exists and is invited but not active\n const userStmt = db.prepare(`\n SELECT id, email, first_name, last_name, role, invitation_token\n FROM users \n WHERE id = ? AND is_active = 0 AND invitation_token IS NOT NULL\n `)\n const invitedUser = await userStmt.bind(userId).first() as any\n\n if (!invitedUser) {\n return c.json({ error: 'User not found or invitation not valid' }, 404)\n }\n\n // Generate new invitation token\n const newInvitationToken = globalThis.crypto.randomUUID()\n\n // Update invitation token and date\n const updateStmt = db.prepare(`\n UPDATE users SET \n invitation_token = ?, \n invited_at = ?, \n updated_at = ?\n WHERE id = ?\n `)\n\n await updateStmt.bind(\n newInvitationToken,\n Date.now(),\n Date.now(),\n userId\n ).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.invitation_resent', 'users', userId,\n { email: invitedUser.email },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n // Generate new invitation link\n const invitationLink = `${c.req.header('origin') || 'http://localhost:8787'}/auth/accept-invitation?token=${newInvitationToken}`\n\n return c.json({\n success: true,\n message: 'Invitation resent successfully',\n invitation_link: invitationLink\n })\n\n } catch (error) {\n console.error('Resend invitation error:', error)\n return c.json({ error: 'Failed to resend invitation' }, 500)\n }\n})\n\n/**\n * DELETE /admin/cancel-invitation/:id - Cancel invitation (requires users.delete permission)\n */\nuserRoutes.delete('/cancel-invitation/:id', requirePermission('users.delete'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n const userId = c.req.param('id')\n\n try {\n // Check if user exists and is invited but not active\n const userStmt = db.prepare(`\n SELECT id, email FROM users \n WHERE id = ? AND is_active = 0 AND invitation_token IS NOT NULL\n `)\n const invitedUser = await userStmt.bind(userId).first() as any\n\n if (!invitedUser) {\n return c.json({ error: 'User not found or invitation not valid' }, 404)\n }\n\n // Delete the user record (since they haven't activated yet)\n const deleteStmt = db.prepare(`DELETE FROM users WHERE id = ?`)\n await deleteStmt.bind(userId).run()\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'user!.invitation_cancelled', 'users', userId,\n { email: invitedUser.email },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n return c.json({\n success: true,\n message: 'Invitation cancelled successfully'\n })\n\n } catch (error) {\n console.error('Cancel invitation error:', error)\n return c.json({ error: 'Failed to cancel invitation' }, 500)\n }\n})\n\n/**\n * GET /admin/activity-logs - View activity logs (requires activity.read permission)\n */\nuserRoutes.get('/activity-logs', requirePermission('activity.read'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n\n try {\n // Get pagination and filter parameters\n const page = parseInt(c.req.query('page') || '1')\n const limit = parseInt(c.req.query('limit') || '50')\n const offset = (page - 1) * limit\n\n const filters = {\n action: c.req.query('action') || '',\n resource_type: c.req.query('resource_type') || '',\n date_from: c.req.query('date_from') || '',\n date_to: c.req.query('date_to') || '',\n user_id: c.req.query('user_id') || ''\n }\n\n // Build where clause\n let whereConditions: string[] = []\n let params: any[] = []\n\n if (filters.action) {\n whereConditions.push('al.action = ?')\n params.push(filters.action)\n }\n\n if (filters.resource_type) {\n whereConditions.push('al.resource_type = ?')\n params.push(filters.resource_type)\n }\n\n if (filters.user_id) {\n whereConditions.push('al.user_id = ?')\n params.push(filters.user_id)\n }\n\n if (filters.date_from) {\n const fromTimestamp = new Date(filters.date_from).getTime()\n whereConditions.push('al.created_at >= ?')\n params.push(fromTimestamp)\n }\n\n if (filters.date_to) {\n const toTimestamp = new Date(filters.date_to + ' 23:59:59').getTime()\n whereConditions.push('al.created_at <= ?')\n params.push(toTimestamp)\n }\n\n const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(' AND ')}` : ''\n\n // Get activity logs with user information\n const logsStmt = db.prepare(`\n SELECT \n al.id, al.user_id, al.action, al.resource_type, al.resource_id,\n al.details, al.ip_address, al.user_agent, al.created_at,\n u.email as user_email,\n COALESCE(u.first_name || ' ' || u.last_name, u.username, u.email) as user_name\n FROM activity_logs al\n LEFT JOIN users u ON al.user_id = u.id\n ${whereClause}\n ORDER BY al.created_at DESC\n LIMIT ? OFFSET ?\n `)\n\n const { results: logs } = await logsStmt.bind(...params, limit, offset).all()\n\n // Get total count for pagination\n const countStmt = db.prepare(`\n SELECT COUNT(*) as total \n FROM activity_logs al\n LEFT JOIN users u ON al.user_id = u.id\n ${whereClause}\n `)\n const countResult = await countStmt.bind(...params).first() as any\n const totalLogs = countResult?.total || 0\n\n // Parse details JSON for each log\n const formattedLogs: ActivityLog[] = (logs || []).map((log: any) => ({\n ...log,\n details: log.details ? JSON.parse(log.details) : null\n }))\n\n // Log the activity\n await logActivity(\n db, user!.userId, 'activity.logs_viewed', undefined, undefined,\n { filters, page, limit },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n const pageData: ActivityLogsPageData = {\n logs: formattedLogs,\n pagination: {\n page,\n limit,\n total: totalLogs,\n pages: Math.ceil(totalLogs / limit)\n },\n filters,\n user: {\n name: user!.email.split('@')[0] || user!.email, // Use email username as fallback\n email: user!.email,\n role: user!.role\n }\n }\n\n return c.html(renderActivityLogsPage(pageData))\n\n } catch (error) {\n console.error('Activity logs error:', error)\n \n const pageData: ActivityLogsPageData = {\n logs: [],\n pagination: { page: 1, limit: 50, total: 0, pages: 0 },\n filters: {},\n user: {\n name: user!.email,\n email: user!.email,\n role: user!.role\n }\n }\n\n return c.html(renderActivityLogsPage(pageData))\n }\n})\n\n/**\n * GET /admin/activity-logs/export - Export activity logs to CSV (requires activity.read permission)\n */\nuserRoutes.get('/activity-logs/export', requirePermission('activity.read'), async (c) => {\n const db = c.env.DB\n const user = c.get('user')\n\n try {\n // Get filter parameters (same as list view)\n const filters = {\n action: c.req.query('action') || '',\n resource_type: c.req.query('resource_type') || '',\n date_from: c.req.query('date_from') || '',\n date_to: c.req.query('date_to') || '',\n user_id: c.req.query('user_id') || ''\n }\n\n // Build where clause\n let whereConditions: string[] = []\n let params: any[] = []\n\n if (filters.action) {\n whereConditions.push('al.action = ?')\n params.push(filters.action)\n }\n\n if (filters.resource_type) {\n whereConditions.push('al.resource_type = ?')\n params.push(filters.resource_type)\n }\n\n if (filters.user_id) {\n whereConditions.push('al.user_id = ?')\n params.push(filters.user_id)\n }\n\n if (filters.date_from) {\n const fromTimestamp = new Date(filters.date_from).getTime()\n whereConditions.push('al.created_at >= ?')\n params.push(fromTimestamp)\n }\n\n if (filters.date_to) {\n const toTimestamp = new Date(filters.date_to + ' 23:59:59').getTime()\n whereConditions.push('al.created_at <= ?')\n params.push(toTimestamp)\n }\n\n const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(' AND ')}` : ''\n\n // Get all matching activity logs (limit to 10,000 for performance)\n const logsStmt = db.prepare(`\n SELECT \n al.id, al.user_id, al.action, al.resource_type, al.resource_id,\n al.details, al.ip_address, al.user_agent, al.created_at,\n u.email as user_email,\n COALESCE(u.first_name || ' ' || u.last_name, u.username, u.email) as user_name\n FROM activity_logs al\n LEFT JOIN users u ON al.user_id = u.id\n ${whereClause}\n ORDER BY al.created_at DESC\n LIMIT 10000\n `)\n\n const { results: logs } = await logsStmt.bind(...params).all()\n\n // Generate CSV content\n const csvHeaders = ['Timestamp', 'User', 'Email', 'Action', 'Resource Type', 'Resource ID', 'IP Address', 'Details']\n const csvRows = [csvHeaders.join(',')]\n\n for (const log of (logs || [])) {\n const row = [\n `\"${new Date((log as any).created_at).toISOString()}\"`,\n `\"${(log as any).user_name || 'Unknown'}\"`,\n `\"${(log as any).user_email || 'N/A'}\"`,\n `\"${(log as any).action}\"`,\n `\"${(log as any).resource_type || 'N/A'}\"`,\n `\"${(log as any).resource_id || 'N/A'}\"`,\n `\"${(log as any).ip_address || 'N/A'}\"`,\n `\"${(log as any).details ? JSON.stringify(JSON.parse((log as any).details)) : 'N/A'}\"`\n ]\n csvRows.push(row.join(','))\n }\n\n const csvContent = csvRows.join('\\n')\n\n // Log the export activity\n await logActivity(\n db, user!.userId, 'activity.logs_exported', undefined, undefined,\n { filters, count: logs?.length || 0 },\n c.req.header('x-forwarded-for') || c.req.header('cf-connecting-ip'),\n c.req.header('user-agent')\n )\n\n // Return CSV file\n const filename = `activity-logs-${new Date().toISOString().split('T')[0]}.csv`\n \n return new Response(csvContent, {\n headers: {\n 'Content-Type': 'text/csv',\n 'Content-Disposition': `attachment; filename=\"${filename}\"`\n }\n })\n\n } catch (error) {\n console.error('Activity logs export error:', error)\n return c.json({ error: 'Failed to export activity logs' }, 500)\n }\n})\n\nexport { userRoutes }","export interface MediaFile {\n id: string;\n filename: string;\n original_name: string;\n mime_type: string;\n size: number;\n public_url: string;\n thumbnail_url?: string;\n alt?: string;\n caption?: string;\n tags: string[];\n uploaded_at: string;\n fileSize: string;\n uploadedAt: string;\n isImage: boolean;\n isVideo: boolean;\n isDocument: boolean;\n}\n\nexport interface MediaGridData {\n files: MediaFile[];\n viewMode?: \"grid\" | \"list\";\n selectable?: boolean;\n emptyMessage?: string;\n className?: string;\n}\n\nexport function renderMediaGrid(data: MediaGridData): string {\n if (data.files.length === 0) {\n return `\n <div class=\"text-center py-12\">\n <svg class=\"mx-auto h-12 w-12 text-zinc-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n </svg>\n <h3 class=\"mt-2 text-sm font-medium text-zinc-950 dark:text-white\">No media files</h3>\n <p class=\"mt-1 text-sm text-zinc-500 dark:text-zinc-400\">${\n data.emptyMessage || \"Get started by uploading your first file.\"\n }</p>\n </div>\n `;\n }\n\n const gridClass = data.viewMode === \"list\" ? \"space-y-4\" : \"media-grid\";\n\n return `\n <div class=\"${gridClass} ${data.className || \"\"}\">\n ${data.files\n .map((file) =>\n renderMediaFileCard(file, data.viewMode, data.selectable)\n )\n .join(\"\")}\n </div>\n `;\n}\n\nexport function renderMediaFileCard(\n file: MediaFile,\n viewMode: \"grid\" | \"list\" = \"grid\",\n selectable: boolean = false\n): string {\n if (viewMode === \"list\") {\n return `\n <div class=\"media-item rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 hover:shadow-md transition-all\" data-file-id=\"${\n file.id\n }\">\n <div class=\"flex items-center p-4\">\n ${\n selectable\n ? `\n <div class=\"flex h-6 shrink-0 items-center mr-4\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input type=\"checkbox\" value=\"${file.id}\" onchange=\"toggleFileSelection('${file.id}')\" class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto media-checkbox\" />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n `\n : \"\"\n }\n\n <div class=\"flex-shrink-0 mr-4\">\n ${\n file.isImage\n ? `\n <img src=\"${file.thumbnail_url || file.public_url}\" alt=\"${\n file.alt || file.original_name\n }\"\n class=\"w-16 h-16 object-cover rounded-lg ring-1 ring-zinc-950/10 dark:ring-white/10\">\n `\n : `\n <div class=\"w-16 h-16 bg-zinc-100 dark:bg-zinc-800 rounded-lg flex items-center justify-center\">\n ${getFileIcon(file.mime_type)}\n </div>\n `\n }\n </div>\n\n <div class=\"flex-1 min-w-0\">\n <div class=\"flex items-center justify-between\">\n <h4 class=\"text-sm font-medium text-zinc-950 dark:text-white truncate\" title=\"${\n file.original_name\n }\">\n ${file.original_name}\n </h4>\n <div class=\"flex items-center space-x-2\">\n <span class=\"text-sm text-zinc-500 dark:text-zinc-400\">${\n file.fileSize\n }</span>\n <button\n class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors\"\n hx-get=\"/admin/media/${file.id}/details\"\n hx-target=\"#file-modal-content\"\n onclick=\"document.getElementById('file-modal').classList.remove('hidden')\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"></path>\n </svg>\n </button>\n </div>\n </div>\n <div class=\"mt-1 flex items-center text-sm text-zinc-500 dark:text-zinc-400\">\n <span>${file.uploadedAt}</span>\n ${\n file.tags.length > 0\n ? `\n <span class=\"mx-2\">•</span>\n <div class=\"flex items-center space-x-1\">\n ${file.tags\n .slice(0, 2)\n .map(\n (tag) => `\n <span class=\"inline-block px-2 py-1 text-xs rounded-lg bg-zinc-100 dark:bg-zinc-800 text-zinc-950 dark:text-white\">\n ${tag}\n </span>\n `\n )\n .join(\"\")}\n ${\n file.tags.length > 2\n ? `<span class=\"text-xs text-zinc-500 dark:text-zinc-400\">+${\n file.tags.length - 2\n }</span>`\n : \"\"\n }\n </div>\n `\n : \"\"\n }\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n // Grid view\n return `\n <div class=\"media-item relative rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 hover:shadow-md transition-all duration-200 overflow-hidden group\" data-file-id=\"${\n file.id\n }\">\n ${\n selectable\n ? `\n <div class=\"absolute top-2 left-2 z-10\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input type=\"checkbox\" value=\"${file.id}\" onchange=\"toggleFileSelection('${file.id}')\" class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto media-checkbox\" />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n </div>\n `\n : \"\"\n }\n\n <div class=\"aspect-square relative\">\n ${\n file.isImage\n ? `\n <img src=\"${file.thumbnail_url || file.public_url}\" alt=\"${\n file.alt || file.original_name\n }\"\n class=\"w-full h-full object-cover\">\n `\n : `\n <div class=\"w-full h-full bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center\">\n ${getFileIcon(file.mime_type)}\n </div>\n `\n }\n\n <!-- Overlay actions -->\n <div class=\"absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-40 transition-all duration-200 flex items-center justify-center opacity-0 group-hover:opacity-100\">\n <div class=\"flex space-x-2\">\n <button\n hx-get=\"/admin/media/${file.id}/details\"\n hx-target=\"#file-modal-content\"\n onclick=\"document.getElementById('file-modal').classList.remove('hidden')\"\n class=\"p-2 bg-white/20 rounded-full hover:bg-white/30 transition-colors\"\n >\n <svg class=\"w-5 h-5 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"></path>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"></path>\n </svg>\n </button>\n <button\n onclick=\"event.stopPropagation(); copyToClipboard('${\n file.public_url\n }')\"\n class=\"p-2 bg-white/20 rounded-full hover:bg-white/30 transition-colors\"\n >\n <svg class=\"w-5 h-5 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"></path>\n </svg>\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"p-3\">\n <h4 class=\"text-sm font-medium text-zinc-950 dark:text-white truncate\" title=\"${\n file.original_name\n }\">\n ${file.original_name}\n </h4>\n <div class=\"flex justify-between items-center mt-1\">\n <span class=\"text-xs text-zinc-500 dark:text-zinc-400\">${\n file.fileSize\n }</span>\n <span class=\"text-xs text-zinc-500 dark:text-zinc-400\">${\n file.uploadedAt\n }</span>\n </div>\n ${\n file.tags.length > 0\n ? `\n <div class=\"flex flex-wrap gap-1 mt-2\">\n ${file.tags\n .slice(0, 2)\n .map(\n (tag) => `\n <span class=\"inline-block px-2 py-1 text-xs rounded-lg bg-zinc-100 dark:bg-zinc-800 text-zinc-950 dark:text-white\">\n ${tag}\n </span>\n `\n )\n .join(\"\")}\n ${\n file.tags.length > 2\n ? `<span class=\"text-xs text-zinc-500 dark:text-zinc-400\">+${\n file.tags.length - 2\n }</span>`\n : \"\"\n }\n </div>\n `\n : \"\"\n }\n </div>\n </div>\n `;\n}\n\nfunction getFileIcon(mimeType: string): string {\n if (mimeType.startsWith(\"image/\")) {\n return `\n <svg class=\"w-8 h-8 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n </svg>\n `;\n } else if (mimeType.startsWith(\"video/\")) {\n return `\n <svg class=\"w-8 h-8 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n `;\n } else if (mimeType === \"application/pdf\") {\n return `\n <svg class=\"w-8 h-8 text-red-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z\" />\n </svg>\n `;\n } else {\n return `\n <svg class=\"w-8 h-8 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n `;\n }\n}\n","import {\n getConfirmationDialogScript,\n renderConfirmationDialog,\n} from \"../components/confirmation-dialog.template\";\nimport { MediaFile, renderMediaGrid } from \"../components/media-grid.template\";\nimport {\n AdminLayoutCatalystData,\n renderAdminLayoutCatalyst,\n} from \"../layouts/admin-layout-catalyst.template\";\n\nexport interface FolderStats {\n folder: string;\n count: number;\n totalSize: number;\n}\n\nexport interface TypeStats {\n type: string;\n count: number;\n}\n\nexport interface MediaLibraryPageData {\n files: MediaFile[];\n folders: FolderStats[];\n types: TypeStats[];\n currentFolder: string;\n currentType: string;\n currentView: \"grid\" | \"list\";\n currentPage: number;\n totalFiles: number;\n hasNextPage: boolean;\n user?: {\n name: string;\n email: string;\n role: string;\n };\n version?: string;\n}\n\nexport function renderMediaLibraryPage(data: MediaLibraryPageData): string {\n const pageContent = `\n <div>\n <!-- Header -->\n <div class=\"sm:flex sm:items-center sm:justify-between mb-6\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">Media Library</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">Manage your media files and assets</p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 flex gap-x-2\">\n <button\n class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n onclick=\"document.getElementById('upload-modal').classList.remove('hidden')\"\n >\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n Upload Media\n </button>\n </div>\n </div>\n \n <div class=\"flex gap-6\">\n <!-- Sidebar -->\n <div class=\"w-64 rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6\">\n <div class=\"space-y-6\">\n <!-- Upload Button -->\n <div>\n <button\n class=\"w-full rounded-lg bg-zinc-950 dark:bg-white px-4 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n onclick=\"document.getElementById('upload-modal').classList.remove('hidden')\"\n >\n Upload Files\n </button>\n </div>\n\n <!-- Folders -->\n <div>\n <h3 class=\"text-sm font-medium text-zinc-950 dark:text-white mb-3\">Folders</h3>\n <ul class=\"space-y-1\">\n <li>\n <a href=\"/admin/media?folder=all\"\n class=\"block px-3 py-2 text-sm rounded-lg transition-colors ${\n data.currentFolder === \"all\"\n ? \"bg-zinc-950 dark:bg-white text-white dark:text-zinc-950 font-medium\"\n : \"text-zinc-700 dark:text-zinc-300 hover:text-zinc-950 dark:hover:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50\"\n }\">\n All Files (${data.totalFiles})\n </a>\n </li>\n ${data.folders\n .map(\n (folder) => `\n <li>\n <a href=\"/admin/media?folder=${folder.folder}\"\n class=\"block px-3 py-2 text-sm rounded-lg transition-colors ${\n data.currentFolder === folder.folder\n ? \"bg-zinc-950 dark:bg-white text-white dark:text-zinc-950 font-medium\"\n : \"text-zinc-700 dark:text-zinc-300 hover:text-zinc-950 dark:hover:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50\"\n }\">\n ${folder.folder} (${folder.count})\n </a>\n </li>\n `\n )\n .join(\"\")}\n </ul>\n </div>\n\n <!-- File Types -->\n <div>\n <h3 class=\"text-sm font-medium text-zinc-950 dark:text-white mb-3\">File Types</h3>\n <ul class=\"space-y-1\">\n <li>\n <a href=\"/admin/media?type=all\"\n class=\"block px-3 py-2 text-sm rounded-lg transition-colors ${\n data.currentType === \"all\"\n ? \"bg-zinc-950 dark:bg-white text-white dark:text-zinc-950 font-medium\"\n : \"text-zinc-700 dark:text-zinc-300 hover:text-zinc-950 dark:hover:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50\"\n }\">\n All Types\n </a>\n </li>\n ${data.types\n .map(\n (type) => `\n <li>\n <a href=\"/admin/media?type=${type.type}\"\n class=\"block px-3 py-2 text-sm rounded-lg transition-colors ${\n data.currentType === type.type\n ? \"bg-zinc-950 dark:bg-white text-white dark:text-zinc-950 font-medium\"\n : \"text-zinc-700 dark:text-zinc-300 hover:text-zinc-950 dark:hover:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50\"\n }\">\n ${\n type.type.charAt(0).toUpperCase() + type.type.slice(1)\n } (${type.count})\n </a>\n </li>\n `\n )\n .join(\"\")}\n </ul>\n </div>\n\n <!-- Quick Actions -->\n <div>\n <h3 class=\"text-sm font-medium text-zinc-950 dark:text-white mb-3\">Quick Actions</h3>\n <div class=\"space-y-2\">\n <button\n onclick=\"openCreateFolderModal()\"\n class=\"w-full text-left px-3 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:text-zinc-950 dark:hover:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50 rounded-lg transition-colors\">\n Create Folder\n </button>\n <button\n class=\"w-full text-left px-3 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:text-zinc-950 dark:hover:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50 rounded-lg transition-colors\"\n hx-delete=\"/media/cleanup\"\n hx-confirm=\"Delete unused files?\"\n >\n Cleanup Unused\n </button>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Main Content -->\n <div class=\"flex-1\">\n <!-- Toolbar -->\n <div class=\"relative rounded-xl mb-6 z-10\">\n <!-- Gradient Background -->\n <div class=\"absolute inset-0 bg-gradient-to-r from-cyan-500/10 via-pink-500/10 to-purple-500/10 dark:from-cyan-400/20 dark:via-pink-400/20 dark:to-purple-400/20\"></div>\n\n <div class=\"relative bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10\">\n <div class=\"px-6 py-5\">\n <div class=\"flex items-center justify-between\">\n <div class=\"flex items-center space-x-4\">\n <div class=\"flex items-center space-x-2\">\n <label class=\"text-sm/6 font-medium text-zinc-950 dark:text-white\">View:</label>\n <div class=\"grid grid-cols-1\">\n <select\n class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-cyan-500/30 dark:outline-cyan-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-cyan-500 dark:focus-visible:outline-cyan-400 sm:text-sm/6 min-w-32\"\n onchange=\"window.location.href = updateUrlParam('view', this.value)\"\n >\n <option value=\"grid\" ${\n data.currentView === \"grid\" ? \"selected\" : \"\"\n }>Grid</option>\n <option value=\"list\" ${\n data.currentView === \"list\" ? \"selected\" : \"\"\n }>List</option>\n </select>\n <svg class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-500 dark:text-zinc-400 sm:size-4\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n\n <div class=\"relative group\">\n <input\n type=\"text\"\n id=\"media-search-input\"\n name=\"search\"\n placeholder=\"Search files...\"\n oninput=\"toggleMediaClearButton()\"\n class=\"rounded-full bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2.5 pl-11 pr-10 text-sm w-72 text-zinc-950 dark:text-white border-2 border-cyan-200/50 dark:border-cyan-700/50 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:bg-white dark:focus:bg-zinc-800 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n hx-get=\"/admin/media/search\"\n hx-trigger=\"keyup changed delay:300ms\"\n hx-target=\"#media-grid\"\n hx-include=\"[name='folder'], [name='type']\"\n >\n <div class=\"absolute left-3.5 top-2.5 flex items-center justify-center w-5 h-5 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 dark:from-cyan-300 dark:to-blue-400 opacity-90 group-focus-within:opacity-100 transition-opacity\">\n <svg class=\"h-3 w-3 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"/>\n </svg>\n </div>\n <button\n type=\"button\"\n id=\"clear-media-search\"\n class=\"hidden absolute right-3 top-2.5 p-0.5 rounded-full bg-zinc-200/80 dark:bg-zinc-700/80 hover:bg-zinc-300 dark:hover:bg-zinc-600 transition-colors\"\n onclick=\"clearMediaSearch()\"\n title=\"Clear search\"\n >\n <svg class=\"h-3.5 w-3.5 text-zinc-600 dark:text-zinc-300\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n <input type=\"hidden\" name=\"folder\" value=\"${\n data.currentFolder\n }\">\n <input type=\"hidden\" name=\"type\" value=\"${\n data.currentType\n }\">\n </div>\n </div>\n\n <div class=\"flex items-center gap-x-3\">\n <span class=\"text-sm/6 font-medium text-zinc-700 dark:text-zinc-300 px-3 py-1.5 rounded-full bg-white/60 dark:bg-zinc-800/60 backdrop-blur-sm\">${\n data.files.length\n } files</span>\n <button\n id=\"select-all-btn\"\n class=\"inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm text-zinc-950 dark:text-white text-sm font-medium rounded-full ring-1 ring-inset ring-cyan-200/50 dark:ring-cyan-700/50 hover:bg-gradient-to-r hover:from-cyan-50 hover:to-pink-50 dark:hover:from-cyan-900/30 dark:hover:to-pink-900/30 hover:ring-cyan-300 dark:hover:ring-cyan-600 transition-all duration-200\"\n onclick=\"toggleSelectAll()\"\n >\n Select All\n </button>\n <div class=\"relative inline-block z-50\" id=\"bulk-actions-dropdown\">\n <button\n id=\"bulk-actions-btn\"\n onclick=\"toggleBulkActionsDropdown()\"\n class=\"inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-zinc-100/60 dark:bg-zinc-800/60 backdrop-blur-sm text-zinc-400 dark:text-zinc-600 text-sm font-medium rounded-full ring-1 ring-inset ring-zinc-200/50 dark:ring-zinc-700/50 cursor-not-allowed\"\n disabled\n >\n Bulk Actions\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"size-4\">\n <path d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </button>\n\n <div\n id=\"bulk-actions-menu\"\n class=\"hidden absolute right-0 mt-2 w-56 origin-top-right divide-y divide-zinc-200 dark:divide-white/10 rounded-lg bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 transition-all duration-100 scale-95 opacity-0 z-50\"\n style=\"transition-behavior: allow-discrete;\"\n >\n <div class=\"py-1\">\n <button\n onclick=\"openMoveToFolderModal()\"\n class=\"group/item flex w-full items-center px-4 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-white/5 hover:text-zinc-950 dark:hover:text-white transition-colors\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"mr-3 size-5 text-zinc-400 dark:text-zinc-500 group-hover/item:text-zinc-950 dark:group-hover/item:text-white\">\n <path d=\"M2 6a2 2 0 0 1 2-2h5.532a2 2 0 0 1 1.536.72l1.9 2.28a1 1 0 0 0 .768.36H17a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6Z\" />\n </svg>\n Move to Folder\n </button>\n </div>\n <div class=\"py-1\">\n <button\n onclick=\"confirmBulkDelete()\"\n class=\"group/item flex w-full items-center px-4 py-2 text-sm text-zinc-700 dark:text-zinc-300 hover:bg-red-50 dark:hover:bg-red-500/10 hover:text-red-600 dark:hover:text-red-400 transition-colors\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"mr-3 size-5 text-zinc-400 dark:text-zinc-500 group-hover/item:text-red-600 dark:group-hover/item:text-red-400\">\n <path fill-rule=\"evenodd\" d=\"M8.75 1A2.75 2.75 0 0 0 6 3.75v.443c-.795.077-1.584.176-2.365.298a.75.75 0 1 0 .23 1.482l.149-.022.841 10.518A2.75 2.75 0 0 0 7.596 19h4.807a2.75 2.75 0 0 0 2.742-2.53l.841-10.52.149.023a.75.75 0 0 0 .23-1.482A41.03 41.03 0 0 0 14 4.193V3.75A2.75 2.75 0 0 0 11.25 1h-2.5ZM10 4c.84 0 1.673.025 2.5.075V3.75c0-.69-.56-1.25-1.25-1.25h-2.5c-.69 0-1.25.56-1.25 1.25v.325C8.327 4.025 9.16 4 10 4ZM8.58 7.72a.75.75 0 0 0-1.5.06l.3 7.5a.75.75 0 1 0 1.5-.06l-.3-7.5Zm4.34.06a.75.75 0 1 0-1.5-.06l-.3 7.5a.75.75 0 1 0 1.5.06l.3-7.5Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n Delete Selected Files\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Media Grid -->\n <div id=\"media-grid\">\n ${renderMediaGrid({\n files: data.files,\n viewMode: data.currentView,\n selectable: true,\n emptyMessage:\n \"No media files found. Upload your first file to get started.\",\n })}\n </div>\n \n <!-- Pagination -->\n ${\n data.hasNextPage\n ? `\n <div class=\"mt-6 flex justify-center\">\n <div class=\"flex space-x-2\">\n ${\n data.currentPage > 1\n ? `\n <a href=\"${buildPageUrl(\n data.currentPage - 1,\n data.currentFolder,\n data.currentType\n )}\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors\">\n Previous\n </a>\n `\n : \"\"\n }\n <span class=\"px-3 py-2 text-sm text-zinc-500 dark:text-zinc-400\">Page ${\n data.currentPage\n }</span>\n <a href=\"${buildPageUrl(\n data.currentPage + 1,\n data.currentFolder,\n data.currentType\n )}\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors\">\n Next\n </a>\n </div>\n </div>\n `\n : \"\"\n }\n </div>\n </div>\n </div>\n \n <!-- Upload Modal -->\n <div id=\"upload-modal\" class=\"hidden fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 w-full max-w-2xl\">\n <div class=\"flex justify-between items-center mb-4\">\n <h3 class=\"text-lg font-semibold text-zinc-950 dark:text-white\">Upload Files</h3>\n <button onclick=\"document.getElementById('upload-modal').classList.add('hidden')\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors\">\n <svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n </div>\n \n <!-- Upload Form -->\n <form \n id=\"upload-form\"\n hx-post=\"/admin/media/upload\"\n hx-encoding=\"multipart/form-data\"\n hx-target=\"#upload-results\"\n class=\"space-y-4\"\n >\n <!-- Drag and Drop Zone -->\n <div\n id=\"upload-zone\"\n class=\"upload-zone border-2 border-dashed border-zinc-950/10 dark:border-white/20 rounded-xl p-8 text-center cursor-pointer bg-zinc-50 dark:bg-zinc-800/50 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors\"\n onclick=\"document.getElementById('file-input').click()\"\n >\n <svg class=\"mx-auto h-12 w-12 text-zinc-400\" stroke=\"currentColor\" fill=\"none\" viewBox=\"0 0 48 48\">\n <path d=\"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <div class=\"mt-4\">\n <p class=\"text-lg text-zinc-950 dark:text-white\">Drop files here or click to upload</p>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">PNG, JPG, GIF, PDF up to 10MB</p>\n </div>\n </div>\n \n <input \n type=\"file\" \n id=\"file-input\" \n name=\"files\" \n multiple \n accept=\"image/*,application/pdf,text/plain\"\n class=\"hidden\"\n onchange=\"handleFileSelect(this.files)\"\n >\n \n <!-- Folder Selection -->\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Upload to folder:</label>\n <select name=\"folder\" class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\">\n <option value=\"uploads\">uploads</option>\n <option value=\"images\">images</option>\n <option value=\"documents\">documents</option>\n </select>\n </div>\n\n <!-- File List -->\n <div id=\"file-list\" class=\"hidden\">\n <h4 class=\"text-sm font-medium text-zinc-950 dark:text-white mb-2\">Selected Files:</h4>\n <div id=\"selected-files\" class=\"space-y-2 max-h-40 overflow-y-auto\"></div>\n </div>\n\n <!-- Upload Button -->\n <div class=\"flex justify-end space-x-2\">\n <button\n type=\"button\"\n onclick=\"document.getElementById('upload-modal').classList.add('hidden')\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n id=\"upload-btn\"\n class=\"rounded-lg bg-zinc-950 dark:bg-white px-4 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 disabled:opacity-50 transition-colors shadow-sm\"\n disabled\n >\n Upload Files\n </button>\n </div>\n </form>\n \n <!-- Upload Results -->\n <div id=\"upload-results\" class=\"mt-4\"></div>\n </div>\n </div>\n \n <!-- File Details Modal -->\n <div id=\"file-modal\" class=\"hidden fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\n <div id=\"file-modal-content\" class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 w-full max-w-4xl max-h-screen overflow-y-auto\">\n <!-- Content loaded via HTMX -->\n </div>\n </div>\n\n <!-- Move to Folder Modal -->\n <div id=\"move-to-folder-modal\" class=\"hidden fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 w-full max-w-md\">\n <div class=\"flex justify-between items-center mb-4\">\n <h3 class=\"text-lg font-semibold text-zinc-950 dark:text-white\">Move to Folder</h3>\n <button onclick=\"closeMoveToFolderModal()\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors\">\n <svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n </div>\n\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400 mb-4\">\n Select a folder to move <span id=\"move-file-count\" class=\"font-medium text-zinc-950 dark:text-white\">0</span> selected file(s) to:\n </p>\n\n <div class=\"space-y-2 mb-6\">\n ${\n data.folders.length > 0\n ? data.folders\n .map(\n (folder) => `\n <button\n onclick=\"performBulkMove('${folder.folder}')\"\n class=\"w-full text-left px-4 py-3 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 hover:bg-zinc-100 dark:hover:bg-zinc-800 text-zinc-950 dark:text-white transition-colors ring-1 ring-inset ring-zinc-200 dark:ring-zinc-700\"\n >\n <div class=\"flex items-center justify-between\">\n <span class=\"font-medium\">${folder.folder}</span>\n <span class=\"text-sm text-zinc-500 dark:text-zinc-400\">${folder.count} files</span>\n </div>\n </button>\n `\n )\n .join(\"\")\n : '<p class=\"text-sm text-zinc-500 dark:text-zinc-400 text-center py-4\">No folders available</p>'\n }\n </div>\n\n <div class=\"flex justify-end space-x-2\">\n <button\n onclick=\"closeMoveToFolderModal()\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n\n <!-- Create Folder Modal -->\n <div id=\"create-folder-modal\" class=\"hidden fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 w-full max-w-md\">\n <div class=\"flex justify-between items-center mb-4\">\n <h3 class=\"text-lg font-semibold text-zinc-950 dark:text-white\">Create New Folder</h3>\n <button onclick=\"closeCreateFolderModal()\" aria-label=\"Close\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors\">\n <svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n </div>\n\n <form onsubmit=\"createNewFolder(event)\" class=\"space-y-4\">\n <div>\n <label for=\"folder-name\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Folder Name\n </label>\n <input\n type=\"text\"\n id=\"folder-name\"\n name=\"folderName\"\n placeholder=\"e.g., images, documents\"\n required\n pattern=\"[a-z0-9-_]+\"\n title=\"Only lowercase letters, numbers, hyphens, and underscores allowed\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 focus:outline-none focus:ring-2 focus:ring-cyan-500 dark:focus:ring-cyan-400 transition-shadow\"\n >\n <p class=\"mt-1 text-xs text-zinc-500 dark:text-zinc-400\">\n Use lowercase letters, numbers, hyphens, and underscores only\n </p>\n </div>\n\n <div class=\"flex justify-end space-x-2\">\n <button\n type=\"button\"\n onclick=\"closeCreateFolderModal()\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n class=\"rounded-lg bg-zinc-950 dark:bg-white px-4 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n Create Folder\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <style>\n .media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; }\n .media-item { position: relative; border-radius: 8px; overflow: hidden; transition: transform 0.2s; }\n .media-item:hover { transform: scale(1.02); }\n .media-item.selected { ring: 2px solid rgba(255, 255, 255, 0.4); }\n .upload-zone { border: 2px dashed rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.1); min-height: 200px; }\n .upload-zone.dragover { border-color: rgba(255, 255, 255, 0.4); background: rgba(255, 255, 255, 0.2); }\n .file-icon { width: 48px; height: 48px; }\n .preview-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.7); opacity: 0; transition: opacity 0.2s; }\n .media-item:hover .preview-overlay { opacity: 1; }\n </style>\n \n <script>\n let selectedFiles = new Set();\n let dragDropFiles = [];\n \n // File selection handling\n function toggleFileSelection(fileId) {\n if (selectedFiles.has(fileId)) {\n selectedFiles.delete(fileId);\n document.querySelector(\\`[data-file-id=\"\\${fileId}\"]\\`).classList.remove('selected');\n } else {\n selectedFiles.add(fileId);\n document.querySelector(\\`[data-file-id=\"\\${fileId}\"]\\`).classList.add('selected');\n }\n updateBulkActionsButton();\n }\n \n function toggleSelectAll() {\n const allItems = document.querySelectorAll('[data-file-id]');\n if (selectedFiles.size === allItems.length) {\n selectedFiles.clear();\n allItems.forEach(item => item.classList.remove('selected'));\n document.getElementById('select-all-btn').textContent = 'Select All';\n } else {\n allItems.forEach(item => {\n const fileId = item.dataset.fileId;\n selectedFiles.add(fileId);\n item.classList.add('selected');\n });\n document.getElementById('select-all-btn').textContent = 'Deselect All';\n }\n updateBulkActionsButton();\n }\n \n function updateBulkActionsButton() {\n const btn = document.getElementById('bulk-actions-btn');\n const chevronIcon = btn.querySelector('svg');\n\n if (selectedFiles.size > 0) {\n btn.disabled = false;\n btn.className = 'inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm text-zinc-950 dark:text-white text-sm font-medium rounded-full ring-1 ring-inset ring-cyan-200/50 dark:ring-cyan-700/50 hover:bg-gradient-to-r hover:from-cyan-50 hover:to-blue-50 dark:hover:from-cyan-900/30 dark:hover:to-blue-900/30 hover:ring-cyan-300 dark:hover:ring-cyan-600 transition-all duration-200';\n btn.innerHTML = \\`Actions (\\${selectedFiles.size}) <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"size-4\"><path d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" /></svg>\\`;\n // Re-attach onclick handler after innerHTML update\n btn.onclick = toggleBulkActionsDropdown;\n } else {\n btn.disabled = true;\n btn.className = 'inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-zinc-100/60 dark:bg-zinc-800/60 backdrop-blur-sm text-zinc-400 dark:text-zinc-600 text-sm font-medium rounded-full ring-1 ring-inset ring-zinc-200/50 dark:ring-zinc-700/50 cursor-not-allowed';\n btn.innerHTML = \\`Bulk Actions <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"size-4\"><path d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" /></svg>\\`;\n btn.onclick = null; // Remove handler when disabled\n // Hide menu when no files selected\n const menu = document.getElementById('bulk-actions-menu');\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0', 'hidden');\n }\n }\n\n function toggleBulkActionsDropdown() {\n const menu = document.getElementById('bulk-actions-menu');\n const isHidden = menu.classList.contains('hidden');\n\n if (isHidden) {\n menu.classList.remove('hidden');\n setTimeout(() => {\n menu.classList.remove('scale-95', 'opacity-0');\n menu.classList.add('scale-100', 'opacity-100');\n }, 10);\n } else {\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0');\n setTimeout(() => {\n menu.classList.add('hidden');\n }, 100);\n }\n }\n \n function confirmBulkDelete() {\n if (selectedFiles.size === 0) return;\n showConfirmDialog('media-bulk-delete-confirm');\n }\n\n async function performBulkDelete() {\n if (selectedFiles.size === 0) return;\n\n try {\n // Show loading state\n const btn = document.getElementById('bulk-actions-btn');\n const originalText = btn.innerHTML;\n btn.innerHTML = 'Deleting...';\n btn.disabled = true;\n\n // Hide menu\n const menu = document.getElementById('bulk-actions-menu');\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0');\n setTimeout(() => menu.classList.add('hidden'), 100);\n \n const response = await fetch('/api/media/bulk-delete', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n fileIds: Array.from(selectedFiles)\n })\n });\n \n const result = await response.json();\n \n if (result.success) {\n // Show success notification\n showNotification(\\`Successfully deleted \\${result.summary.successful} file\\${result.summary.successful > 1 ? 's' : ''}\\`, 'success');\n \n // Remove deleted files from DOM\n result.deleted.forEach(item => {\n const element = document.querySelector(\\`[data-file-id=\"\\${item.fileId}\"]\\`);\n if (element) {\n element.remove();\n }\n });\n \n // Show errors if any\n if (result.errors.length > 0) {\n console.warn('Some files failed to delete:', result.errors);\n showNotification(\\`\\${result.errors.length} file\\${result.errors.length > 1 ? 's' : ''} failed to delete\\`, 'warning');\n }\n \n // Clear selection\n selectedFiles.clear();\n updateBulkActionsButton();\n document.getElementById('select-all-btn').textContent = 'Select All';\n } else {\n showNotification('Failed to delete files', 'error');\n }\n } catch (error) {\n console.error('Bulk delete error:', error);\n showNotification('An error occurred while deleting files', 'error');\n } finally {\n // Reset button state\n updateBulkActionsButton();\n }\n }\n \n function openMoveToFolderModal() {\n if (selectedFiles.size === 0) return;\n\n // Update file count in modal\n document.getElementById('move-file-count').textContent = selectedFiles.size.toString();\n\n // Show modal\n document.getElementById('move-to-folder-modal').classList.remove('hidden');\n\n // Hide bulk actions menu\n const menu = document.getElementById('bulk-actions-menu');\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0');\n setTimeout(() => menu.classList.add('hidden'), 100);\n }\n\n function closeMoveToFolderModal() {\n document.getElementById('move-to-folder-modal').classList.add('hidden');\n }\n\n function openCreateFolderModal() {\n document.getElementById('create-folder-modal').classList.remove('hidden');\n // Clear and focus the input\n const input = document.getElementById('folder-name');\n input.value = '';\n setTimeout(() => input.focus(), 100);\n }\n\n function closeCreateFolderModal() {\n document.getElementById('create-folder-modal').classList.add('hidden');\n }\n\n async function createNewFolder(event) {\n event.preventDefault();\n\n const folderName = document.getElementById('folder-name').value.trim();\n\n if (!folderName) {\n showNotification('Please enter a folder name', 'error');\n return;\n }\n\n // Validate folder name format\n const folderPattern = /^[a-z0-9-_]+$/;\n if (!folderPattern.test(folderName)) {\n showNotification('Folder name can only contain lowercase letters, numbers, hyphens, and underscores', 'error');\n return;\n }\n\n try {\n const response = await fetch('/api/media/create-folder', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ folderName })\n });\n\n const result = await response.json();\n\n if (result.success) {\n showNotification(\\`Folder \"\\${folderName}\" created successfully\\`, 'success');\n closeCreateFolderModal();\n\n // Reload the page to show the new folder (delay to allow notification to show)\n setTimeout(() => {\n window.location.reload();\n }, 2000);\n } else {\n showNotification(result.error || 'Failed to create folder', 'error');\n }\n } catch (error) {\n console.error('Create folder error:', error);\n showNotification('An error occurred while creating the folder', 'error');\n }\n }\n\n async function performBulkMove(targetFolder) {\n if (selectedFiles.size === 0) return;\n\n try {\n // Show loading state\n closeMoveToFolderModal();\n const btn = document.getElementById('bulk-actions-btn');\n const originalText = btn.innerHTML;\n btn.innerHTML = 'Moving...';\n btn.disabled = true;\n\n const response = await fetch('/api/media/bulk-move', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n fileIds: Array.from(selectedFiles),\n folder: targetFolder\n })\n });\n\n const result = await response.json();\n\n if (result.success) {\n // Show success notification\n const movedCount = result.summary.successful;\n showNotification(\\`Successfully moved \\${movedCount} file\\${movedCount > 1 ? 's' : ''} to \\${targetFolder}\\`, 'success');\n\n // Reload the page to show updated file locations\n setTimeout(() => {\n window.location.reload();\n }, 1000);\n } else {\n showNotification('Failed to move files', 'error');\n updateBulkActionsButton();\n }\n } catch (error) {\n console.error('Bulk move error:', error);\n showNotification('An error occurred while moving files', 'error');\n updateBulkActionsButton();\n }\n }\n\n function showNotification(message, type = 'info') {\n const notification = document.createElement('div');\n const bgColor = type === 'success' ? 'bg-green-600' :\n type === 'warning' ? 'bg-yellow-600' :\n type === 'error' ? 'bg-red-600' : 'bg-blue-600';\n\n notification.className = \\`fixed top-4 right-4 \\${bgColor} text-white px-4 py-3 rounded-lg shadow-xl ring-1 ring-white/10 z-50 transition-all transform translate-x-full\\`;\n notification.textContent = message;\n document.body.appendChild(notification);\n\n // Animate in\n setTimeout(() => {\n notification.classList.remove('translate-x-full');\n }, 100);\n\n // Remove after 3 seconds\n setTimeout(() => {\n notification.classList.add('translate-x-full');\n setTimeout(() => {\n if (document.body.contains(notification)) {\n document.body.removeChild(notification);\n }\n }, 300);\n }, 3000);\n }\n \n // URL parameter helpers\n function updateUrlParam(param, value) {\n const url = new URL(window.location);\n url.searchParams.set(param, value);\n return url.toString();\n }\n \n // Drag and drop handling\n const uploadZone = document.getElementById('upload-zone');\n \n ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {\n uploadZone.addEventListener(eventName, preventDefaults, false);\n });\n \n function preventDefaults(e) {\n e.preventDefault();\n e.stopPropagation();\n }\n \n ['dragenter', 'dragover'].forEach(eventName => {\n uploadZone.addEventListener(eventName, () => uploadZone.classList.add('dragover'), false);\n });\n \n ['dragleave', 'drop'].forEach(eventName => {\n uploadZone.addEventListener(eventName, () => uploadZone.classList.remove('dragover'), false);\n });\n \n uploadZone.addEventListener('drop', handleDrop, false);\n \n function handleDrop(e) {\n const dt = e.dataTransfer;\n const files = dt.files;\n handleFileSelect(files);\n }\n \n function handleFileSelect(files) {\n dragDropFiles = Array.from(files);\n \n // Update the actual file input with the selected files\n const fileInput = document.getElementById('file-input');\n const dt = new DataTransfer();\n dragDropFiles.forEach(file => dt.items.add(file));\n fileInput.files = dt.files;\n \n displaySelectedFiles();\n document.getElementById('upload-btn').disabled = false;\n }\n \n function displaySelectedFiles() {\n const fileList = document.getElementById('file-list');\n const selectedFilesDiv = document.getElementById('selected-files');\n\n selectedFilesDiv.innerHTML = '';\n\n dragDropFiles.forEach((file, index) => {\n const fileItem = document.createElement('div');\n fileItem.className = 'flex items-center justify-between p-2 rounded-lg bg-zinc-50 dark:bg-zinc-800 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10';\n fileItem.innerHTML = \\`\n <div class=\"flex items-center space-x-2\">\n <span class=\"text-sm text-zinc-950 dark:text-white\">\\${file.name}</span>\n <span class=\"text-xs text-zinc-500 dark:text-zinc-400\">(\\${formatFileSize(file.size)})</span>\n </div>\n <button onclick=\"removeFile(\\${index})\" class=\"text-red-600 dark:text-red-400 hover:text-red-700 dark:hover:text-red-300 transition-colors\">\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n \\`;\n selectedFilesDiv.appendChild(fileItem);\n });\n\n fileList.classList.toggle('hidden', dragDropFiles.length === 0);\n }\n \n function removeFile(index) {\n dragDropFiles.splice(index, 1);\n displaySelectedFiles();\n \n const fileInput = document.getElementById('file-input');\n const dt = new DataTransfer();\n dragDropFiles.forEach(file => dt.items.add(file));\n fileInput.files = dt.files;\n \n document.getElementById('upload-btn').disabled = dragDropFiles.length === 0;\n }\n \n function formatFileSize(bytes) {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n \n // Copy to clipboard function\n function copyToClipboard(text) {\n navigator.clipboard.writeText(text).then(() => {\n const notification = document.createElement('div');\n notification.className = 'fixed top-4 right-4 bg-green-600 text-white px-4 py-3 rounded-lg shadow-xl ring-1 ring-white/10 z-50';\n notification.textContent = 'URL copied to clipboard!';\n document.body.appendChild(notification);\n setTimeout(() => document.body.removeChild(notification), 2000);\n }).catch(err => {\n console.error('Failed to copy: ', err);\n });\n }\n\n // Toggle clear button visibility\n function toggleMediaClearButton() {\n const searchInput = document.getElementById('media-search-input');\n const clearButton = document.getElementById('clear-media-search');\n if (searchInput.value.trim()) {\n clearButton.classList.remove('hidden');\n } else {\n clearButton.classList.add('hidden');\n }\n }\n\n // Clear search input\n function clearMediaSearch() {\n const searchInput = document.getElementById('media-search-input');\n searchInput.value = '';\n toggleMediaClearButton();\n // Trigger htmx to refresh the grid\n htmx.trigger(searchInput, 'keyup');\n }\n\n // Initialize clear button visibility on page load\n document.addEventListener('DOMContentLoaded', function() {\n toggleMediaClearButton();\n });\n\n // Close modal when clicking outside\n document.getElementById('file-modal').addEventListener('click', function(e) {\n if (e.target === this) {\n this.classList.add('hidden');\n }\n });\n \n // Close bulk actions dropdown when clicking outside\n document.addEventListener('click', function(e) {\n const dropdown = document.getElementById('bulk-actions-dropdown');\n const menu = document.getElementById('bulk-actions-menu');\n if (dropdown && menu && !dropdown.contains(e.target)) {\n menu.classList.remove('scale-100', 'opacity-100');\n menu.classList.add('scale-95', 'opacity-0');\n setTimeout(() => {\n menu.classList.add('hidden');\n }, 100);\n }\n });\n </script>\n\n <!-- Confirmation Dialog for Bulk Delete -->\n ${renderConfirmationDialog({\n id: \"media-bulk-delete-confirm\",\n title: \"Delete Selected Files\",\n message: `Are you sure you want to delete ${\n data.files.length > 0 ? \"the selected files\" : \"these files\"\n }? This action cannot be undone and the files will be permanently removed.`,\n confirmText: \"Delete Files\",\n cancelText: \"Cancel\",\n confirmClass: \"bg-red-500 hover:bg-red-400\",\n iconColor: \"red\",\n onConfirm: \"performBulkDelete()\",\n })}\n\n <!-- Confirmation Dialog Script -->\n ${getConfirmationDialogScript()}\n `;\n\n function buildPageUrl(page: number, folder: string, type: string): string {\n const params = new URLSearchParams();\n params.set(\"page\", page.toString());\n if (folder !== \"all\") params.set(\"folder\", folder);\n if (type !== \"all\") params.set(\"type\", type);\n return `/admin/media?${params.toString()}`;\n }\n\n const layoutData: AdminLayoutCatalystData = {\n title: \"Media Library\",\n pageTitle: \"Media Library\",\n currentPath: \"/admin/media\",\n user: data.user,\n version: data.version,\n content: pageContent,\n };\n\n return renderAdminLayoutCatalyst(layoutData);\n}\n","import { MediaFile } from './media-grid.template'\n\nexport interface MediaFileDetailsData {\n file: MediaFile & {\n width?: number\n height?: number\n folder: string\n uploadedAt: string\n }\n}\n\nexport function renderMediaFileDetails(data: MediaFileDetailsData): string {\n const { file } = data\n \n return `\n <div class=\"flex justify-between items-center mb-4\">\n <h3 class=\"text-lg font-semibold text-zinc-950 dark:text-white\">File Details</h3>\n <button onclick=\"document.getElementById('file-modal').classList.add('hidden')\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors\">\n <svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n </div>\n \n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <!-- Preview -->\n <div class=\"space-y-4\">\n <div class=\"rounded-xl bg-zinc-50 dark:bg-zinc-800 p-4\">\n ${file.isImage ? `\n <img src=\"${file.public_url}\" alt=\"${file.alt || file.filename}\" class=\"w-full h-auto rounded-lg\">\n ` : file.isVideo ? `\n <video src=\"${file.public_url}\" controls class=\"w-full h-auto rounded-lg\"></video>\n ` : `\n <div class=\"flex items-center justify-center h-32\">\n <svg class=\"w-12 h-12 text-zinc-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"></path>\n </svg>\n </div>\n `}\n </div>\n\n <div class=\"text-center space-x-2\">\n <button\n onclick=\"copyToClipboard('${file.public_url}')\"\n class=\"inline-flex items-center rounded-lg bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-700 transition-colors\"\n >\n Copy URL\n </button>\n <a\n href=\"${file.public_url}\"\n target=\"_blank\"\n class=\"inline-flex items-center rounded-lg bg-white dark:bg-zinc-800 px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors\"\n >\n Open Original\n </a>\n </div>\n </div>\n \n <!-- Details -->\n <div class=\"space-y-4\">\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Filename</label>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">${file.original_name}</p>\n </div>\n\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Size</label>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">${file.fileSize}</p>\n </div>\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Type</label>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">${file.mime_type}</p>\n </div>\n </div>\n\n ${file.width && file.height ? `\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Width</label>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">${file.width}px</p>\n </div>\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Height</label>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">${file.height}px</p>\n </div>\n </div>\n ` : ''}\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Folder</label>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">${file.folder}</p>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Uploaded</label>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">${file.uploadedAt}</p>\n </div>\n\n <!-- Editable Fields -->\n <form hx-put=\"/admin/media/${file.id}\" hx-target=\"#file-modal-content\" class=\"space-y-4\">\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Alt Text</label>\n <input\n type=\"text\"\n name=\"alt\"\n value=\"${file.alt || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white placeholder-zinc-500 dark:placeholder-zinc-400 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 focus:ring-2 focus:ring-blue-600 dark:focus:ring-blue-500 focus:outline-none transition-colors\"\n placeholder=\"Describe this image...\"\n >\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Caption</label>\n <textarea\n name=\"caption\"\n rows=\"3\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white placeholder-zinc-500 dark:placeholder-zinc-400 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 focus:ring-2 focus:ring-blue-600 dark:focus:ring-blue-500 focus:outline-none transition-colors\"\n placeholder=\"Optional caption...\"\n >${file.caption || ''}</textarea>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-1\">Tags</label>\n <input\n type=\"text\"\n name=\"tags\"\n value=\"${file.tags.join(', ')}\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white placeholder-zinc-500 dark:placeholder-zinc-400 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 focus:ring-2 focus:ring-blue-600 dark:focus:ring-blue-500 focus:outline-none transition-colors\"\n placeholder=\"tag1, tag2, tag3\"\n >\n </div>\n\n <div class=\"flex justify-between\">\n <button\n type=\"submit\"\n class=\"rounded-lg bg-green-600 px-4 py-2 text-sm font-semibold text-white hover:bg-green-700 transition-colors\"\n >\n Save Changes\n </button>\n <button\n type=\"button\"\n hx-delete=\"/admin/media/${file.id}\"\n hx-confirm=\"Are you sure you want to delete this file?\"\n hx-target=\"body\"\n class=\"rounded-lg bg-red-600 px-4 py-2 text-sm font-semibold text-white hover:bg-red-700 transition-colors\"\n >\n Delete File\n </button>\n </div>\n </form>\n </div>\n </div>\n `\n}","import { Hono } from 'hono'\nimport { html, raw } from 'hono/html'\nimport { z } from 'zod'\nimport type { D1Database, KVNamespace, R2Bucket } from '@cloudflare/workers-types'\nimport { requireAuth, requireRole } from '../middleware'\nimport { renderMediaLibraryPage, MediaLibraryPageData, FolderStats, TypeStats } from '../templates/pages/admin-media-library.template'\nimport { renderMediaFileDetails, MediaFileDetailsData } from '../templates/components/media-file-details.template'\nimport { MediaFile, renderMediaFileCard } from '../templates/components/media-grid.template'\nimport type { Bindings, Variables } from '../app'\n\n// File validation schema\nconst fileValidationSchema = z.object({\n name: z.string().min(1).max(255),\n type: z.string().refine(\n (type) => {\n const allowedTypes = [\n // Images\n 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml',\n // Documents\n 'application/pdf', 'text/plain', 'application/msword', \n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n // Videos\n 'video/mp4', 'video/webm', 'video/ogg', 'video/avi', 'video/mov',\n // Audio\n 'audio/mp3', 'audio/wav', 'audio/ogg', 'audio/m4a'\n ]\n return allowedTypes.includes(type)\n },\n { message: 'Unsupported file type' }\n ),\n size: z.number().min(1).max(50 * 1024 * 1024) // 50MB max\n})\n\nconst adminMediaRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Media library main page\nadminMediaRoutes.get('/', async (c) => {\n try {\n const user = c.get('user')\n const { searchParams } = new URL(c.req.url)\n const folder = searchParams.get('folder') || 'all'\n const type = searchParams.get('type') || 'all'\n const view = searchParams.get('view') || 'grid'\n const page = parseInt(searchParams.get('page') || '1')\n const cacheBust = searchParams.get('t') // Cache-busting parameter\n const limit = 24\n const offset = (page - 1) * limit\n\n const db = c.env.DB\n\n // TODO: Cache implementation removed during migration - will be added back when cache plugin is migrated\n\n // Build query for media files\n let query = 'SELECT * FROM media'\n const params: any[] = []\n const conditions: string[] = ['deleted_at IS NULL']\n \n if (folder !== 'all') {\n conditions.push('folder = ?')\n params.push(folder)\n }\n \n if (type !== 'all') {\n switch (type) {\n case 'images':\n conditions.push('mime_type LIKE ?')\n params.push('image/%')\n break\n case 'documents':\n conditions.push('mime_type IN (?, ?, ?)')\n params.push('application/pdf', 'text/plain', 'application/msword')\n break\n case 'videos':\n conditions.push('mime_type LIKE ?')\n params.push('video/%')\n break\n }\n }\n \n if (conditions.length > 0) {\n query += ` WHERE ${conditions.join(' AND ')}`\n }\n \n query += ` ORDER BY uploaded_at DESC LIMIT ${limit} OFFSET ${offset}`\n \n const stmt = db.prepare(query)\n const { results } = await stmt.bind(...params).all()\n \n // Get folder statistics\n const foldersStmt = db.prepare(`\n SELECT folder, COUNT(*) as count, SUM(size) as totalSize\n FROM media \n GROUP BY folder \n ORDER BY folder\n `)\n const { results: folders } = await foldersStmt.all()\n \n // Get type statistics\n const typesStmt = db.prepare(`\n SELECT \n CASE \n WHEN mime_type LIKE 'image/%' THEN 'images'\n WHEN mime_type LIKE 'video/%' THEN 'videos'\n WHEN mime_type IN ('application/pdf', 'text/plain') THEN 'documents'\n ELSE 'other'\n END as type,\n COUNT(*) as count\n FROM media \n GROUP BY type\n `)\n const { results: types } = await typesStmt.all()\n \n // Process media files with local serving URLs\n const mediaFiles: MediaFile[] = results.map((row: any) => ({\n id: row.id,\n filename: row.filename,\n original_name: row.original_name,\n mime_type: row.mime_type,\n size: row.size,\n public_url: `/files/${row.r2_key}`,\n thumbnail_url: row.mime_type.startsWith('image/') ? `/files/${row.r2_key}` : undefined,\n alt: row.alt,\n caption: row.caption,\n tags: row.tags ? JSON.parse(row.tags) : [],\n uploaded_at: row.uploaded_at,\n fileSize: formatFileSize(row.size),\n uploadedAt: new Date(row.uploaded_at).toLocaleDateString(),\n isImage: row.mime_type.startsWith('image/'),\n isVideo: row.mime_type.startsWith('video/'),\n isDocument: !row.mime_type.startsWith('image/') && !row.mime_type.startsWith('video/')\n }))\n \n const pageData: MediaLibraryPageData = {\n files: mediaFiles,\n folders: folders.map((f: any) => ({\n folder: f.folder,\n count: f.count,\n totalSize: f.totalSize\n })) as FolderStats[],\n types: types.map((t: any) => ({\n type: t.type,\n count: t.count\n })) as TypeStats[],\n currentFolder: folder,\n currentType: type,\n currentView: view as 'grid' | 'list',\n currentPage: page,\n totalFiles: results.length,\n hasNextPage: results.length === limit,\n user: {\n name: user!.email,\n email: user!.email,\n role: user!.role\n },\n version: c.get('appVersion')\n }\n\n // TODO: Cache implementation removed during migration\n\n return c.html(renderMediaLibraryPage(pageData))\n } catch (error) {\n console.error('Error loading media library:', error)\n return c.html(html`<p>Error loading media library</p>`)\n }\n})\n\n// Media selector endpoint (HTMX endpoint for content form media selection)\nadminMediaRoutes.get('/selector', async (c) => {\n try {\n const { searchParams } = new URL(c.req.url)\n const search = searchParams.get('search') || ''\n const db = c.env.DB\n\n // Build search query\n let query = 'SELECT * FROM media WHERE deleted_at IS NULL'\n const params: any[] = []\n\n if (search.trim()) {\n query += ' AND (filename LIKE ? OR original_name LIKE ? OR alt LIKE ?)'\n const searchTerm = `%${search}%`\n params.push(searchTerm, searchTerm, searchTerm)\n }\n\n query += ' ORDER BY uploaded_at DESC LIMIT 24'\n\n const stmt = db.prepare(query)\n const { results } = await stmt.bind(...params).all()\n\n const mediaFiles = results.map((row: any) => ({\n id: row.id,\n filename: row.filename,\n original_name: row.original_name,\n mime_type: row.mime_type,\n size: row.size,\n public_url: `/files/${row.r2_key}`,\n thumbnail_url: row.mime_type.startsWith('image/') ? `/files/${row.r2_key}` : undefined,\n alt: row.alt,\n tags: row.tags ? JSON.parse(row.tags) : [],\n uploaded_at: row.uploaded_at,\n fileSize: formatFileSize(row.size),\n uploadedAt: new Date(row.uploaded_at).toLocaleDateString(),\n isImage: row.mime_type.startsWith('image/'),\n isVideo: row.mime_type.startsWith('video/'),\n isDocument: !row.mime_type.startsWith('image/') && !row.mime_type.startsWith('video/')\n }))\n\n // Render media selector grid\n return c.html(html`\n <div class=\"mb-4\">\n <input\n type=\"search\"\n id=\"media-selector-search\"\n placeholder=\"Search files...\"\n class=\"w-full rounded-lg bg-white dark:bg-zinc-800 px-4 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow\"\n hx-get=\"/admin/media/selector\"\n hx-trigger=\"keyup changed delay:300ms\"\n hx-target=\"#media-selector-grid\"\n hx-include=\"[name='search']\"\n >\n </div>\n\n <div id=\"media-selector-grid\" class=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4 max-h-96 overflow-y-auto\">\n ${raw(mediaFiles.map(file => `\n <div\n class=\"relative group cursor-pointer rounded-lg overflow-hidden bg-zinc-50 dark:bg-zinc-800 shadow-sm hover:shadow-md transition-shadow\"\n data-media-id=\"${file.id}\"\n >\n <div class=\"aspect-square relative\">\n ${file.isImage ? `\n <img\n src=\"${file.public_url}\"\n alt=\"${file.alt || file.filename}\"\n class=\"w-full h-full object-cover\"\n loading=\"lazy\"\n >\n ` : file.isVideo ? `\n <video\n src=\"${file.public_url}\"\n class=\"w-full h-full object-cover\"\n muted\n ></video>\n ` : `\n <div class=\"w-full h-full flex items-center justify-center bg-zinc-100 dark:bg-zinc-700\">\n <div class=\"text-center\">\n <svg class=\"w-12 h-12 mx-auto text-zinc-400 dark:text-zinc-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"></path>\n </svg>\n <span class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">${file.filename.split('.').pop()?.toUpperCase()}</span>\n </div>\n </div>\n `}\n\n <div class=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center\">\n <button\n type=\"button\"\n onclick=\"selectMediaFile('${file.id}', '${file.public_url.replace(/'/g, \"\\\\'\")}', '${file.filename.replace(/'/g, \"\\\\'\")}')\"\n class=\"px-4 py-2 bg-white dark:bg-zinc-900 text-zinc-950 dark:text-white rounded-lg font-medium hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors\"\n >\n Select\n </button>\n </div>\n </div>\n\n <div class=\"p-2\">\n <p class=\"text-xs text-zinc-700 dark:text-zinc-300 truncate\" title=\"${file.original_name}\">\n ${file.original_name}\n </p>\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400\">\n ${file.fileSize}\n </p>\n </div>\n </div>\n `).join(''))}\n </div>\n\n ${mediaFiles.length === 0 ? html`\n <div class=\"text-center py-12 text-zinc-500 dark:text-zinc-400\">\n <svg class=\"mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"></path>\n </svg>\n <p class=\"mt-2\">No media files found</p>\n </div>\n ` : ''}\n `)\n } catch (error) {\n console.error('Error loading media selector:', error)\n return c.html(html`<div class=\"text-red-500 dark:text-red-400\">Error loading media files</div>`)\n }\n})\n\n// Search media files (HTMX endpoint)\nadminMediaRoutes.get('/search', async (c) => {\n try {\n const { searchParams } = new URL(c.req.url)\n const search = searchParams.get('search') || ''\n const folder = searchParams.get('folder') || 'all'\n const type = searchParams.get('type') || 'all'\n const db = c.env.DB\n \n // Build search query\n let query = 'SELECT * FROM media'\n const params: any[] = []\n const conditions: string[] = []\n \n if (search.trim()) {\n conditions.push('(filename LIKE ? OR original_name LIKE ? OR alt LIKE ?)')\n const searchTerm = `%${search}%`\n params.push(searchTerm, searchTerm, searchTerm)\n }\n \n if (folder !== 'all') {\n conditions.push('folder = ?')\n params.push(folder)\n }\n \n if (type !== 'all') {\n switch (type) {\n case 'images':\n conditions.push('mime_type LIKE ?')\n params.push('image/%')\n break\n case 'documents':\n conditions.push('mime_type IN (?, ?, ?)')\n params.push('application/pdf', 'text/plain', 'application/msword')\n break\n case 'videos':\n conditions.push('mime_type LIKE ?')\n params.push('video/%')\n break\n }\n }\n \n if (conditions.length > 0) {\n query += ` WHERE ${conditions.join(' AND ')}`\n }\n \n query += ` ORDER BY uploaded_at DESC LIMIT 24`\n \n const stmt = db.prepare(query)\n const { results } = await stmt.bind(...params).all()\n \n const mediaFiles = results.map((row: any) => ({\n ...row,\n public_url: `/files/${row.r2_key}`,\n thumbnail_url: row.mime_type.startsWith('image/') ? `/files/${row.r2_key}` : undefined,\n tags: row.tags ? JSON.parse(row.tags) : [],\n uploadedAt: new Date(row.uploaded_at).toLocaleDateString(),\n fileSize: formatFileSize(row.size),\n isImage: row.mime_type.startsWith('image/'),\n isVideo: row.mime_type.startsWith('video/'),\n isDocument: !row.mime_type.startsWith('image/') && !row.mime_type.startsWith('video/')\n }))\n \n const gridHTML = mediaFiles.map(file => generateMediaItemHTML(file)).join('')\n \n return c.html(raw(gridHTML))\n } catch (error) {\n console.error('Error searching media:', error)\n return c.html('<div class=\"text-red-500\">Error searching files</div>')\n }\n})\n\n// Get file details modal (HTMX endpoint)\nadminMediaRoutes.get('/:id/details', async (c) => {\n try {\n const id = c.req.param('id')\n const db = c.env.DB\n \n const stmt = db.prepare('SELECT * FROM media WHERE id = ?')\n const result = await stmt.bind(id).first() as any\n \n if (!result) {\n return c.html('<div class=\"text-red-500\">File not found</div>')\n }\n \n const file: MediaFile & { width?: number; height?: number; folder: string; uploadedAt: string } = {\n id: result.id,\n filename: result.filename,\n original_name: result.original_name,\n mime_type: result.mime_type,\n size: result.size,\n public_url: `/files/${result.r2_key}`,\n thumbnail_url: result.mime_type.startsWith('image/') ? `/files/${result.r2_key}` : undefined,\n alt: result.alt,\n caption: result.caption,\n tags: result.tags ? JSON.parse(result.tags) : [],\n uploaded_at: result.uploaded_at,\n fileSize: formatFileSize(result.size),\n uploadedAt: new Date(result.uploaded_at).toLocaleString(),\n isImage: result.mime_type.startsWith('image/'),\n isVideo: result.mime_type.startsWith('video/'),\n isDocument: !result.mime_type.startsWith('image/') && !result.mime_type.startsWith('video/'),\n width: result.width,\n height: result.height,\n folder: result.folder\n }\n \n const detailsData: MediaFileDetailsData = { file }\n \n return c.html(renderMediaFileDetails(detailsData))\n } catch (error) {\n console.error('Error fetching file details:', error)\n return c.html('<div class=\"text-red-500\">Error loading file details</div>')\n }\n})\n\n// Upload files endpoint (HTMX compatible)\nadminMediaRoutes.post('/upload', async (c) => {\n try {\n const user = c.get('user')\n const formData = await c.req.formData()\n const files = formData.getAll('files') as File[]\n \n if (!files || files.length === 0) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n No files provided\n </div>\n `)\n }\n\n const uploadResults = []\n const errors = []\n\n for (const file of files) {\n try {\n // Validate file\n const validation = fileValidationSchema.safeParse({\n name: file.name,\n type: file.type,\n size: file.size\n })\n\n if (!validation.success) {\n errors.push({\n filename: file.name,\n error: validation.error.issues[0]?.message || 'Validation failed'\n })\n continue\n }\n\n // Generate unique filename and R2 key\n const fileId = globalThis.crypto.randomUUID()\n const fileExtension = file.name.split('.').pop() || ''\n const filename = `${fileId}.${fileExtension}`\n const folder = formData.get('folder') as string || 'uploads'\n const r2Key = `${folder}/${filename}`\n\n // Upload to R2\n const arrayBuffer = await file.arrayBuffer()\n const uploadResult = await c.env.MEDIA_BUCKET.put(r2Key, arrayBuffer, {\n httpMetadata: {\n contentType: file.type,\n contentDisposition: `inline; filename=\"${file.name}\"`\n },\n customMetadata: {\n originalName: file.name,\n uploadedBy: user!.userId,\n uploadedAt: new Date().toISOString()\n }\n })\n\n if (!uploadResult) {\n errors.push({\n filename: file.name,\n error: 'Failed to upload to storage'\n })\n continue\n }\n\n // Extract image dimensions if it's an image\n let width: number | undefined\n let height: number | undefined\n \n if (file.type.startsWith('image/') && !file.type.includes('svg')) {\n try {\n const dimensions = await getImageDimensions(arrayBuffer)\n width = dimensions.width\n height = dimensions.height\n } catch (error) {\n console.warn('Failed to extract image dimensions:', error)\n }\n }\n\n // Generate URLs - use public serving route\n const publicUrl = `/files/${r2Key}`\n const thumbnailUrl = file.type.startsWith('image/') ? publicUrl : undefined\n\n // Save to database\n const stmt = c.env.DB.prepare(`\n INSERT INTO media (\n id, filename, original_name, mime_type, size, width, height, \n folder, r2_key, public_url, thumbnail_url, uploaded_by, uploaded_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `)\n \n await stmt.bind(\n fileId,\n filename,\n file.name,\n file.type,\n file.size,\n width,\n height,\n folder,\n r2Key,\n publicUrl,\n thumbnailUrl,\n user!.userId,\n Math.floor(Date.now() / 1000)\n ).run()\n\n uploadResults.push({\n id: fileId,\n filename: filename,\n originalName: file.name,\n mimeType: file.type,\n size: file.size,\n publicUrl: publicUrl\n })\n } catch (error) {\n errors.push({\n filename: file.name,\n error: 'Upload failed: ' + (error instanceof Error ? error.message : 'Unknown error')\n })\n }\n }\n\n // TODO: Cache invalidation removed during migration\n\n // Fetch updated media list to include in response\n let mediaGridHTML = ''\n if (uploadResults.length > 0) {\n try {\n const folder = formData.get('folder') as string || 'uploads'\n const query = 'SELECT * FROM media WHERE deleted_at IS NULL ORDER BY uploaded_at DESC LIMIT 24'\n const stmt = c.env.DB.prepare(query)\n const { results } = await stmt.all()\n\n const mediaFiles = results.map((row: any) => ({\n id: row.id,\n filename: row.filename,\n original_name: row.original_name,\n mime_type: row.mime_type,\n size: row.size,\n public_url: `/files/${row.r2_key}`,\n thumbnail_url: row.mime_type.startsWith('image/') ? `/files/${row.r2_key}` : undefined,\n tags: row.tags ? JSON.parse(row.tags) : [],\n uploaded_at: row.uploaded_at,\n fileSize: formatFileSize(row.size),\n uploadedAt: new Date(row.uploaded_at).toLocaleDateString(),\n isImage: row.mime_type.startsWith('image/'),\n isVideo: row.mime_type.startsWith('video/'),\n isDocument: !row.mime_type.startsWith('image/') && !row.mime_type.startsWith('video/')\n }))\n\n mediaGridHTML = mediaFiles.map(file => renderMediaFileCard(file, 'grid', true)).join('')\n } catch (error) {\n console.error('Error fetching updated media list:', error)\n }\n }\n\n // Return HTMX response with results\n return c.html(html`\n ${uploadResults.length > 0 ? html`\n <div class=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-4\">\n Successfully uploaded ${uploadResults.length} file${uploadResults.length > 1 ? 's' : ''}\n </div>\n ` : ''}\n\n ${errors.length > 0 ? html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n <p class=\"font-medium\">Upload errors:</p>\n <ul class=\"list-disc list-inside mt-2\">\n ${errors.map(error => html`\n <li>${error.filename}: ${error.error}</li>\n `)}\n </ul>\n </div>\n ` : ''}\n\n ${uploadResults.length > 0 ? html`\n <script>\n // Close modal and refresh page after successful upload with cache busting\n setTimeout(() => {\n document.getElementById('upload-modal').classList.add('hidden');\n window.location.href = '/admin/media?t=' + Date.now();\n }, 1500);\n </script>\n ` : ''}\n `)\n } catch (error) {\n console.error('Upload error:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Upload failed: ${error instanceof Error ? error.message : 'Unknown error'}\n </div>\n `)\n }\n})\n\n// Serve files from R2 storage\nadminMediaRoutes.get('/file/*', async (c) => {\n try {\n const r2Key = c.req.path.replace('/admin/media/file/', '')\n \n if (!r2Key) {\n return c.notFound()\n }\n\n // Get file from R2\n const object = await c.env.MEDIA_BUCKET.get(r2Key)\n \n if (!object) {\n return c.notFound()\n }\n\n // Set appropriate headers\n const headers = new Headers()\n object.httpMetadata?.contentType && headers.set('Content-Type', object.httpMetadata.contentType)\n object.httpMetadata?.contentDisposition && headers.set('Content-Disposition', object.httpMetadata.contentDisposition)\n headers.set('Cache-Control', 'public, max-age=31536000') // 1 year cache\n \n return new Response(object.body as any, {\n headers\n })\n } catch (error) {\n console.error('Error serving file:', error)\n return c.notFound()\n }\n})\n\n// Update media file metadata (HTMX compatible)\nadminMediaRoutes.put('/:id', async (c) => {\n try {\n const user = c.get('user')\n const fileId = c.req.param('id')\n const formData = await c.req.formData()\n \n // Get file record\n const stmt = c.env.DB.prepare('SELECT * FROM media WHERE id = ? AND deleted_at IS NULL')\n const fileRecord = await stmt.bind(fileId).first() as any\n \n if (!fileRecord) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4\">\n File not found\n </div>\n `)\n }\n\n // Check permissions (only allow updates by uploader or admin)\n if (fileRecord.uploaded_by !== user!.userId && user!.role !== 'admin') {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4\">\n Permission denied\n </div>\n `)\n }\n\n // Extract form data\n const alt = formData.get('alt') as string || null\n const caption = formData.get('caption') as string || null\n const tagsString = formData.get('tags') as string || ''\n const tags = tagsString ? tagsString.split(',').map(tag => tag.trim()).filter(tag => tag) : []\n\n // Update database\n const updateStmt = c.env.DB.prepare(`\n UPDATE media \n SET alt = ?, caption = ?, tags = ?, updated_at = ?\n WHERE id = ?\n `)\n await updateStmt.bind(\n alt,\n caption,\n JSON.stringify(tags),\n Math.floor(Date.now() / 1000),\n fileId\n ).run()\n\n // TODO: Cache invalidation removed during migration\n\n return c.html(html`\n <div class=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-4\">\n File updated successfully\n </div>\n <script>\n // Refresh the file details\n setTimeout(() => {\n htmx.trigger('#file-modal-content', 'htmx:load');\n }, 1000);\n </script>\n `)\n } catch (error) {\n console.error('Update error:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4\">\n Update failed: ${error instanceof Error ? error.message : 'Unknown error'}\n </div>\n `)\n }\n})\n\n// Delete media file (HTMX compatible)\nadminMediaRoutes.delete('/:id', async (c) => {\n try {\n const user = c.get('user')\n const fileId = c.req.param('id')\n \n // Get file record\n const stmt = c.env.DB.prepare('SELECT * FROM media WHERE id = ? AND deleted_at IS NULL')\n const fileRecord = await stmt.bind(fileId).first() as any\n \n if (!fileRecord) {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4\">\n File not found\n </div>\n `)\n }\n\n // Check permissions (only allow deletion by uploader or admin)\n if (fileRecord.uploaded_by !== user!.userId && user!.role !== 'admin') {\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4\">\n Permission denied\n </div>\n `)\n }\n\n // Delete from R2\n try {\n await c.env.MEDIA_BUCKET.delete(fileRecord.r2_key)\n } catch (error) {\n console.warn('Failed to delete from R2:', error)\n // Continue with database deletion even if R2 deletion fails\n }\n\n // Soft delete in database\n const deleteStmt = c.env.DB.prepare('UPDATE media SET deleted_at = ? WHERE id = ?')\n await deleteStmt.bind(Math.floor(Date.now() / 1000), fileId).run()\n\n // TODO: Cache invalidation removed during migration\n\n // Return HTMX response that redirects to media library\n return c.html(html`\n <script>\n // Close modal if open\n const modal = document.getElementById('file-modal');\n if (modal) {\n modal.classList.add('hidden');\n }\n // Redirect to media library\n window.location.href = '/admin/media';\n </script>\n `)\n } catch (error) {\n console.error('Delete error:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4\">\n Delete failed: ${error instanceof Error ? error.message : 'Unknown error'}\n </div>\n `)\n }\n})\n\n// Helper function to extract image dimensions\nasync function getImageDimensions(arrayBuffer: ArrayBuffer): Promise<{ width: number; height: number }> {\n const uint8Array = new Uint8Array(arrayBuffer)\n \n // Check for JPEG\n if (uint8Array[0] === 0xFF && uint8Array[1] === 0xD8) {\n return getJPEGDimensions(uint8Array)\n }\n \n // Check for PNG\n if (uint8Array[0] === 0x89 && uint8Array[1] === 0x50 && uint8Array[2] === 0x4E && uint8Array[3] === 0x47) {\n return getPNGDimensions(uint8Array)\n }\n \n // Default fallback\n return { width: 0, height: 0 }\n}\n\nfunction getJPEGDimensions(uint8Array: Uint8Array): { width: number; height: number } {\n let i = 2\n while (i < uint8Array.length - 8) {\n if (uint8Array[i] === 0xFF && uint8Array[i + 1] === 0xC0) {\n return {\n height: (uint8Array[i + 5]! << 8) | uint8Array[i + 6]!,\n width: (uint8Array[i + 7]! << 8) | uint8Array[i + 8]!\n }\n }\n const segmentLength = (uint8Array[i + 2]! << 8) | uint8Array[i + 3]!\n i += 2 + segmentLength\n }\n return { width: 0, height: 0 }\n}\n\nfunction getPNGDimensions(uint8Array: Uint8Array): { width: number; height: number } {\n if (uint8Array.length < 24) {\n return { width: 0, height: 0 }\n }\n return {\n width: (uint8Array[16]! << 24) | (uint8Array[17]! << 16) | (uint8Array[18]! << 8) | uint8Array[19]!,\n height: (uint8Array[20]! << 24) | (uint8Array[21]! << 16) | (uint8Array[22]! << 8) | uint8Array[23]!\n }\n}\n\n// Helper function to generate media item HTML\nfunction generateMediaItemHTML(file: any): string {\n const isImage = file.isImage\n const isVideo = file.isVideo\n \n return `\n <div \n class=\"media-item bg-white rounded-lg shadow-sm overflow-hidden cursor-pointer\" \n data-file-id=\"${file.id}\"\n onclick=\"toggleFileSelection('${file.id}')\"\n >\n <div class=\"aspect-square relative\">\n ${isImage ? `\n <img \n src=\"${file.public_url}\" \n alt=\"${file.alt || file.filename}\"\n class=\"w-full h-full object-cover\"\n loading=\"lazy\"\n >\n ` : isVideo ? `\n <video \n src=\"${file.public_url}\" \n class=\"w-full h-full object-cover\"\n muted\n ></video>\n ` : `\n <div class=\"w-full h-full flex items-center justify-center bg-gray-100\">\n <div class=\"text-center\">\n <svg class=\"file-icon mx-auto text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"></path>\n </svg>\n <span class=\"text-xs text-gray-500 mt-1\">${file.filename.split('.').pop()?.toUpperCase()}</span>\n </div>\n </div>\n `}\n \n <div class=\"preview-overlay flex items-center justify-center\">\n <div class=\"flex space-x-2\">\n <button \n onclick=\"event.stopPropagation(); showFileDetails('${file.id}')\"\n class=\"p-2 bg-white bg-opacity-20 rounded-full hover:bg-opacity-30\"\n >\n <svg class=\"w-5 h-5 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"></path>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"></path>\n </svg>\n </button>\n <button \n onclick=\"event.stopPropagation(); copyToClipboard('${file.public_url}')\"\n class=\"p-2 bg-white bg-opacity-20 rounded-full hover:bg-opacity-30\"\n >\n <svg class=\"w-5 h-5 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"></path>\n </svg>\n </button>\n </div>\n </div>\n </div>\n \n <div class=\"p-3\">\n <h4 class=\"text-sm font-medium text-gray-900 truncate\" title=\"${file.original_name}\">\n ${file.original_name}\n </h4>\n <div class=\"flex justify-between items-center mt-1\">\n <span class=\"text-xs text-gray-500\">${file.fileSize}</span>\n <span class=\"text-xs text-gray-500\">${file.uploadedAt}</span>\n </div>\n ${file.tags.length > 0 ? `\n <div class=\"flex flex-wrap gap-1 mt-2\">\n ${file.tags.slice(0, 2).map((tag: string) => `\n <span class=\"inline-block px-2 py-1 text-xs bg-gray-100 text-gray-600 rounded\">\n ${tag}\n </span>\n `).join('')}\n ${file.tags.length > 2 ? `<span class=\"text-xs text-gray-400\">+${file.tags.length - 2}</span>` : ''}\n </div>\n ` : ''}\n </div>\n </div>\n `\n}\n\n// Helper function to format file size\nfunction formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes'\n const k = 1024\n const sizes = ['Bytes', 'KB', 'MB', 'GB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]\n}\n\nexport { adminMediaRoutes }","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\nimport { renderConfirmationDialog, getConfirmationDialogScript } from '../components/confirmation-dialog.template'\n\nexport interface Plugin {\n id: string\n name: string\n displayName: string\n description: string\n version: string\n author: string\n status: 'active' | 'inactive' | 'error'\n category: string\n icon: string\n downloadCount?: number\n rating?: number\n lastUpdated: string\n dependencies?: string[]\n permissions?: string[]\n isCore?: boolean\n}\n\nexport interface PluginsListPageData {\n plugins: Plugin[]\n stats?: {\n total: number\n active: number\n inactive: number\n errors: number\n }\n user?: {\n name: string\n email: string\n role: string\n }\n version?: string\n}\n\nexport function renderPluginsListPage(data: PluginsListPageData): string {\n const pageContent = `\n <div>\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">Plugins</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">Manage and extend functionality with plugins</p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none\">\n <div class=\"relative inline-block text-left\">\n <button onclick=\"toggleDropdown()\" class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n Install Plugin\n <svg class=\"-mr-1 ml-2 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n <div id=\"plugin-dropdown\" class=\"hidden absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-xl bg-white dark:bg-zinc-900 shadow-xl ring-1 ring-zinc-950/5 dark:ring-white/10 focus:outline-none\">\n <div class=\"py-1\">\n <button onclick=\"installPlugin('faq-plugin')\" class=\"block w-full text-left px-4 py-2 text-sm text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors first:rounded-t-xl\">\n <div class=\"flex items-center\">\n <span class=\"text-lg mr-2\">❓</span>\n <div>\n <div class=\"font-medium\">FAQ System</div>\n <div class=\"text-xs text-zinc-500 dark:text-zinc-400\">Community FAQ management plugin</div>\n </div>\n </div>\n </button>\n <div class=\"border-t border-zinc-950/5 dark:border-white/10 my-1\"></div>\n <button onclick=\"showNotification('Plugin marketplace coming soon!', 'info')\" class=\"block w-full text-left px-4 py-2 text-sm text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors last:rounded-b-xl\">\n <div class=\"flex items-center\">\n <svg class=\"w-5 h-5 mr-2 text-zinc-500 dark:text-zinc-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z\" />\n </svg>\n <div>\n <div class=\"font-medium\">Browse Marketplace</div>\n <div class=\"text-xs text-zinc-500 dark:text-zinc-400\">Discover more plugins</div>\n </div>\n </div>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Stats -->\n <div class=\"mb-6\">\n <h3 class=\"text-base font-semibold text-zinc-950 dark:text-white\">Plugin Statistics</h3>\n <dl class=\"mt-5 grid grid-cols-1 divide-zinc-950/5 dark:divide-white/10 overflow-hidden rounded-lg bg-zinc-800/75 dark:bg-zinc-800/75 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 md:grid-cols-4 md:divide-x md:divide-y-0\">\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Total Plugins</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-cyan-400\">\n ${data.stats?.total || 0}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-lime-400/10 text-lime-600 dark:text-lime-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Increased by</span>\n 8.5%\n </div>\n </dd>\n </div>\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Active Plugins</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-lime-400\">\n ${data.stats?.active || 0}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-lime-400/10 text-lime-600 dark:text-lime-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Increased by</span>\n 12.3%\n </div>\n </dd>\n </div>\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Inactive Plugins</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-purple-400\">\n ${data.stats?.inactive || 0}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-pink-400/10 text-pink-600 dark:text-pink-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 3a.75.75 0 0 1 .75.75v10.638l3.96-4.158a.75.75 0 1 1 1.08 1.04l-5.25 5.5a.75.75 0 0 1-1.08 0l-5.25-5.5a.75.75 0 1 1 1.08-1.04l3.96 4.158V3.75A.75.75 0 0 1 10 3Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Decreased by</span>\n 3.2%\n </div>\n </dd>\n </div>\n <div class=\"px-4 py-5 sm:p-6\">\n <dt class=\"text-base font-normal text-zinc-700 dark:text-zinc-100\">Plugin Errors</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-pink-400\">\n ${data.stats?.errors || 0}\n </div>\n <div class=\"inline-flex items-baseline rounded-full bg-pink-400/10 text-pink-600 dark:text-pink-400 px-2.5 py-0.5 text-sm font-medium md:mt-2 lg:mt-0\">\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"-ml-1 mr-0.5 size-5 shrink-0 self-center\">\n <path d=\"M10 3a.75.75 0 0 1 .75.75v10.638l3.96-4.158a.75.75 0 1 1 1.08 1.04l-5.25 5.5a.75.75 0 0 1-1.08 0l-5.25-5.5a.75.75 0 1 1 1.08-1.04l3.96 4.158V3.75A.75.75 0 0 1 10 3Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n <span class=\"sr-only\">Decreased by</span>\n 1.5%\n </div>\n </dd>\n </div>\n </dl>\n </div>\n\n <!-- Filters -->\n <div class=\"relative rounded-xl overflow-hidden mb-6\">\n <!-- Gradient Background -->\n <div class=\"absolute inset-0 bg-gradient-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10 dark:from-cyan-400/20 dark:via-blue-400/20 dark:to-purple-400/20\"></div>\n\n <div class=\"relative bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10\">\n <div class=\"px-6 py-5\">\n <div class=\"flex items-center justify-between\">\n <div class=\"flex items-center space-x-4 flex-1\">\n <div>\n <label class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">Category</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-cyan-500/30 dark:outline-cyan-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-cyan-500 dark:focus-visible:outline-cyan-400 sm:text-sm/6 min-w-48\">\n <option value=\"\">All Categories</option>\n <option value=\"content\">Content Management</option>\n <option value=\"media\">Media</option>\n <option value=\"seo\">SEO & Analytics</option>\n <option value=\"security\">Security</option>\n <option value=\"utilities\">Utilities</option>\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-cyan-600 dark:text-cyan-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n <div>\n <label class=\"block text-sm/6 font-medium text-zinc-950 dark:text-white\">Status</label>\n <div class=\"mt-2 grid grid-cols-1\">\n <select class=\"col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-cyan-500/30 dark:outline-cyan-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-cyan-500 dark:focus-visible:outline-cyan-400 sm:text-sm/6 min-w-48\">\n <option value=\"\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n <option value=\"error\">Error</option>\n </select>\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" data-slot=\"icon\" aria-hidden=\"true\" class=\"pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-cyan-600 dark:text-cyan-400 sm:size-4\">\n <path d=\"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" fill-rule=\"evenodd\" />\n </svg>\n </div>\n </div>\n <div class=\"flex-1 max-w-md\">\n <label class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Search</label>\n <div class=\"relative group\">\n <div class=\"absolute left-3.5 top-2.5 flex items-center justify-center w-5 h-5 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 dark:from-cyan-300 dark:to-blue-400 opacity-90 group-focus-within:opacity-100 transition-opacity\">\n <svg class=\"h-3 w-3 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"/>\n </svg>\n </div>\n <input\n type=\"text\"\n placeholder=\"Search plugins...\"\n class=\"w-full rounded-full bg-transparent px-11 py-2 text-sm text-zinc-950 dark:text-white placeholder-zinc-500 dark:placeholder-zinc-400 border-2 border-cyan-200/50 dark:border-cyan-700/50 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n />\n </div>\n </div>\n </div>\n <div class=\"flex items-center gap-x-3 ml-4\">\n <button\n onclick=\"location.reload()\"\n class=\"inline-flex items-center gap-x-1.5 px-3 py-1.5 bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm text-zinc-950 dark:text-white text-sm font-medium rounded-full ring-1 ring-inset ring-cyan-200/50 dark:ring-cyan-700/50 hover:bg-gradient-to-r hover:from-cyan-50 hover:to-blue-50 dark:hover:from-cyan-900/30 dark:hover:to-blue-900/30 hover:ring-cyan-300 dark:hover:ring-cyan-600 transition-all duration-200\"\n >\n <svg class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"/>\n </svg>\n Refresh\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Plugins Grid -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6\">\n ${data.plugins.map(plugin => renderPluginCard(plugin)).join('')}\n </div>\n\n <script>\n async function togglePlugin(pluginId, action) {\n const button = event.target;\n const originalText = button.textContent;\n button.disabled = true;\n button.textContent = action === 'activate' ? 'Activating...' : 'Deactivating...';\n \n try {\n const response = await fetch(\\`/admin/plugins/\\${pluginId}/\\${action}\\`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n \n const result = await response.json();\n \n if (result.success) {\n // Update UI\n const card = button.closest('.plugin-card');\n const statusBadge = card.querySelector('.status-badge');\n\n if (action === 'activate') {\n // Update status badge\n statusBadge.className = 'status-badge inline-flex items-center rounded-md px-2.5 py-1 text-sm font-medium ring-1 ring-inset bg-lime-50 dark:bg-lime-500/10 text-lime-700 dark:text-lime-300 ring-lime-700/10 dark:ring-lime-400/20';\n statusBadge.innerHTML = '<div class=\"w-2 h-2 bg-lime-500 dark:bg-lime-400 rounded-full mr-2\"></div>Active';\n // Update card border to green\n card.className = 'plugin-card rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-[3px] ring-lime-500 dark:ring-lime-400 p-6 hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-all';\n // Update button\n button.textContent = 'Deactivate';\n button.onclick = () => togglePlugin(pluginId, 'deactivate');\n button.className = 'bg-red-600 dark:bg-red-700 hover:bg-red-700 dark:hover:bg-red-600 text-white px-3 py-1.5 rounded-lg text-sm font-medium transition-colors';\n } else {\n // Update status badge\n statusBadge.className = 'status-badge inline-flex items-center rounded-md px-2.5 py-1 text-sm font-medium ring-1 ring-inset bg-zinc-50 dark:bg-zinc-500/10 text-zinc-700 dark:text-zinc-400 ring-zinc-700/10 dark:ring-zinc-400/20';\n statusBadge.innerHTML = '<div class=\"w-2 h-2 bg-zinc-500 dark:bg-zinc-400 rounded-full mr-2\"></div>Inactive';\n // Update card border to pink\n card.className = 'plugin-card rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-[3px] ring-pink-500 dark:ring-pink-400 p-6 hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-all';\n // Update button\n button.textContent = 'Activate';\n button.onclick = () => togglePlugin(pluginId, 'activate');\n button.className = 'bg-lime-600 dark:bg-lime-700 hover:bg-lime-700 dark:hover:bg-lime-600 text-white px-3 py-1.5 rounded-lg text-sm font-medium transition-colors';\n }\n\n showNotification(\\`Plugin \\${action}d successfully\\`, 'success');\n } else {\n throw new Error(result.error || \\`Failed to \\${action} plugin\\`);\n }\n } catch (error) {\n showNotification(error.message, 'error');\n button.textContent = originalText;\n } finally {\n button.disabled = false;\n }\n }\n \n async function installPlugin(pluginName) {\n const button = event.target;\n button.disabled = true;\n button.textContent = 'Installing...';\n \n try {\n const response = await fetch('/admin/plugins/install', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({ name: pluginName })\n });\n \n const result = await response.json();\n \n if (result.success) {\n showNotification('Plugin installed successfully!', 'success');\n setTimeout(() => location.reload(), 1500);\n } else {\n throw new Error(result.error || 'Failed to install plugin');\n }\n } catch (error) {\n showNotification(error.message, 'error');\n button.disabled = false;\n button.textContent = 'Install';\n }\n }\n \n let pluginToUninstall = null;\n\n async function uninstallPlugin(pluginId) {\n pluginToUninstall = pluginId;\n showConfirmDialog('uninstall-plugin-confirm');\n }\n\n async function performUninstallPlugin() {\n if (!pluginToUninstall) return;\n\n const button = event.target;\n if (button) button.disabled = true;\n\n try {\n const response = await fetch(\\`/admin/plugins/\\${pluginToUninstall}/uninstall\\`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n\n const result = await response.json();\n\n if (result.success) {\n showNotification('Plugin uninstalled successfully!', 'success');\n setTimeout(() => location.reload(), 1500);\n } else {\n throw new Error(result.error || 'Failed to uninstall plugin');\n }\n } catch (error) {\n showNotification(error.message, 'error');\n if (button) button.disabled = false;\n } finally {\n pluginToUninstall = null;\n }\n }\n \n function openPluginSettings(pluginId) {\n window.location.href = \\`/admin/plugins/\\${pluginId}\\`;\n }\n \n function showPluginDetails(pluginId) {\n // TODO: Implement plugin details modal\n showNotification('Plugin details coming soon!', 'info');\n }\n \n function showNotification(message, type) {\n const notification = document.createElement('div');\n const bgColor = type === 'success' ? 'bg-green-600' : type === 'error' ? 'bg-red-600' : 'bg-blue-600';\n notification.className = \\`fixed top-4 right-4 px-4 py-2 rounded-lg text-white z-50 \\${bgColor}\\`;\n notification.textContent = message;\n document.body.appendChild(notification);\n \n setTimeout(() => {\n notification.remove();\n }, 3000);\n }\n \n function toggleDropdown() {\n const dropdown = document.getElementById('plugin-dropdown');\n dropdown.classList.toggle('hidden');\n }\n \n // Close dropdown when clicking outside\n document.addEventListener('click', (event) => {\n const dropdown = document.getElementById('plugin-dropdown');\n const button = event.target.closest('button[onclick=\"toggleDropdown()\"]');\n \n if (!button && !dropdown.contains(event.target)) {\n dropdown.classList.add('hidden');\n }\n });\n </script>\n\n <!-- Confirmation Dialogs -->\n ${renderConfirmationDialog({\n id: 'uninstall-plugin-confirm',\n title: 'Uninstall Plugin',\n message: 'Are you sure you want to uninstall this plugin? This action cannot be undone.',\n confirmText: 'Uninstall',\n cancelText: 'Cancel',\n iconColor: 'red',\n confirmClass: 'bg-red-500 hover:bg-red-400',\n onConfirm: 'performUninstallPlugin()'\n })}\n\n ${getConfirmationDialogScript()}\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: 'Plugins',\n pageTitle: 'Plugin Management',\n currentPath: '/admin/plugins',\n user: data.user,\n version: data.version,\n content: pageContent\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}\n\nfunction renderPluginCard(plugin: Plugin): string {\n const statusColors = {\n active: 'bg-lime-50 dark:bg-lime-500/10 text-lime-700 dark:text-lime-300 ring-lime-700/10 dark:ring-lime-400/20',\n inactive: 'bg-zinc-50 dark:bg-zinc-500/10 text-zinc-700 dark:text-zinc-400 ring-zinc-700/10 dark:ring-zinc-400/20',\n error: 'bg-red-50 dark:bg-red-500/10 text-red-700 dark:text-red-400 ring-red-700/10 dark:ring-red-400/20'\n }\n\n const statusIcons = {\n active: '<div class=\"w-2 h-2 bg-lime-500 dark:bg-lime-400 rounded-full mr-2\"></div>',\n inactive: '<div class=\"w-2 h-2 bg-zinc-500 dark:bg-zinc-400 rounded-full mr-2\"></div>',\n error: '<div class=\"w-2 h-2 bg-red-500 dark:bg-red-400 rounded-full mr-2\"></div>'\n }\n\n // Border colors based on status\n const borderColors = {\n active: 'ring-[3px] ring-lime-500 dark:ring-lime-400',\n inactive: 'ring-[3px] ring-pink-500 dark:ring-pink-400',\n error: 'ring-[3px] ring-red-500 dark:ring-red-400'\n }\n\n // Core system plugins that cannot be deactivated\n const criticalCorePlugins = ['core-auth', 'core-media']\n const canToggle = !criticalCorePlugins.includes(plugin.id)\n\n const actionButton = plugin.status === 'active'\n ? `<button onclick=\"togglePlugin('${plugin.id}', 'deactivate')\" class=\"bg-red-600 dark:bg-red-700 hover:bg-red-700 dark:hover:bg-red-600 text-white px-3 py-1.5 rounded-lg text-sm font-medium transition-colors\">Deactivate</button>`\n : `<button onclick=\"togglePlugin('${plugin.id}', 'activate')\" class=\"bg-lime-600 dark:bg-lime-700 hover:bg-lime-700 dark:hover:bg-lime-600 text-white px-3 py-1.5 rounded-lg text-sm font-medium transition-colors\">Activate</button>`\n\n return `\n <div class=\"plugin-card rounded-xl bg-white dark:bg-zinc-900 shadow-sm ${borderColors[plugin.status]} p-6 hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-all\">\n <div class=\"flex items-start justify-between mb-4\">\n <div class=\"flex items-center gap-3\">\n <div class=\"w-12 h-12 rounded-lg flex items-center justify-center ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 bg-zinc-50 dark:bg-zinc-800\">\n ${plugin.icon || getDefaultPluginIcon(plugin.category)}\n </div>\n <div>\n <h3 class=\"text-lg font-semibold text-zinc-950 dark:text-white\">${plugin.displayName}</h3>\n <p class=\"text-sm text-zinc-500 dark:text-zinc-400\">v${plugin.version} by ${plugin.author}</p>\n </div>\n </div>\n <div class=\"flex flex-col items-end gap-2\">\n <span class=\"status-badge inline-flex items-center rounded-md px-2.5 py-1 text-sm font-medium ring-1 ring-inset ${statusColors[plugin.status]}\">\n ${statusIcons[plugin.status]}${plugin.status.charAt(0).toUpperCase() + plugin.status.slice(1)}\n </span>\n ${plugin.isCore ? '<span class=\"inline-flex items-center rounded-md px-2.5 py-1 text-sm font-medium bg-cyan-50 dark:bg-cyan-500/10 text-cyan-700 dark:text-cyan-300 ring-1 ring-inset ring-cyan-700/10 dark:ring-cyan-400/20\">Core</span>' : ''}\n </div>\n </div>\n\n <p class=\"text-zinc-600 dark:text-zinc-300 text-sm mb-4 line-clamp-3\">${plugin.description}</p>\n\n <div class=\"flex items-center gap-4 mb-4 text-xs text-zinc-500 dark:text-zinc-400\">\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z\"/>\n </svg>\n ${plugin.category}\n </span>\n\n ${plugin.downloadCount ? `\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\"/>\n </svg>\n ${plugin.downloadCount.toLocaleString()}\n </span>\n ` : ''}\n\n ${plugin.rating ? `\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-4 h-4 text-yellow-500 dark:text-yellow-400 fill-current\" viewBox=\"0 0 24 24\">\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"/>\n </svg>\n ${plugin.rating}\n </span>\n ` : ''}\n\n <span>${plugin.lastUpdated}</span>\n </div>\n\n ${plugin.dependencies && plugin.dependencies.length > 0 ? `\n <div class=\"mb-4\">\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mb-2\">Dependencies:</p>\n <div class=\"flex flex-wrap gap-1\">\n ${plugin.dependencies.map(dep => `<span class=\"inline-block bg-zinc-100 dark:bg-zinc-800 text-zinc-700 dark:text-zinc-300 text-xs px-2 py-1 rounded\">${dep}</span>`).join('')}\n </div>\n </div>\n ` : ''}\n\n <div class=\"flex items-center justify-between\">\n <div class=\"flex gap-2\">\n ${canToggle ? actionButton : ''}\n <button onclick=\"openPluginSettings('${plugin.id}')\" class=\"bg-white dark:bg-zinc-800 hover:bg-zinc-50 dark:hover:bg-zinc-700 text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors\">\n Settings\n </button>\n </div>\n\n <div class=\"flex items-center gap-2\">\n <button onclick=\"showPluginDetails('${plugin.id}')\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300 p-1.5 rounded-lg hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors\" title=\"Plugin Details\">\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/>\n </svg>\n </button>\n\n ${!plugin.isCore ? `\n <button onclick=\"uninstallPlugin('${plugin.id}')\" class=\"text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 p-1.5 rounded-lg hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors\" title=\"Uninstall Plugin\">\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"/>\n </svg>\n </button>\n ` : ''}\n </div>\n </div>\n </div>\n `\n}\n\nfunction getDefaultPluginIcon(category: string): string {\n const iconColor = 'text-zinc-600 dark:text-zinc-400'\n\n const icons: Record<string, string> = {\n 'content': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z\" />\n </svg>\n `,\n 'media': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z\" />\n </svg>\n `,\n 'seo': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\" />\n </svg>\n `,\n 'analytics': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n `,\n 'ecommerce': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84M7.5 14.25 5.106 5.272M6 20.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm12.75 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z\" />\n </svg>\n `,\n 'email': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75\" />\n </svg>\n `,\n 'workflow': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99\" />\n </svg>\n `,\n 'security': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z\" />\n </svg>\n `,\n 'social': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M18 18.72a9.094 9.094 0 0 0 3.741-.479 3 3 0 0 0-4.682-2.72m.94 3.198.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0 1 12 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 0 1 6 18.719m12 0a5.971 5.971 0 0 0-.941-3.197m0 0A5.995 5.995 0 0 0 12 12.75a5.995 5.995 0 0 0-5.058 2.772m0 0a3 3 0 0 0-4.681 2.72 8.986 8.986 0 0 0 3.74.477m.94-3.197a5.971 5.971 0 0 0-.94 3.197M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z\" />\n </svg>\n `,\n 'utility': `\n <svg class=\"w-6 h-6 ${iconColor}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z\" />\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z\" />\n </svg>\n `,\n }\n\n const iconKey = category.toLowerCase() as keyof typeof icons\n return icons[iconKey] || icons['utility'] || ''\n}\n\n// Mock data generator\nexport function generateMockPlugins(): Plugin[] {\n return [\n {\n id: '1',\n name: 'seo-optimizer',\n displayName: 'SEO Optimizer',\n description: 'Advanced SEO optimization tools including meta tag management, sitemap generation, and analytics integration. Boost your search engine rankings with automated optimizations.',\n version: '2.1.4',\n author: 'SonicJS Team',\n status: 'active',\n category: 'seo',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 10V3L4 14h7v7l9-11h-7z\"/></svg>`,\n downloadCount: 15420,\n rating: 4.8,\n lastUpdated: '2 days ago',\n dependencies: ['analytics-plugin'],\n permissions: ['read:content', 'write:meta'],\n isCore: true\n },\n {\n id: '2',\n name: 'image-optimizer',\n displayName: 'Image Optimizer',\n description: 'Automatically compress and optimize images on upload. Supports WebP conversion, lazy loading, and responsive image generation for better performance.',\n version: '1.5.2',\n author: 'MediaPro',\n status: 'active',\n category: 'media',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"/></svg>`,\n downloadCount: 8930,\n rating: 4.6,\n lastUpdated: '1 week ago',\n dependencies: [],\n permissions: ['write:media', 'read:settings']\n },\n {\n id: '3',\n name: 'backup-manager',\n displayName: 'Backup Manager',\n description: 'Automated backup solution for content and media files. Schedule regular backups to cloud storage with encryption and restore capabilities.',\n version: '3.0.1',\n author: 'BackupCorp',\n status: 'inactive',\n category: 'utilities',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4\"/></svg>`,\n downloadCount: 12450,\n rating: 4.9,\n lastUpdated: '3 days ago',\n dependencies: ['cloud-storage'],\n permissions: ['read:all', 'write:backups']\n },\n {\n id: '4',\n name: 'security-scanner',\n displayName: 'Security Scanner',\n description: 'Real-time security monitoring and vulnerability scanning. Detects malware, suspicious activities, and provides security recommendations.',\n version: '1.2.8',\n author: 'SecureWeb',\n status: 'error',\n category: 'security',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z\"/></svg>`,\n downloadCount: 5680,\n rating: 4.3,\n lastUpdated: '5 days ago',\n dependencies: ['security-core'],\n permissions: ['read:logs', 'read:files', 'write:security']\n },\n {\n id: '5',\n name: 'social-share',\n displayName: 'Social Share',\n description: 'Easy social media sharing buttons and Open Graph meta tag generation. Supports all major social platforms with customizable styling.',\n version: '2.3.0',\n author: 'SocialPlus',\n status: 'active',\n category: 'content',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z\"/></svg>`,\n downloadCount: 22100,\n rating: 4.7,\n lastUpdated: '4 days ago',\n dependencies: [],\n permissions: ['read:content', 'write:meta']\n },\n {\n id: '6',\n name: 'analytics-pro',\n displayName: 'Analytics Pro',\n description: 'Advanced analytics dashboard with custom tracking events, conversion funnels, and detailed visitor insights. GDPR compliant with privacy controls.',\n version: '4.1.2',\n author: 'AnalyticsPro Inc',\n status: 'active',\n category: 'seo',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z\"/></svg>`,\n downloadCount: 18750,\n rating: 4.9,\n lastUpdated: '1 day ago',\n dependencies: ['gdpr-compliance'],\n permissions: ['read:analytics', 'write:tracking', 'read:users']\n },\n {\n id: '7',\n name: 'form-builder',\n displayName: 'Advanced Form Builder',\n description: 'Drag-and-drop form builder with conditional logic, file uploads, payment integration, and email notifications. Perfect for contact forms and surveys.',\n version: '1.8.5',\n author: 'FormWorks',\n status: 'inactive',\n category: 'content',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"/></svg>`,\n downloadCount: 9870,\n rating: 4.4,\n lastUpdated: '1 week ago',\n dependencies: ['email-service'],\n permissions: ['write:forms', 'read:submissions', 'send:emails']\n },\n {\n id: '8',\n name: 'cache-optimizer',\n displayName: 'Cache Optimizer',\n description: 'Intelligent caching system with Redis support, CDN integration, and automatic cache invalidation. Dramatically improves site performance.',\n version: '2.7.3',\n author: 'SpeedBoost',\n status: 'active',\n category: 'utilities',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 10V3L4 14h7v7l9-11h-7z\"/></svg>`,\n downloadCount: 13240,\n rating: 4.8,\n lastUpdated: '6 days ago',\n dependencies: ['redis-connector'],\n permissions: ['read:cache', 'write:cache', 'manage:cdn'],\n isCore: true\n },\n {\n id: '9',\n name: 'multilingual',\n displayName: 'Multilingual Support',\n description: 'Complete internationalization solution with automatic translation, language detection, and localized content management for global websites.',\n version: '3.2.1',\n author: 'GlobalWeb',\n status: 'active',\n category: 'content',\n icon: `<svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129\"/></svg>`,\n downloadCount: 7650,\n rating: 4.5,\n lastUpdated: '2 weeks ago',\n dependencies: ['translation-api'],\n permissions: ['read:content', 'write:translations', 'manage:languages']\n }\n ]\n}","import type { AuthSettings } from '../../services/auth-validation'\n\nexport function renderAuthSettingsForm(settings: AuthSettings): string {\n const fields = settings.requiredFields\n const validation = settings.validation\n const registration = settings.registration\n\n return `\n <div class=\"space-y-8\">\n <!-- Required Fields Section -->\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Registration Fields</h3>\n <p class=\"text-sm text-gray-400 mb-6\">Configure which fields are required during user registration and their minimum lengths.</p>\n\n <div class=\"space-y-6\">\n ${Object.entries(fields).map(([fieldName, config]) => `\n <div class=\"border-b border-white/10 pb-6 last:border-b-0 last:pb-0\">\n <div class=\"flex items-start justify-between mb-4\">\n <div>\n <h4 class=\"text-sm font-medium text-white\">${config.label}</h4>\n <p class=\"text-xs text-gray-400 mt-1\">Field type: ${config.type}</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"requiredFields_${fieldName}_required\"\n ${config.required ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n <span class=\"ml-3 text-sm font-medium text-gray-300\">Required</span>\n </label>\n </div>\n\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-xs font-medium text-gray-400 mb-2\">Minimum Length</label>\n <input\n type=\"number\"\n name=\"requiredFields_${fieldName}_minLength\"\n value=\"${config.minLength}\"\n min=\"0\"\n max=\"100\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-white placeholder-gray-300 focus:border-blue-400 focus:outline-none transition-colors w-full\"\n >\n </div>\n <div>\n <label class=\"block text-xs font-medium text-gray-400 mb-2\">Field Label</label>\n <input\n type=\"text\"\n name=\"requiredFields_${fieldName}_label\"\n value=\"${config.label}\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-white placeholder-gray-300 focus:border-blue-400 focus:outline-none transition-colors w-full\"\n >\n </div>\n </div>\n </div>\n `).join('')}\n </div>\n </div>\n\n <!-- Password Requirements Section -->\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Password Requirements</h3>\n <p class=\"text-sm text-gray-400 mb-6\">Additional password complexity requirements.</p>\n\n <div class=\"space-y-4\">\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Require Uppercase Letter</label>\n <p class=\"text-xs text-gray-400\">Password must contain at least one uppercase letter (A-Z)</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"validation_passwordRequirements_requireUppercase\"\n ${validation.passwordRequirements.requireUppercase ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Require Lowercase Letter</label>\n <p class=\"text-xs text-gray-400\">Password must contain at least one lowercase letter (a-z)</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"validation_passwordRequirements_requireLowercase\"\n ${validation.passwordRequirements.requireLowercase ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Require Numbers</label>\n <p class=\"text-xs text-gray-400\">Password must contain at least one number (0-9)</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"validation_passwordRequirements_requireNumbers\"\n ${validation.passwordRequirements.requireNumbers ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Require Special Characters</label>\n <p class=\"text-xs text-gray-400\">Password must contain at least one special character (!@#$%^&*)</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"validation_passwordRequirements_requireSpecialChars\"\n ${validation.passwordRequirements.requireSpecialChars ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n </div>\n </div>\n\n <!-- Registration Settings Section -->\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Registration Settings</h3>\n <p class=\"text-sm text-gray-400 mb-6\">General registration behavior.</p>\n\n <div class=\"space-y-4\">\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Allow User Registration</label>\n <p class=\"text-xs text-gray-400\">Enable or disable public user registration</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"registration_enabled\"\n ${registration.enabled ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Require Email Verification</label>\n <p class=\"text-xs text-gray-400\">Users must verify their email before accessing the system</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"registration_requireEmailVerification\"\n ${registration.requireEmailVerification ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n\n <div>\n <label class=\"block text-sm font-medium text-gray-300 mb-2\">Default User Role</label>\n <select\n name=\"registration_defaultRole\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-white focus:border-blue-400 focus:outline-none transition-colors w-full\"\n >\n <option value=\"viewer\" ${registration.defaultRole === 'viewer' ? 'selected' : ''}>Viewer</option>\n <option value=\"editor\" ${registration.defaultRole === 'editor' ? 'selected' : ''}>Editor</option>\n <option value=\"admin\" ${registration.defaultRole === 'admin' ? 'selected' : ''}>Admin</option>\n </select>\n <p class=\"text-xs text-gray-400 mt-1\">Role assigned to new users upon registration</p>\n </div>\n </div>\n </div>\n\n <!-- Validation Settings Section -->\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n <h3 class=\"text-lg font-semibold text-white mb-4\">Validation Settings</h3>\n <p class=\"text-sm text-gray-400 mb-6\">Additional validation rules.</p>\n\n <div class=\"space-y-4\">\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Enforce Email Format</label>\n <p class=\"text-xs text-gray-400\">Validate that email addresses are in correct format</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"validation_emailFormat\"\n ${validation.emailFormat ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n\n <div class=\"flex items-center justify-between\">\n <div>\n <label class=\"text-sm font-medium text-gray-300\">Prevent Duplicate Usernames</label>\n <p class=\"text-xs text-gray-400\">Ensure usernames are unique across all users</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n name=\"validation_allowDuplicateUsernames\"\n ${!validation.allowDuplicateUsernames ? 'checked' : ''}\n class=\"sr-only peer\"\n >\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n </div>\n </div>\n </div>\n `\n}\n","import { renderAdminLayout, AdminLayoutData } from '../layouts/admin-layout-v2.template'\nimport { renderAuthSettingsForm } from '../components/auth-settings-form.template'\nimport type { AuthSettings } from '../../services/auth-validation'\n\nexport interface PluginSettings {\n [key: string]: any\n}\n\nexport interface PluginActivity {\n id: string\n action: string\n message: string\n timestamp: number\n user?: string\n}\n\nexport interface PluginSettingsPageData {\n plugin: {\n id: string\n name: string\n displayName: string\n description: string\n version: string\n author: string\n status: 'active' | 'inactive' | 'error'\n category: string\n icon: string\n downloadCount?: number\n rating?: number\n lastUpdated: string\n dependencies?: string[]\n permissions?: string[]\n isCore?: boolean\n settings?: PluginSettings\n }\n activity?: PluginActivity[]\n user?: {\n name: string\n email: string\n role: string\n }\n}\n\nexport function renderPluginSettingsPage(data: PluginSettingsPageData): string {\n const { plugin, activity = [], user } = data\n \n const pageContent = `\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6\">\n <!-- Header with breadcrumb -->\n <div class=\"flex items-center mb-6\">\n <nav class=\"flex\" aria-label=\"Breadcrumb\">\n <ol class=\"flex items-center space-x-2\">\n <li>\n <a href=\"/admin/plugins\" class=\"text-gray-400 hover:text-white transition-colors\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10\"/>\n </svg>\n Plugins\n </a>\n </li>\n <li>\n <svg class=\"w-5 h-5 text-gray-500\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\"/>\n </svg>\n </li>\n <li>\n <span class=\"text-gray-300\">${plugin.displayName}</span>\n </li>\n </ol>\n </nav>\n </div>\n\n <!-- Plugin Header -->\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6 mb-6\">\n <div class=\"flex items-start justify-between\">\n <div class=\"flex items-center gap-4\">\n <div class=\"w-16 h-16 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center text-white text-2xl font-bold\">\n ${plugin.icon || plugin.displayName.charAt(0).toUpperCase()}\n </div>\n <div>\n <h1 class=\"text-2xl font-semibold text-white mb-1\">${plugin.displayName}</h1>\n <p class=\"text-gray-300 mb-2\">${plugin.description}</p>\n <div class=\"flex items-center gap-4 text-sm text-gray-400\">\n <span>v${plugin.version}</span>\n <span>by ${plugin.author}</span>\n <span>${plugin.category}</span>\n ${plugin.downloadCount ? `<span>${plugin.downloadCount.toLocaleString()} downloads</span>` : ''}\n ${plugin.rating ? `<span>★ ${plugin.rating}</span>` : ''}\n </div>\n </div>\n </div>\n \n <div class=\"flex items-center gap-3\">\n ${renderStatusBadge(plugin.status)}\n ${renderToggleButton(plugin)}\n </div>\n </div>\n </div>\n\n <!-- Tabs -->\n <div class=\"mb-6\">\n <nav class=\"flex space-x-8\" aria-label=\"Tabs\">\n <button onclick=\"showTab('settings')\" id=\"settings-tab\" class=\"tab-button active border-b-2 border-blue-400 py-2 px-1 text-sm font-medium text-blue-400\">\n Settings\n </button>\n <button onclick=\"showTab('activity')\" id=\"activity-tab\" class=\"tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300\">\n Activity Log\n </button>\n <button onclick=\"showTab('info')\" id=\"info-tab\" class=\"tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300\">\n Information\n </button>\n </nav>\n </div>\n\n <!-- Tab Content -->\n <div id=\"tab-content\">\n <!-- Settings Tab -->\n <div id=\"settings-content\" class=\"tab-content\">\n ${renderSettingsTab(plugin)}\n </div>\n\n <!-- Activity Tab -->\n <div id=\"activity-content\" class=\"tab-content hidden\">\n ${renderActivityTab(activity)}\n </div>\n\n <!-- Information Tab -->\n <div id=\"info-content\" class=\"tab-content hidden\">\n ${renderInformationTab(plugin)}\n </div>\n </div>\n </div>\n\n <script>\n function showTab(tabName) {\n // Hide all tab contents\n document.querySelectorAll('.tab-content').forEach(content => {\n content.classList.add('hidden');\n });\n \n // Remove active class from all tabs\n document.querySelectorAll('.tab-button').forEach(tab => {\n tab.classList.remove('active', 'border-blue-400', 'text-blue-400');\n tab.classList.add('border-transparent', 'text-gray-400');\n });\n \n // Show selected tab content\n document.getElementById(tabName + '-content').classList.remove('hidden');\n \n // Add active class to selected tab\n const activeTab = document.getElementById(tabName + '-tab');\n activeTab.classList.add('active', 'border-blue-400', 'text-blue-400');\n activeTab.classList.remove('border-transparent', 'text-gray-400');\n }\n\n async function togglePlugin(pluginId, action) {\n const button = event.target;\n const originalText = button.textContent;\n button.disabled = true;\n button.textContent = action === 'activate' ? 'Activating...' : 'Deactivating...';\n \n try {\n const response = await fetch(\\`/admin/plugins/\\${pluginId}/\\${action}\\`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n \n const result = await response.json();\n \n if (result.success) {\n showNotification(\\`Plugin \\${action}d successfully\\`, 'success');\n setTimeout(() => location.reload(), 1000);\n } else {\n throw new Error(result.error || \\`Failed to \\${action} plugin\\`);\n }\n } catch (error) {\n showNotification(error.message, 'error');\n button.textContent = originalText;\n button.disabled = false;\n }\n }\n\n async function saveSettings() {\n const form = document.getElementById('settings-form');\n const formData = new FormData(form);\n const isAuthPlugin = '${plugin.id}' === 'core-auth';\n let settings = {};\n\n if (isAuthPlugin) {\n // Handle nested auth settings structure\n settings = {\n requiredFields: {},\n validation: {\n passwordRequirements: {}\n },\n registration: {}\n };\n\n for (let [key, value] of formData.entries()) {\n const input = form.querySelector(\\`[name=\"\\${key}\"]\\`);\n const fieldValue = input.type === 'checkbox' ? input.checked :\n input.type === 'number' ? parseInt(value) || 0 : value;\n\n // Parse nested field names like \"requiredFields_email_required\"\n if (key.startsWith('requiredFields_')) {\n const parts = key.replace('requiredFields_', '').split('_');\n const fieldName = parts[0];\n const propName = parts[1];\n\n if (!settings.requiredFields[fieldName]) {\n settings.requiredFields[fieldName] = { type: 'text', label: '' };\n }\n settings.requiredFields[fieldName][propName] = fieldValue;\n } else if (key.startsWith('validation_passwordRequirements_')) {\n const propName = key.replace('validation_passwordRequirements_', '');\n settings.validation.passwordRequirements[propName] = fieldValue;\n } else if (key.startsWith('validation_')) {\n const propName = key.replace('validation_', '');\n // Invert the allowDuplicateUsernames logic\n if (propName === 'allowDuplicateUsernames') {\n settings.validation[propName] = !fieldValue;\n } else {\n settings.validation[propName] = fieldValue;\n }\n } else if (key.startsWith('registration_')) {\n const propName = key.replace('registration_', '');\n settings.registration[propName] = fieldValue;\n }\n }\n } else {\n // Handle regular plugin settings\n for (let [key, value] of formData.entries()) {\n if (key.startsWith('setting_')) {\n const settingKey = key.replace('setting_', '');\n\n const input = form.querySelector(\\`[name=\"\\${key}\"]\\`);\n if (input.type === 'checkbox') {\n settings[settingKey] = input.checked;\n } else if (input.type === 'number') {\n settings[settingKey] = parseInt(value) || 0;\n } else {\n settings[settingKey] = value;\n }\n }\n }\n }\n\n const saveButton = document.getElementById('save-button');\n saveButton.disabled = true;\n saveButton.textContent = 'Saving...';\n\n try {\n const response = await fetch(\\`/admin/plugins/${plugin.id}/settings\\`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(settings)\n });\n\n const result = await response.json();\n\n if (result.success) {\n showNotification('Settings saved successfully', 'success');\n // Reload page after 1 second to show updated settings\n setTimeout(() => location.reload(), 1000);\n } else {\n throw new Error(result.error || 'Failed to save settings');\n }\n } catch (error) {\n showNotification(error.message, 'error');\n } finally {\n saveButton.disabled = false;\n saveButton.textContent = 'Save Settings';\n }\n }\n\n function showNotification(message, type) {\n const notification = document.createElement('div');\n const bgColor = type === 'success' ? 'bg-green-600' : type === 'error' ? 'bg-red-600' : 'bg-blue-600';\n notification.className = \\`fixed top-4 right-4 px-4 py-2 rounded-lg text-white z-50 \\${bgColor}\\`;\n notification.textContent = message;\n document.body.appendChild(notification);\n \n setTimeout(() => {\n notification.remove();\n }, 3000);\n }\n </script>\n `\n\n const layoutData: AdminLayoutData = {\n title: `${plugin.displayName} Settings`,\n pageTitle: `${plugin.displayName} Settings`,\n currentPath: `/admin/plugins/${plugin.id}`,\n user,\n content: pageContent\n }\n\n return renderAdminLayout(layoutData)\n}\n\nfunction renderStatusBadge(status: string): string {\n const statusColors: Record<string, string> = {\n active: 'bg-green-900/50 text-green-300 border-green-600/30',\n inactive: 'bg-gray-800/50 text-gray-400 border-gray-600/30',\n error: 'bg-red-900/50 text-red-300 border-red-600/30'\n }\n\n const statusIcons: Record<string, string> = {\n active: '<div class=\"w-2 h-2 bg-green-400 rounded-full mr-2\"></div>',\n inactive: '<div class=\"w-2 h-2 bg-gray-500 rounded-full mr-2\"></div>',\n error: '<div class=\"w-2 h-2 bg-red-400 rounded-full mr-2\"></div>'\n }\n\n return `\n <span class=\"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${statusColors[status] || statusColors.inactive} border\">\n ${statusIcons[status] || statusIcons.inactive}${status.charAt(0).toUpperCase() + status.slice(1)}\n </span>\n `\n}\n\nfunction renderToggleButton(plugin: any): string {\n if (plugin.isCore) {\n return '<span class=\"text-sm text-gray-400\">Core Plugin</span>'\n }\n\n return plugin.status === 'active' \n ? `<button onclick=\"togglePlugin('${plugin.id}', 'deactivate')\" class=\"bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors\">Deactivate</button>`\n : `<button onclick=\"togglePlugin('${plugin.id}', 'activate')\" class=\"bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors\">Activate</button>`\n}\n\nfunction renderSettingsTab(plugin: any): string {\n const settings = plugin.settings || {}\n const isSeedDataPlugin = plugin.id === 'seed-data' || plugin.name === 'seed-data'\n const isAuthPlugin = plugin.id === 'core-auth' || plugin.name === 'core-auth'\n\n return `\n ${isSeedDataPlugin ? `\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6 mb-6\">\n <div class=\"flex items-center justify-between\">\n <div>\n <h2 class=\"text-xl font-semibold text-white mb-2\">Seed Data Generator</h2>\n <p class=\"text-gray-400\">Generate realistic example data for testing and development.</p>\n </div>\n <a\n href=\"/admin/seed-data\"\n target=\"_blank\"\n class=\"inline-flex items-center gap-2 bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-lg font-medium transition-colors\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 4v16m8-8H4\"/>\n </svg>\n Open Seed Data Tool\n </a>\n </div>\n </div>\n ` : ''}\n\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n ${isAuthPlugin ? `\n <h2 class=\"text-xl font-semibold text-white mb-4\">Authentication Settings</h2>\n <p class=\"text-gray-400 mb-6\">Configure user registration fields and validation rules.</p>\n ` : `\n <h2 class=\"text-xl font-semibold text-white mb-4\">Plugin Settings</h2>\n `}\n\n <form id=\"settings-form\" class=\"space-y-6\">\n ${isAuthPlugin && Object.keys(settings).length > 0\n ? renderAuthSettingsForm(settings as AuthSettings)\n : Object.keys(settings).length > 0\n ? renderSettingsFields(settings)\n : renderNoSettings(plugin)\n }\n\n ${Object.keys(settings).length > 0 ? `\n <div class=\"flex items-center justify-end pt-6 border-t border-white/10\">\n <button\n type=\"button\"\n id=\"save-button\"\n onclick=\"saveSettings()\"\n class=\"bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg font-medium transition-colors\"\n >\n Save Settings\n </button>\n </div>\n ` : ''}\n </form>\n </div>\n `\n}\n\nfunction renderSettingsFields(settings: PluginSettings): string {\n return Object.entries(settings).map(([key, value]) => {\n const fieldId = `setting_${key}`\n const displayName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())\n \n if (typeof value === 'boolean') {\n return `\n <div class=\"flex items-center justify-between\">\n <div>\n <label for=\"${fieldId}\" class=\"text-sm font-medium text-gray-300\">${displayName}</label>\n <p class=\"text-xs text-gray-400\">Enable or disable this feature</p>\n </div>\n <label class=\"relative inline-flex items-center cursor-pointer\">\n <input type=\"checkbox\" name=\"${fieldId}\" id=\"${fieldId}\" ${value ? 'checked' : ''} class=\"sr-only peer\">\n <div class=\"w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600\"></div>\n </label>\n </div>\n `\n } else if (typeof value === 'number') {\n return `\n <div>\n <label for=\"${fieldId}\" class=\"block text-sm font-medium text-gray-300 mb-2\">${displayName}</label>\n <input \n type=\"number\" \n name=\"${fieldId}\" \n id=\"${fieldId}\" \n value=\"${value}\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-white placeholder-gray-300 focus:border-blue-400 focus:outline-none transition-colors w-full\"\n >\n </div>\n `\n } else {\n return `\n <div>\n <label for=\"${fieldId}\" class=\"block text-sm font-medium text-gray-300 mb-2\">${displayName}</label>\n <input \n type=\"text\" \n name=\"${fieldId}\" \n id=\"${fieldId}\" \n value=\"${value}\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-white placeholder-gray-300 focus:border-blue-400 focus:outline-none transition-colors w-full\"\n >\n </div>\n `\n }\n }).join('')\n}\n\nfunction renderNoSettings(plugin: any): string {\n // Special handling for seed-data plugin\n if (plugin.id === 'seed-data' || plugin.name === 'seed-data') {\n return `\n <div class=\"text-center py-8\">\n <svg class=\"w-16 h-16 text-green-400 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253\"/>\n </svg>\n <h3 class=\"text-lg font-medium text-gray-300 mb-2\">Seed Data Generator</h3>\n <p class=\"text-gray-400 mb-6\">Generate realistic example data for testing and development.</p>\n <a\n href=\"/admin/seed-data\"\n class=\"inline-flex items-center gap-2 bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-lg font-medium transition-colors\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 4v16m8-8H4\"/>\n </svg>\n Generate Seed Data\n </a>\n </div>\n `\n }\n\n return `\n <div class=\"text-center py-8\">\n <svg class=\"w-12 h-12 text-gray-400 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z\"/>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"/>\n </svg>\n <h3 class=\"text-lg font-medium text-gray-300 mb-2\">No Settings Available</h3>\n <p class=\"text-gray-400\">This plugin doesn't have any configurable settings.</p>\n </div>\n `\n}\n\nfunction renderActivityTab(activity: PluginActivity[]): string {\n return `\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n <h2 class=\"text-xl font-semibold text-white mb-4\">Activity Log</h2>\n \n ${activity.length > 0 ? `\n <div class=\"space-y-4\">\n ${activity.map(item => `\n <div class=\"flex items-start gap-3 p-3 rounded-lg bg-white/5\">\n <div class=\"w-2 h-2 bg-blue-400 rounded-full mt-2\"></div>\n <div class=\"flex-1\">\n <div class=\"flex items-center justify-between\">\n <span class=\"text-sm font-medium text-white\">${item.action}</span>\n <span class=\"text-xs text-gray-400\">${formatTimestamp(item.timestamp)}</span>\n </div>\n <p class=\"text-sm text-gray-300 mt-1\">${item.message}</p>\n ${item.user ? `<p class=\"text-xs text-gray-400 mt-1\">by ${item.user}</p>` : ''}\n </div>\n </div>\n `).join('')}\n </div>\n ` : `\n <div class=\"text-center py-8\">\n <svg class=\"w-12 h-12 text-gray-400 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"/>\n </svg>\n <h3 class=\"text-lg font-medium text-gray-300 mb-2\">No Activity</h3>\n <p class=\"text-gray-400\">No recent activity for this plugin.</p>\n </div>\n `}\n </div>\n `\n}\n\nfunction renderInformationTab(plugin: any): string {\n return `\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <!-- Plugin Details -->\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n <h2 class=\"text-xl font-semibold text-white mb-4\">Plugin Details</h2>\n <div class=\"space-y-3\">\n <div class=\"flex justify-between\">\n <span class=\"text-gray-400\">Name:</span>\n <span class=\"text-white\">${plugin.displayName}</span>\n </div>\n <div class=\"flex justify-between\">\n <span class=\"text-gray-400\">Version:</span>\n <span class=\"text-white\">${plugin.version}</span>\n </div>\n <div class=\"flex justify-between\">\n <span class=\"text-gray-400\">Author:</span>\n <span class=\"text-white\">${plugin.author}</span>\n </div>\n <div class=\"flex justify-between\">\n <span class=\"text-gray-400\">Category:</span>\n <span class=\"text-white\">${plugin.category}</span>\n </div>\n <div class=\"flex justify-between\">\n <span class=\"text-gray-400\">Status:</span>\n <span class=\"text-white\">${plugin.status}</span>\n </div>\n <div class=\"flex justify-between\">\n <span class=\"text-gray-400\">Last Updated:</span>\n <span class=\"text-white\">${plugin.lastUpdated}</span>\n </div>\n </div>\n </div>\n\n <!-- Dependencies & Permissions -->\n <div class=\"backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6\">\n <h2 class=\"text-xl font-semibold text-white mb-4\">Dependencies & Permissions</h2>\n \n ${plugin.dependencies && plugin.dependencies.length > 0 ? `\n <div class=\"mb-6\">\n <h3 class=\"text-sm font-medium text-gray-300 mb-2\">Dependencies:</h3>\n <div class=\"space-y-1\">\n ${plugin.dependencies.map((dep: string) => `\n <div class=\"inline-block bg-white/10 text-gray-300 text-sm px-2 py-1 rounded mr-2\">${dep}</div>\n `).join('')}\n </div>\n </div>\n ` : ''}\n\n ${plugin.permissions && plugin.permissions.length > 0 ? `\n <div>\n <h3 class=\"text-sm font-medium text-gray-300 mb-2\">Permissions:</h3>\n <div class=\"space-y-1\">\n ${plugin.permissions.map((perm: string) => `\n <div class=\"inline-block bg-white/10 text-gray-300 text-sm px-2 py-1 rounded mr-2\">${perm}</div>\n `).join('')}\n </div>\n </div>\n ` : ''}\n\n ${(!plugin.dependencies || plugin.dependencies.length === 0) && (!plugin.permissions || plugin.permissions.length === 0) ? `\n <p class=\"text-gray-400\">No dependencies or special permissions required.</p>\n ` : ''}\n </div>\n </div>\n `\n}\n\nfunction formatTimestamp(timestamp: number): string {\n const date = new Date(timestamp * 1000)\n return date.toLocaleString()\n}","import { Hono } from 'hono'\nimport type { D1Database, KVNamespace } from '@cloudflare/workers-types'\nimport { renderPluginsListPage, PluginsListPageData, Plugin } from '../templates/pages/admin-plugins-list.template'\nimport { renderPluginSettingsPage, PluginSettingsPageData } from '../templates/pages/admin-plugin-settings.template'\nimport { PluginService } from '../services'\n// TODO: authValidationService not yet migrated - commented out temporarily\n// import { authValidationService } from '../services/auth-validation'\nimport type { Bindings, Variables } from '../app'\n\nconst adminPluginRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Plugin list page\nadminPluginRoutes.get('/', async (c) => {\n try {\n const user = c.get('user')\n const db = c.env.DB\n \n // Temporarily skip permission check for admin users\n // TODO: Fix permission system\n if (user?.role !== 'admin') {\n return c.text('Access denied', 403)\n }\n \n const pluginService = new PluginService(db)\n \n // Get all plugins with error handling\n let plugins: any[] = []\n let stats = { total: 0, active: 0, inactive: 0, errors: 0 }\n \n try {\n plugins = await pluginService.getAllPlugins()\n stats = await pluginService.getPluginStats()\n } catch (error) {\n console.error('Error loading plugins:', error)\n // Continue with empty data\n }\n \n // Map to template format\n const templatePlugins: Plugin[] = plugins.map(p => ({\n id: p.id,\n name: p.name,\n displayName: p.display_name,\n description: p.description,\n version: p.version,\n author: p.author,\n status: p.status,\n category: p.category,\n icon: p.icon,\n downloadCount: p.download_count,\n rating: p.rating,\n lastUpdated: formatLastUpdated(p.last_updated),\n dependencies: p.dependencies,\n permissions: p.permissions,\n isCore: p.is_core\n }))\n \n const pageData: PluginsListPageData = {\n plugins: templatePlugins,\n stats,\n user: {\n name: user?.email || 'User',\n email: user?.email || '',\n role: user?.role || 'user'\n },\n version: c.get('appVersion')\n }\n\n return c.html(renderPluginsListPage(pageData))\n } catch (error) {\n console.error('Error loading plugins page:', error)\n return c.text('Internal server error', 500)\n }\n})\n\n// Get plugin settings page\nadminPluginRoutes.get('/:id', async (c) => {\n try {\n const user = c.get('user')\n const db = c.env.DB\n const pluginId = c.req.param('id')\n \n // Check authorization\n if (user?.role !== 'admin') {\n return c.redirect('/admin/plugins')\n }\n \n const pluginService = new PluginService(db)\n const plugin = await pluginService.getPlugin(pluginId)\n \n if (!plugin) {\n return c.text('Plugin not found', 404)\n }\n \n // Get activity log\n const activity = await pluginService.getPluginActivity(pluginId, 20)\n \n // Map plugin data to template format\n const templatePlugin = {\n id: plugin.id,\n name: plugin.name,\n displayName: plugin.display_name,\n description: plugin.description,\n version: plugin.version,\n author: plugin.author,\n status: plugin.status,\n category: plugin.category,\n icon: plugin.icon,\n downloadCount: plugin.download_count,\n rating: plugin.rating,\n lastUpdated: formatLastUpdated(plugin.last_updated),\n dependencies: plugin.dependencies,\n permissions: plugin.permissions,\n isCore: plugin.is_core,\n settings: plugin.settings\n }\n \n // Map activity data\n const templateActivity = (activity || []).map(item => ({\n id: item.id,\n action: item.action,\n message: item.message,\n timestamp: item.timestamp,\n user: item.user_email\n }))\n \n const pageData: PluginSettingsPageData = {\n plugin: templatePlugin,\n activity: templateActivity,\n user: {\n name: user?.email || 'User',\n email: user?.email || '',\n role: user?.role || 'user'\n }\n }\n \n return c.html(renderPluginSettingsPage(pageData))\n } catch (error) {\n console.error('Error getting plugin settings page:', error)\n return c.text('Internal server error', 500)\n }\n})\n\n// Activate plugin\nadminPluginRoutes.post('/:id/activate', async (c) => {\n try {\n const user = c.get('user')\n const db = c.env.DB\n const pluginId = c.req.param('id')\n \n // Temporarily skip permission check for admin users\n if (user?.role !== 'admin') {\n return c.json({ error: 'Access denied' }, 403)\n }\n \n const pluginService = new PluginService(db)\n await pluginService.activatePlugin(pluginId)\n \n return c.json({ success: true })\n } catch (error) {\n console.error('Error activating plugin:', error)\n const message = error instanceof Error ? error.message : 'Failed to activate plugin'\n return c.json({ error: message }, 400)\n }\n})\n\n// Deactivate plugin\nadminPluginRoutes.post('/:id/deactivate', async (c) => {\n try {\n const user = c.get('user')\n const db = c.env.DB\n const pluginId = c.req.param('id')\n \n // Temporarily skip permission check for admin users\n if (user?.role !== 'admin') {\n return c.json({ error: 'Access denied' }, 403)\n }\n \n const pluginService = new PluginService(db)\n await pluginService.deactivatePlugin(pluginId)\n \n return c.json({ success: true })\n } catch (error) {\n console.error('Error deactivating plugin:', error)\n const message = error instanceof Error ? error.message : 'Failed to deactivate plugin'\n return c.json({ error: message }, 400)\n }\n})\n\n// Install plugin\nadminPluginRoutes.post('/install', async (c) => {\n try {\n const user = c.get('user')\n const db = c.env.DB\n \n // Temporarily skip permission check for admin users\n if (user?.role !== 'admin') {\n return c.json({ error: 'Access denied' }, 403)\n }\n \n const body = await c.req.json()\n \n const pluginService = new PluginService(db)\n \n // Handle FAQ plugin installation\n if (body.name === 'faq-plugin') {\n const faqPlugin = await pluginService.installPlugin({\n id: 'third-party-faq',\n name: 'faq-plugin',\n display_name: 'FAQ System',\n description: 'Frequently Asked Questions management system with categories, search, and custom styling',\n version: '2.0.0',\n author: 'Community Developer',\n category: 'content',\n icon: '❓',\n permissions: ['manage:faqs'],\n dependencies: [],\n settings: {\n enableSearch: true,\n enableCategories: true,\n questionsPerPage: 10\n }\n })\n\n return c.json({ success: true, plugin: faqPlugin })\n }\n\n // Handle Demo Login plugin installation\n if (body.name === 'demo-login-plugin') {\n const demoPlugin = await pluginService.installPlugin({\n id: 'demo-login-prefill',\n name: 'demo-login-plugin',\n display_name: 'Demo Login Prefill',\n description: 'Prefills login form with demo credentials (admin@sonicjs.com/admin123) for easy site demonstration',\n version: '1.0.0-beta.1',\n author: 'SonicJS',\n category: 'demo',\n icon: '🎯',\n permissions: [],\n dependencies: [],\n settings: {\n enableNotice: true,\n demoEmail: 'admin@sonicjs.com',\n demoPassword: 'admin123'\n }\n })\n\n return c.json({ success: true, plugin: demoPlugin })\n }\n\n // Handle core Authentication System plugin installation\n if (body.name === 'core-auth') {\n const authPlugin = await pluginService.installPlugin({\n id: 'core-auth',\n name: 'core-auth',\n display_name: 'Authentication System',\n description: 'Core authentication and user management system',\n version: '1.0.0-beta.1',\n author: 'SonicJS Team',\n category: 'security',\n icon: '🔐',\n permissions: ['manage:users', 'manage:roles', 'manage:permissions'],\n dependencies: [],\n is_core: true,\n settings: {}\n })\n\n return c.json({ success: true, plugin: authPlugin })\n }\n\n // Handle core Media Manager plugin installation\n if (body.name === 'core-media') {\n const mediaPlugin = await pluginService.installPlugin({\n id: 'core-media',\n name: 'core-media',\n display_name: 'Media Manager',\n description: 'Core media upload and management system',\n version: '1.0.0-beta.1',\n author: 'SonicJS Team',\n category: 'media',\n icon: '📸',\n permissions: ['manage:media', 'upload:files'],\n dependencies: [],\n is_core: true,\n settings: {}\n })\n\n return c.json({ success: true, plugin: mediaPlugin })\n }\n\n // Handle core Workflow Engine plugin installation\n if (body.name === 'core-workflow') {\n const workflowPlugin = await pluginService.installPlugin({\n id: 'core-workflow',\n name: 'core-workflow',\n display_name: 'Workflow Engine',\n description: 'Content workflow and approval system',\n version: '1.0.0-beta.1',\n author: 'SonicJS Team',\n category: 'content',\n icon: '🔄',\n permissions: ['manage:workflows', 'approve:content'],\n dependencies: [],\n is_core: true,\n settings: {}\n })\n\n return c.json({ success: true, plugin: workflowPlugin })\n }\n\n // Handle Database Tools plugin installation\n if (body.name === 'database-tools') {\n const databaseToolsPlugin = await pluginService.installPlugin({\n id: 'database-tools',\n name: 'database-tools',\n display_name: 'Database Tools',\n description: 'Database management tools including truncate, backup, and validation',\n version: '1.0.0-beta.1',\n author: 'SonicJS Team',\n category: 'system',\n icon: '🗄️',\n permissions: ['manage:database', 'admin'],\n dependencies: [],\n is_core: false,\n settings: {\n enableTruncate: true,\n enableBackup: true,\n enableValidation: true,\n requireConfirmation: true\n }\n })\n\n return c.json({ success: true, plugin: databaseToolsPlugin })\n }\n\n // Handle Seed Data plugin installation\n if (body.name === 'seed-data') {\n const seedDataPlugin = await pluginService.installPlugin({\n id: 'seed-data',\n name: 'seed-data',\n display_name: 'Seed Data',\n description: 'Generate realistic example users and content for testing and development',\n version: '1.0.0-beta.1',\n author: 'SonicJS Team',\n category: 'development',\n icon: '🌱',\n permissions: ['admin'],\n dependencies: [],\n is_core: false,\n settings: {\n userCount: 20,\n contentCount: 200,\n defaultPassword: 'password123'\n }\n })\n\n return c.json({ success: true, plugin: seedDataPlugin })\n }\n\n return c.json({ error: 'Plugin not found in registry' }, 404)\n } catch (error) {\n console.error('Error installing plugin:', error)\n const message = error instanceof Error ? error.message : 'Failed to install plugin'\n return c.json({ error: message }, 400)\n }\n})\n\n// Uninstall plugin\nadminPluginRoutes.post('/:id/uninstall', async (c) => {\n try {\n const user = c.get('user')\n const db = c.env.DB\n const pluginId = c.req.param('id')\n \n // Temporarily skip permission check for admin users\n if (user?.role !== 'admin') {\n return c.json({ error: 'Access denied' }, 403)\n }\n \n const pluginService = new PluginService(db)\n await pluginService.uninstallPlugin(pluginId)\n \n return c.json({ success: true })\n } catch (error) {\n console.error('Error uninstalling plugin:', error)\n const message = error instanceof Error ? error.message : 'Failed to uninstall plugin'\n return c.json({ error: message }, 400)\n }\n})\n\n// Update plugin settings\nadminPluginRoutes.post('/:id/settings', async (c) => {\n try {\n const user = c.get('user')\n const db = c.env.DB\n const pluginId = c.req.param('id')\n\n // Temporarily skip permission check for admin users\n if (user?.role !== 'admin') {\n return c.json({ error: 'Access denied' }, 403)\n }\n\n const settings = await c.req.json()\n\n const pluginService = new PluginService(db)\n await pluginService.updatePluginSettings(pluginId, settings)\n\n // TODO: Clear auth validation cache if updating core-auth plugin\n // Commented out until authValidationService is migrated\n // if (pluginId === 'core-auth') {\n // authValidationService.clearCache()\n // console.log('[AuthSettings] Cache cleared after updating authentication settings')\n // }\n\n return c.json({ success: true })\n } catch (error) {\n console.error('Error updating plugin settings:', error)\n const message = error instanceof Error ? error.message : 'Failed to update settings'\n return c.json({ error: message }, 400)\n }\n})\n\n// Helper function to format last updated time\nfunction formatLastUpdated(timestamp: number): string {\n const now = Date.now() / 1000\n const diff = now - timestamp\n\n if (diff < 60) return 'just now'\n if (diff < 3600) return `${Math.floor(diff / 60)} minutes ago`\n if (diff < 86400) return `${Math.floor(diff / 3600)} hours ago`\n if (diff < 604800) return `${Math.floor(diff / 86400)} days ago`\n if (diff < 2592000) return `${Math.floor(diff / 604800)} weeks ago`\n return `${Math.floor(diff / 2592000)} months ago`\n}\n\nexport { adminPluginRoutes }","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\n\ninterface BaseUser {\n name: string\n email: string\n role: string\n}\n\nexport interface LogEntry {\n id: string\n level: string\n category: string\n message: string\n data?: any\n userId?: string\n sessionId?: string\n requestId?: string\n ipAddress?: string\n userAgent?: string\n method?: string\n url?: string\n statusCode?: number\n duration?: number\n stackTrace?: string\n tags: string[]\n source?: string\n createdAt: Date\n formattedDate: string\n formattedDuration?: string\n levelClass: string\n categoryClass: string\n}\n\nexport interface LogsListPageData {\n logs: LogEntry[]\n pagination: {\n currentPage: number\n totalPages: number\n totalItems: number\n itemsPerPage: number\n startItem: number\n endItem: number\n baseUrl: string\n }\n filters: {\n level: string\n category: string\n search: string\n startDate: string\n endDate: string\n source: string\n }\n user?: BaseUser\n}\n\nexport function renderLogsListPage(data: LogsListPageData) {\n const { logs, pagination, filters, user } = data\n\n const content = `\n <div>\n <div class=\"sm:flex sm:items-center sm:justify-between mb-6\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">System Logs</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">\n Monitor and analyze system activity, errors, and performance metrics.\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 flex gap-x-2\">\n <a\n href=\"/admin/logs/config\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-700 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 transition-colors shadow-sm\"\n >\n Configure\n </a>\n <a\n href=\"/admin/logs/export?${new URLSearchParams(filters).toString()}\"\n class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n Export\n </a>\n </div>\n </div>\n\n <!-- Filters -->\n <div class=\"relative rounded-xl overflow-hidden mb-6\">\n <!-- Gradient Background -->\n <div class=\"absolute inset-0 bg-gradient-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10 dark:from-cyan-400/20 dark:via-blue-400/20 dark:to-purple-400/20\"></div>\n\n <div class=\"relative bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10\">\n <div class=\"px-6 py-5\">\n <form method=\"GET\" action=\"/admin/logs\" class=\"space-y-4\">\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <div class=\"relative group\">\n <label for=\"search\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Search</label>\n <div class=\"relative\">\n <div class=\"absolute left-3.5 top-2.5 flex items-center justify-center w-5 h-5 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 dark:from-cyan-300 dark:to-blue-400 opacity-90 group-focus-within:opacity-100 transition-opacity\">\n <svg class=\"h-3 w-3 text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" stroke-width=\"2.5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"/>\n </svg>\n </div>\n <input\n type=\"text\"\n name=\"search\"\n id=\"search\"\n value=\"${filters.search}\"\n placeholder=\"Search messages...\"\n class=\"w-full rounded-full bg-transparent pl-11 pr-4 py-2 text-sm text-zinc-950 dark:text-white placeholder-zinc-500 dark:placeholder-zinc-400 border-2 border-cyan-200/50 dark:border-cyan-700/50 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n />\n </div>\n </div>\n\n <div>\n <label for=\"level\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Level</label>\n <select\n name=\"level\"\n id=\"level\"\n class=\"w-full rounded-lg bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2 text-sm text-zinc-950 dark:text-white border-2 border-cyan-200/50 dark:border-cyan-700/50 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n >\n <option value=\"\">All Levels</option>\n <option value=\"debug\" ${filters.level === 'debug' ? 'selected' : ''}>Debug</option>\n <option value=\"info\" ${filters.level === 'info' ? 'selected' : ''}>Info</option>\n <option value=\"warn\" ${filters.level === 'warn' ? 'selected' : ''}>Warning</option>\n <option value=\"error\" ${filters.level === 'error' ? 'selected' : ''}>Error</option>\n <option value=\"fatal\" ${filters.level === 'fatal' ? 'selected' : ''}>Fatal</option>\n </select>\n </div>\n\n <div>\n <label for=\"category\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Category</label>\n <select\n name=\"category\"\n id=\"category\"\n class=\"w-full rounded-lg bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2 text-sm text-zinc-950 dark:text-white border-2 border-cyan-200/50 dark:border-cyan-700/50 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n >\n <option value=\"\">All Categories</option>\n <option value=\"auth\" ${filters.category === 'auth' ? 'selected' : ''}>Authentication</option>\n <option value=\"api\" ${filters.category === 'api' ? 'selected' : ''}>API</option>\n <option value=\"workflow\" ${filters.category === 'workflow' ? 'selected' : ''}>Workflow</option>\n <option value=\"plugin\" ${filters.category === 'plugin' ? 'selected' : ''}>Plugin</option>\n <option value=\"media\" ${filters.category === 'media' ? 'selected' : ''}>Media</option>\n <option value=\"system\" ${filters.category === 'system' ? 'selected' : ''}>System</option>\n <option value=\"security\" ${filters.category === 'security' ? 'selected' : ''}>Security</option>\n <option value=\"error\" ${filters.category === 'error' ? 'selected' : ''}>Error</option>\n </select>\n </div>\n\n <div>\n <label for=\"source\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Source</label>\n <input\n type=\"text\"\n name=\"source\"\n id=\"source\"\n value=\"${filters.source}\"\n placeholder=\"e.g., http-middleware\"\n class=\"w-full rounded-lg bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2 text-sm text-zinc-950 dark:text-white placeholder-zinc-500 dark:placeholder-zinc-400 border-2 border-cyan-200/50 dark:border-cyan-700/50 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n />\n </div>\n\n <div>\n <label for=\"start_date\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">Start Date</label>\n <input\n type=\"datetime-local\"\n name=\"start_date\"\n id=\"start_date\"\n value=\"${filters.startDate}\"\n class=\"w-full rounded-lg bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2 text-sm text-zinc-950 dark:text-white border-2 border-cyan-200/50 dark:border-cyan-700/50 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n />\n </div>\n\n <div>\n <label for=\"end_date\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">End Date</label>\n <input\n type=\"datetime-local\"\n name=\"end_date\"\n id=\"end_date\"\n value=\"${filters.endDate}\"\n class=\"w-full rounded-lg bg-white/90 dark:bg-zinc-800/90 backdrop-blur-sm px-4 py-2 text-sm text-zinc-950 dark:text-white border-2 border-cyan-200/50 dark:border-cyan-700/50 focus:outline-none focus:border-cyan-500 dark:focus:border-cyan-400 focus:shadow-lg focus:shadow-cyan-500/20 dark:focus:shadow-cyan-400/20 transition-all duration-300\"\n />\n </div>\n\n <div class=\"sm:col-span-2 flex items-end gap-x-2\">\n <button\n type=\"submit\"\n class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n Apply Filters\n </button>\n <a\n href=\"/admin/logs\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-700 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 transition-colors shadow-sm\"\n >\n Clear\n </a>\n </div>\n </div>\n\n <div class=\"flex items-center justify-end pt-2\">\n <span class=\"text-sm/6 font-medium text-zinc-700 dark:text-zinc-300 px-3 py-1.5 rounded-full bg-white/60 dark:bg-zinc-800/60 backdrop-blur-sm\">${pagination.totalItems} ${pagination.totalItems === 1 ? 'entry' : 'entries'}</span>\n </div>\n </form>\n </div>\n </div>\n </div>\n\n <!-- Logs Table -->\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden\">\n <div class=\"overflow-x-auto\">\n <table class=\"min-w-full\">\n <thead>\n <tr class=\"border-b border-zinc-950/5 dark:border-white/5\">\n <th scope=\"col\" class=\"px-4 py-3.5 text-left text-sm font-semibold text-zinc-950 dark:text-white sm:pl-6\">\n Level\n </th>\n <th scope=\"col\" class=\"px-4 py-3.5 text-left text-sm font-semibold text-zinc-950 dark:text-white\">\n Category\n </th>\n <th scope=\"col\" class=\"px-4 py-3.5 text-left text-sm font-semibold text-zinc-950 dark:text-white\">\n Message\n </th>\n <th scope=\"col\" class=\"px-4 py-3.5 text-left text-sm font-semibold text-zinc-950 dark:text-white\">\n Source\n </th>\n <th scope=\"col\" class=\"px-4 py-3.5 text-left text-sm font-semibold text-zinc-950 dark:text-white\">\n Time\n </th>\n <th scope=\"col\" class=\"relative px-4 py-3.5 sm:pr-6\">\n <span class=\"sr-only\">Actions</span>\n </th>\n </tr>\n </thead>\n <tbody>\n ${logs.map(log => `\n <tr class=\"border-t border-zinc-950/5 dark:border-white/5 hover:bg-gradient-to-r hover:from-cyan-50/50 hover:via-blue-50/30 hover:to-purple-50/50 dark:hover:from-cyan-900/20 dark:hover:via-blue-900/10 dark:hover:to-purple-900/20 hover:shadow-sm hover:shadow-cyan-500/5 dark:hover:shadow-cyan-400/5 transition-all duration-300\">\n <td class=\"px-4 py-4 whitespace-nowrap sm:pl-6\">\n <span class=\"inline-flex items-center rounded-md px-2.5 py-1 text-sm font-medium ring-1 ring-inset ${log.levelClass}\">\n ${log.level}\n </span>\n </td>\n <td class=\"px-4 py-4 whitespace-nowrap\">\n <span class=\"inline-flex items-center rounded-md px-2.5 py-1 text-sm font-medium ring-1 ring-inset ${log.categoryClass}\">\n ${log.category}\n </span>\n </td>\n <td class=\"px-4 py-4\">\n <div class=\"text-sm max-w-md\">\n <div class=\"truncate text-zinc-950 dark:text-white\" title=\"${log.message}\">${log.message}</div>\n ${log.url ? `<div class=\"text-xs text-zinc-500 dark:text-zinc-400 truncate mt-1\">${log.method} ${log.url}</div>` : ''}\n ${log.duration ? `<div class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">${log.formattedDuration}</div>` : ''}\n </div>\n </td>\n <td class=\"px-4 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400\">\n ${log.source || '-'}\n </td>\n <td class=\"px-4 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400\">\n ${log.formattedDate}\n </td>\n <td class=\"px-4 py-4 whitespace-nowrap text-right text-sm font-medium sm:pr-6\">\n <a href=\"/admin/logs/${log.id}\" class=\"text-cyan-600 dark:text-cyan-400 hover:text-cyan-700 dark:hover:text-cyan-300 transition-colors\">\n View Details\n </a>\n </td>\n </tr>\n `).join('')}\n </tbody>\n </table>\n </div>\n\n ${logs.length === 0 ? `\n <div class=\"text-center py-12\">\n <svg class=\"mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n <h3 class=\"mt-2 text-sm font-medium text-zinc-950 dark:text-white\">No log entries</h3>\n <p class=\"mt-1 text-sm text-zinc-500 dark:text-zinc-400\">No log entries found matching your criteria.</p>\n </div>\n ` : ''}\n </div>\n\n <!-- Pagination -->\n ${pagination.totalPages > 1 ? `\n <div class=\"mt-6 flex items-center justify-between\">\n <div class=\"flex-1 flex justify-between sm:hidden\">\n ${pagination.currentPage > 1 ? `\n <a\n href=\"${pagination.baseUrl}?${new URLSearchParams({...filters, page: (pagination.currentPage - 1).toString()}).toString()}\"\n class=\"relative inline-flex items-center px-4 py-2 rounded-lg bg-white dark:bg-zinc-800 text-sm font-medium text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-700 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 transition-colors\"\n >\n Previous\n </a>\n ` : `\n <span class=\"relative inline-flex items-center px-4 py-2 rounded-lg text-sm font-medium text-zinc-400 dark:text-zinc-600 bg-zinc-100 dark:bg-zinc-800 cursor-not-allowed\">\n Previous\n </span>\n `}\n ${pagination.currentPage < pagination.totalPages ? `\n <a\n href=\"${pagination.baseUrl}?${new URLSearchParams({...filters, page: (pagination.currentPage + 1).toString()}).toString()}\"\n class=\"ml-3 relative inline-flex items-center px-4 py-2 rounded-lg bg-white dark:bg-zinc-800 text-sm font-medium text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-700 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 transition-colors\"\n >\n Next\n </a>\n ` : `\n <span class=\"ml-3 relative inline-flex items-center px-4 py-2 rounded-lg text-sm font-medium text-zinc-400 dark:text-zinc-600 bg-zinc-100 dark:bg-zinc-800 cursor-not-allowed\">\n Next\n </span>\n `}\n </div>\n <div class=\"hidden sm:flex-1 sm:flex sm:items-center sm:justify-between\">\n <div>\n <p class=\"text-sm text-zinc-700 dark:text-zinc-300\">\n Showing <span class=\"font-medium\">${pagination.startItem}</span> to <span class=\"font-medium\">${pagination.endItem}</span> of{' '}\n <span class=\"font-medium\">${pagination.totalItems}</span> results\n </p>\n </div>\n <div>\n <nav class=\"relative z-0 inline-flex rounded-lg shadow-sm -space-x-px\" aria-label=\"Pagination\">\n ${pagination.currentPage > 1 ? `\n <a\n href=\"${pagination.baseUrl}?${new URLSearchParams({...filters, page: (pagination.currentPage - 1).toString()}).toString()}\"\n class=\"relative inline-flex items-center px-2 py-2 rounded-l-lg bg-white dark:bg-zinc-800 text-sm font-medium text-zinc-500 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:bg-zinc-700 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 transition-colors\"\n >\n <span class=\"sr-only\">Previous</span>\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\" clip-rule=\"evenodd\" />\n </svg>\n </a>\n ` : ''}\n\n ${Array.from({ length: Math.min(10, pagination.totalPages) }, (_, i) => {\n const page = Math.max(1, Math.min(pagination.totalPages - 9, pagination.currentPage - 5)) + i\n if (page > pagination.totalPages) return ''\n\n return `\n <a\n href=\"${pagination.baseUrl}?${new URLSearchParams({...filters, page: page.toString()}).toString()}\"\n class=\"relative inline-flex items-center px-4 py-2 text-sm font-medium ring-1 ring-inset transition-colors ${\n page === pagination.currentPage\n ? 'z-10 bg-cyan-50 dark:bg-cyan-900/20 ring-cyan-600 dark:ring-cyan-400 text-cyan-600 dark:text-cyan-400'\n : 'bg-white dark:bg-zinc-800 ring-zinc-950/10 dark:ring-white/10 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:bg-zinc-700'\n }\"\n >\n ${page}\n </a>\n `\n }).join('')}\n\n ${pagination.currentPage < pagination.totalPages ? `\n <a\n href=\"${pagination.baseUrl}?${new URLSearchParams({...filters, page: (pagination.currentPage + 1).toString()}).toString()}\"\n class=\"relative inline-flex items-center px-2 py-2 rounded-r-lg bg-white dark:bg-zinc-800 text-sm font-medium text-zinc-500 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:bg-zinc-700 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 transition-colors\"\n >\n <span class=\"sr-only\">Next</span>\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\" />\n </svg>\n </a>\n ` : ''}\n </nav>\n </div>\n </div>\n </div>\n ` : ''}\n </div>\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: 'System Logs',\n pageTitle: 'System Logs',\n currentPath: '/admin/logs',\n user,\n content\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}","import { html } from 'hono/html'\nimport { adminLayoutV2 } from '../layouts/admin-layout-v2.template'\nimport { LogEntry } from './admin-logs-list.template'\n\ninterface BaseUser {\n name: string\n email: string\n role: string\n}\n\nexport interface LogDetailsPageData {\n log: LogEntry\n user?: BaseUser\n}\n\nexport function renderLogDetailsPage(data: LogDetailsPageData) {\n const { log, user } = data\n\n const content = html`\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <nav class=\"mb-4\">\n <a href=\"/admin/logs\" class=\"text-indigo-600 hover:text-indigo-900\">\n ← Back to Logs\n </a>\n </nav>\n <h1 class=\"text-2xl font-semibold text-gray-900\">Log Details</h1>\n <p class=\"mt-2 text-sm text-gray-700\">\n Detailed information for log entry ${log.id}\n </p>\n </div>\n </div>\n\n <div class=\"mt-6 bg-white shadow rounded-lg overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <div class=\"flex items-center justify-between\">\n <h2 class=\"text-lg font-medium text-gray-900\">Log Entry Information</h2>\n <div class=\"flex items-center space-x-2\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${log.levelClass}\">\n ${log.level}\n </span>\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${log.categoryClass}\">\n ${log.category}\n </span>\n </div>\n </div>\n </div>\n \n <div class=\"px-6 py-4\">\n <dl class=\"grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-2\">\n <div>\n <dt class=\"text-sm font-medium text-gray-500\">ID</dt>\n <dd class=\"mt-1 text-sm text-gray-900 font-mono\">${log.id}</dd>\n </div>\n \n <div>\n <dt class=\"text-sm font-medium text-gray-500\">Timestamp</dt>\n <dd class=\"mt-1 text-sm text-gray-900\">${log.formattedDate}</dd>\n </div>\n \n <div>\n <dt class=\"text-sm font-medium text-gray-500\">Level</dt>\n <dd class=\"mt-1\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${log.levelClass}\">\n ${log.level}\n </span>\n </dd>\n </div>\n \n <div>\n <dt class=\"text-sm font-medium text-gray-500\">Category</dt>\n <dd class=\"mt-1\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${log.categoryClass}\">\n ${log.category}\n </span>\n </dd>\n </div>\n \n ${log.source ? html`\n <div>\n <dt class=\"text-sm font-medium text-gray-500\">Source</dt>\n <dd class=\"mt-1 text-sm text-gray-900\">${log.source}</dd>\n </div>\n ` : ''}\n \n ${log.userId ? html`\n <div>\n <dt class=\"text-sm font-medium text-gray-500\">User ID</dt>\n <dd class=\"mt-1 text-sm text-gray-900 font-mono\">${log.userId}</dd>\n </div>\n ` : ''}\n \n ${log.sessionId ? html`\n <div>\n <dt class=\"text-sm font-medium text-gray-500\">Session ID</dt>\n <dd class=\"mt-1 text-sm text-gray-900 font-mono\">${log.sessionId}</dd>\n </div>\n ` : ''}\n \n ${log.requestId ? html`\n <div>\n <dt class=\"text-sm font-medium text-gray-500\">Request ID</dt>\n <dd class=\"mt-1 text-sm text-gray-900 font-mono\">${log.requestId}</dd>\n </div>\n ` : ''}\n \n ${log.ipAddress ? html`\n <div>\n <dt class=\"text-sm font-medium text-gray-500\">IP Address</dt>\n <dd class=\"mt-1 text-sm text-gray-900\">${log.ipAddress}</dd>\n </div>\n ` : ''}\n \n ${log.method && log.url ? html`\n <div class=\"sm:col-span-2\">\n <dt class=\"text-sm font-medium text-gray-500\">HTTP Request</dt>\n <dd class=\"mt-1 text-sm text-gray-900\">\n <span class=\"font-medium\">${log.method}</span> ${log.url}\n ${log.statusCode ? html`<span class=\"ml-2 text-gray-500\">(${log.statusCode})</span>` : ''}\n </dd>\n </div>\n ` : ''}\n \n ${log.duration ? html`\n <div>\n <dt class=\"text-sm font-medium text-gray-500\">Duration</dt>\n <dd class=\"mt-1 text-sm text-gray-900\">${log.formattedDuration}</dd>\n </div>\n ` : ''}\n \n ${log.userAgent ? html`\n <div class=\"sm:col-span-2\">\n <dt class=\"text-sm font-medium text-gray-500\">User Agent</dt>\n <dd class=\"mt-1 text-sm text-gray-900 break-all\">${log.userAgent}</dd>\n </div>\n ` : ''}\n </dl>\n </div>\n </div>\n\n <!-- Message -->\n <div class=\"mt-6 bg-white shadow rounded-lg overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <h3 class=\"text-lg font-medium text-gray-900\">Message</h3>\n </div>\n <div class=\"px-6 py-4\">\n <div class=\"text-sm text-gray-900 whitespace-pre-wrap break-words\">\n ${log.message}\n </div>\n </div>\n </div>\n\n <!-- Tags -->\n ${log.tags && log.tags.length > 0 ? html`\n <div class=\"mt-6 bg-white shadow rounded-lg overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <h3 class=\"text-lg font-medium text-gray-900\">Tags</h3>\n </div>\n <div class=\"px-6 py-4\">\n <div class=\"flex flex-wrap gap-2\">\n ${log.tags.map(tag => html`\n <span class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800\">\n ${tag}\n </span>\n `).join('')}\n </div>\n </div>\n </div>\n ` : ''}\n\n <!-- Additional Data -->\n ${log.data ? html`\n <div class=\"mt-6 bg-white shadow rounded-lg overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <h3 class=\"text-lg font-medium text-gray-900\">Additional Data</h3>\n </div>\n <div class=\"px-6 py-4\">\n <pre class=\"text-sm text-gray-900 bg-gray-50 rounded-md p-4 overflow-x-auto\"><code>${JSON.stringify(log.data, null, 2)}</code></pre>\n </div>\n </div>\n ` : ''}\n\n <!-- Stack Trace -->\n ${log.stackTrace ? html`\n <div class=\"mt-6 bg-white shadow rounded-lg overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <h3 class=\"text-lg font-medium text-gray-900\">Stack Trace</h3>\n </div>\n <div class=\"px-6 py-4\">\n <pre class=\"text-sm text-gray-900 bg-gray-50 rounded-md p-4 overflow-x-auto whitespace-pre-wrap\"><code>${log.stackTrace}</code></pre>\n </div>\n </div>\n ` : ''}\n\n <!-- Actions -->\n <div class=\"mt-6 flex justify-between\">\n <a\n href=\"/admin/logs\"\n class=\"inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"\n >\n ← Back to Logs\n </a>\n \n <div class=\"flex space-x-3\">\n ${log.level === 'error' || log.level === 'fatal' ? html`\n <button\n type=\"button\"\n class=\"inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500\"\n onclick=\"alert('Error reporting functionality would be implemented here')\"\n >\n Report Issue\n </button>\n ` : ''}\n \n <button\n type=\"button\"\n class=\"inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"\n onclick=\"navigator.clipboard.writeText(JSON.stringify(${JSON.stringify(log)}, null, 2)).then(() => alert('Log details copied to clipboard'))\"\n >\n Copy Details\n </button>\n </div>\n </div>\n </div>\n `\n\n return adminLayoutV2({\n title: `Log Details - ${log.id}`,\n user,\n content: content as string\n })\n}","import { html } from 'hono/html'\nimport { adminLayoutV2 } from '../layouts/admin-layout-v2.template'\nimport { LogConfig } from '@sonicjs-cms/core'\n\ninterface BaseUser {\n name: string\n email: string\n role: string\n}\n\nexport interface LogConfigPageData {\n configs: LogConfig[]\n user?: BaseUser\n}\n\nexport function renderLogConfigPage(data: LogConfigPageData) {\n const { configs, user } = data\n\n const content = html`\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <nav class=\"mb-4\">\n <a href=\"/admin/logs\" class=\"text-indigo-600 hover:text-indigo-900\">\n ← Back to Logs\n </a>\n </nav>\n <h1 class=\"text-2xl font-semibold text-gray-900\">Log Configuration</h1>\n <p class=\"mt-2 text-sm text-gray-700\">\n Configure logging settings for different categories and manage log retention policies.\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none\">\n <button\n type=\"button\"\n hx-post=\"/admin/logs/cleanup\"\n hx-confirm=\"Are you sure you want to run log cleanup? This will permanently delete old logs based on retention policies.\"\n hx-target=\"#cleanup-result\"\n class=\"inline-flex items-center justify-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2\"\n >\n Run Cleanup\n </button>\n </div>\n </div>\n\n <div id=\"cleanup-result\" class=\"mt-4\"></div>\n\n <!-- Log Levels Reference -->\n <div class=\"mt-6 bg-white shadow rounded-lg\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <h2 class=\"text-lg font-medium text-gray-900\">Log Levels Reference</h2>\n </div>\n <div class=\"px-6 py-4\">\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-5\">\n <div class=\"text-center\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800\">\n debug\n </span>\n <p class=\"mt-2 text-xs text-gray-500\">Detailed diagnostic information</p>\n </div>\n <div class=\"text-center\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800\">\n info\n </span>\n <p class=\"mt-2 text-xs text-gray-500\">General information messages</p>\n </div>\n <div class=\"text-center\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800\">\n warn\n </span>\n <p class=\"mt-2 text-xs text-gray-500\">Warning conditions</p>\n </div>\n <div class=\"text-center\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800\">\n error\n </span>\n <p class=\"mt-2 text-xs text-gray-500\">Error conditions</p>\n </div>\n <div class=\"text-center\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-purple-100 text-purple-800\">\n fatal\n </span>\n <p class=\"mt-2 text-xs text-gray-500\">Critical system errors</p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Configuration Cards -->\n <div class=\"mt-8 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n ${configs.map(config => html`\n <div class=\"bg-white shadow rounded-lg overflow-hidden\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <div class=\"flex items-center justify-between\">\n <h3 class=\"text-lg font-medium text-gray-900 capitalize\">${config.category}</h3>\n <div class=\"flex items-center\">\n ${config.enabled ? html`\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800\">\n Enabled\n </span>\n ` : html`\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800\">\n Disabled\n </span>\n `}\n </div>\n </div>\n </div>\n \n <form hx-post=\"/admin/logs/config/${config.category}\" hx-target=\"#config-result-${config.category}\">\n <div class=\"px-6 py-4 space-y-4\">\n <div class=\"flex gap-3\">\n <div class=\"flex h-6 shrink-0 items-center\">\n <div class=\"group grid size-4 grid-cols-1\">\n <input\n id=\"enabled-${config.category}\"\n name=\"enabled\"\n type=\"checkbox\"\n ${config.enabled ? 'checked' : ''}\n class=\"col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto\"\n />\n <svg viewBox=\"0 0 14 14\" fill=\"none\" class=\"pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25\">\n <path d=\"M3 8L6 11L11 3.5\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:checked]:opacity-100\" />\n <path d=\"M3 7H11\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"opacity-0 group-has-[:indeterminate]:opacity-100\" />\n </svg>\n </div>\n </div>\n <div class=\"text-sm/6\">\n <label for=\"enabled-${config.category}\" class=\"font-medium text-zinc-950 dark:text-white\">\n Enable logging for this category\n </label>\n </div>\n </div>\n \n <div>\n <label for=\"level-${config.category}\" class=\"block text-sm font-medium text-gray-700\">\n Minimum Log Level\n </label>\n <select\n id=\"level-${config.category}\"\n name=\"level\"\n class=\"mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm\"\n >\n <option value=\"debug\" ${config.level === 'debug' ? 'selected' : ''}>Debug</option>\n <option value=\"info\" ${config.level === 'info' ? 'selected' : ''}>Info</option>\n <option value=\"warn\" ${config.level === 'warn' ? 'selected' : ''}>Warning</option>\n <option value=\"error\" ${config.level === 'error' ? 'selected' : ''}>Error</option>\n <option value=\"fatal\" ${config.level === 'fatal' ? 'selected' : ''}>Fatal</option>\n </select>\n <p class=\"mt-1 text-sm text-gray-500\">Only logs at this level or higher will be stored</p>\n </div>\n \n <div>\n <label for=\"retention-${config.category}\" class=\"block text-sm font-medium text-gray-700\">\n Retention Period (days)\n </label>\n <input\n type=\"number\"\n id=\"retention-${config.category}\"\n name=\"retention\"\n value=\"${config.retention}\"\n min=\"1\"\n max=\"365\"\n class=\"mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm\"\n />\n <p class=\"mt-1 text-sm text-gray-500\">Logs older than this will be deleted</p>\n </div>\n \n <div>\n <label for=\"max_size-${config.category}\" class=\"block text-sm font-medium text-gray-700\">\n Maximum Log Count\n </label>\n <input\n type=\"number\"\n id=\"max_size-${config.category}\"\n name=\"max_size\"\n value=\"${config.maxSize || ''}\"\n min=\"100\"\n max=\"100000\"\n class=\"mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm\"\n />\n <p class=\"mt-1 text-sm text-gray-500\">Maximum number of logs to keep for this category</p>\n </div>\n </div>\n \n <div class=\"px-6 py-4 bg-gray-50 border-t border-gray-200\">\n <div id=\"config-result-${config.category}\" class=\"mb-4\"></div>\n <button\n type=\"submit\"\n class=\"w-full inline-flex justify-center items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"\n >\n Update Configuration\n </button>\n </div>\n </form>\n \n <div class=\"px-6 py-3 bg-gray-50 border-t border-gray-200\">\n <div class=\"text-xs text-gray-500\">\n <div>Created: ${new Date(config.createdAt).toLocaleDateString()}</div>\n <div>Updated: ${new Date(config.updatedAt).toLocaleDateString()}</div>\n </div>\n </div>\n </div>\n `).join('')}\n </div>\n\n <!-- Global Settings -->\n <div class=\"mt-8 bg-white shadow rounded-lg\">\n <div class=\"px-6 py-4 border-b border-gray-200\">\n <h2 class=\"text-lg font-medium text-gray-900\">Global Log Settings</h2>\n </div>\n <div class=\"px-6 py-4\">\n <div class=\"space-y-6\">\n <div>\n <h3 class=\"text-base font-medium text-gray-900\">Storage Information</h3>\n <div class=\"mt-2 grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div class=\"bg-gray-50 rounded-lg p-4\">\n <div class=\"text-2xl font-bold text-gray-900\">-</div>\n <div class=\"text-sm text-gray-500\">Total Log Entries</div>\n </div>\n <div class=\"bg-gray-50 rounded-lg p-4\">\n <div class=\"text-2xl font-bold text-gray-900\">-</div>\n <div class=\"text-sm text-gray-500\">Storage Used</div>\n </div>\n <div class=\"bg-gray-50 rounded-lg p-4\">\n <div class=\"text-2xl font-bold text-gray-900\">-</div>\n <div class=\"text-sm text-gray-500\">Oldest Log</div>\n </div>\n </div>\n </div>\n \n <div>\n <h3 class=\"text-base font-medium text-gray-900\">Log Categories</h3>\n <div class=\"mt-2 text-sm text-gray-600\">\n <ul class=\"list-disc list-inside space-y-1\">\n <li><strong>auth</strong> - Authentication and authorization events</li>\n <li><strong>api</strong> - API requests and responses</li>\n <li><strong>workflow</strong> - Content workflow state changes</li>\n <li><strong>plugin</strong> - Plugin-related activities</li>\n <li><strong>media</strong> - File upload and media operations</li>\n <li><strong>system</strong> - General system events</li>\n <li><strong>security</strong> - Security-related events and alerts</li>\n <li><strong>error</strong> - General error conditions</li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <script src=\"https://unpkg.com/htmx.org@1.9.6\"></script>\n `\n\n return adminLayoutV2({\n title: 'Log Configuration',\n user,\n content: content as string\n })\n}","import { Hono } from 'hono'\nimport { html } from 'hono/html'\nimport type { D1Database, KVNamespace } from '@cloudflare/workers-types'\nimport { getLogger, type LogLevel, type LogCategory, type LogFilter } from '../services'\nimport { renderLogsListPage, type LogsListPageData } from '../templates/pages/admin-logs-list.template'\nimport { renderLogDetailsPage, type LogDetailsPageData } from '../templates/pages/admin-log-details.template'\nimport { renderLogConfigPage, type LogConfigPageData } from '../templates/pages/admin-log-config.template'\nimport type { Bindings, Variables } from '../app'\n\nconst adminLogsRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n// Main logs listing page\nadminLogsRoutes.get('/', async (c) => {\n try {\n const user = c.get('user')\n const logger = getLogger(c.env.DB)\n \n // Use Hono's built-in query method instead of parsing URL\n const query = c.req.query()\n \n // Parse query parameters\n const page = parseInt(query.page || '1')\n const limit = parseInt(query.limit || '50')\n const level = query.level\n const category = query.category\n const search = query.search\n const startDate = query.start_date\n const endDate = query.end_date\n const source = query.source\n \n // Build filter\n const filter: LogFilter = {\n limit,\n offset: (page - 1) * limit,\n sortBy: 'created_at',\n sortOrder: 'desc'\n }\n \n if (level) {\n filter.level = level.split(',') as LogLevel[]\n }\n \n if (category) {\n filter.category = category.split(',') as LogCategory[]\n }\n \n if (search) {\n filter.search = search\n }\n \n if (startDate) {\n filter.startDate = new Date(startDate)\n }\n \n if (endDate) {\n filter.endDate = new Date(endDate)\n }\n \n if (source) {\n filter.source = source\n }\n \n // Get logs and total count\n const { logs, total } = await logger.getLogs(filter)\n \n // Format logs for display\n const formattedLogs = logs.map(log => ({\n ...log,\n data: log.data ? JSON.parse(log.data) : null,\n tags: log.tags ? JSON.parse(log.tags) : [],\n formattedDate: new Date(log.createdAt).toLocaleString(),\n formattedDuration: log.duration ? `${log.duration}ms` : null,\n levelClass: getLevelClass(log.level),\n categoryClass: getCategoryClass(log.category)\n }))\n \n const totalPages = Math.ceil(total / limit)\n \n const pageData: LogsListPageData = {\n logs: formattedLogs,\n pagination: {\n currentPage: page,\n totalPages,\n totalItems: total,\n itemsPerPage: limit,\n startItem: (page - 1) * limit + 1,\n endItem: Math.min(page * limit, total),\n baseUrl: '/admin/logs'\n },\n filters: {\n level: level || '',\n category: category || '',\n search: search || '',\n startDate: startDate || '',\n endDate: endDate || '',\n source: source || ''\n },\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n \n return c.html(renderLogsListPage(pageData))\n } catch (error) {\n console.error('Error fetching logs:', error)\n return c.html(html`<p>Error loading logs: ${error}</p>`)\n }\n})\n\n// Log details page\nadminLogsRoutes.get('/:id', async (c) => {\n try {\n const id = c.req.param('id')\n const user = c.get('user')\n const logger = getLogger(c.env.DB)\n \n // Get single log by ID\n const { logs } = await logger.getLogs({ \n limit: 1, \n offset: 0,\n search: id // Using search to find by ID - this is a simplification\n })\n \n const log = logs.find(l => l.id === id)\n \n if (!log) {\n return c.html(html`<p>Log entry not found</p>`)\n }\n \n const formattedLog = {\n ...log,\n data: log.data ? JSON.parse(log.data) : null,\n tags: log.tags ? JSON.parse(log.tags) : [],\n formattedDate: new Date(log.createdAt).toLocaleString(),\n formattedDuration: log.duration ? `${log.duration}ms` : null,\n levelClass: getLevelClass(log.level),\n categoryClass: getCategoryClass(log.category)\n }\n \n const pageData: LogDetailsPageData = {\n log: formattedLog,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n \n return c.html(renderLogDetailsPage(pageData))\n } catch (error) {\n console.error('Error fetching log details:', error)\n return c.html(html`<p>Error loading log details: ${error}</p>`)\n }\n})\n\n// Log configuration page\nadminLogsRoutes.get('/config', async (c) => {\n try {\n const user = c.get('user')\n const logger = getLogger(c.env.DB)\n \n // Get all log configurations\n const configs = await logger.getAllConfigs()\n \n const pageData: LogConfigPageData = {\n configs,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n \n return c.html(renderLogConfigPage(pageData))\n } catch (error) {\n console.error('Error fetching log config:', error)\n return c.html(html`<p>Error loading log configuration: ${error}</p>`)\n }\n})\n\n// Update log configuration\nadminLogsRoutes.post('/config/:category', async (c) => {\n try {\n const category = c.req.param('category') as LogCategory\n const formData = await c.req.formData()\n \n const enabled = formData.get('enabled') === 'on'\n const level = formData.get('level') as string\n const retention = parseInt(formData.get('retention') as string)\n const maxSize = parseInt(formData.get('max_size') as string)\n \n const logger = getLogger(c.env.DB)\n await logger.updateConfig(category, {\n enabled,\n level,\n retention,\n maxSize\n })\n \n return c.html(html`\n <div class=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded\">\n Configuration updated successfully!\n </div>\n `)\n } catch (error) {\n console.error('Error updating log config:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Failed to update configuration. Please try again.\n </div>\n `)\n }\n})\n\n// Export logs\nadminLogsRoutes.get('/export', async (c) => {\n try {\n const query = c.req.query()\n const format = query.format || 'csv'\n const level = query.level\n const category = query.category\n const startDate = query.start_date\n const endDate = query.end_date\n \n const logger = getLogger(c.env.DB)\n \n // Build filter for export\n const filter: LogFilter = {\n limit: 10000, // Export up to 10k logs\n offset: 0,\n sortBy: 'created_at',\n sortOrder: 'desc'\n }\n \n if (level) {\n filter.level = level.split(',') as LogLevel[]\n }\n \n if (category) {\n filter.category = category.split(',') as LogCategory[]\n }\n \n if (startDate) {\n filter.startDate = new Date(startDate)\n }\n \n if (endDate) {\n filter.endDate = new Date(endDate)\n }\n \n const { logs } = await logger.getLogs(filter)\n \n if (format === 'json') {\n return c.json(logs, 200, {\n 'Content-Disposition': 'attachment; filename=\"logs-export.json\"'\n })\n } else {\n // Default to CSV\n const headers = [\n 'ID', 'Level', 'Category', 'Message', 'Source', 'User ID', \n 'IP Address', 'Method', 'URL', 'Status Code', 'Duration', \n 'Created At'\n ]\n const csvRows = [headers.join(',')]\n \n logs.forEach(log => {\n const row = [\n log.id,\n log.level,\n log.category,\n `\"${log.message.replace(/\"/g, '\"\"')}\"`, // Escape quotes\n log.source || '',\n log.userId || '',\n log.ipAddress || '',\n log.method || '',\n log.url || '',\n log.statusCode || '',\n log.duration || '',\n new Date(log.createdAt).toISOString()\n ]\n csvRows.push(row.join(','))\n })\n \n const csv = csvRows.join('\\n')\n \n return new Response(csv, {\n headers: {\n 'Content-Type': 'text/csv',\n 'Content-Disposition': 'attachment; filename=\"logs-export.csv\"'\n }\n })\n }\n } catch (error) {\n console.error('Error exporting logs:', error)\n return c.json({ error: 'Failed to export logs' }, 500)\n }\n})\n\n// Clean up old logs\nadminLogsRoutes.post('/cleanup', async (c) => {\n try {\n const user = c.get('user')\n \n // Only allow admin users to run cleanup\n if (!user || user.role !== 'admin') {\n return c.json({ \n success: false, \n error: 'Unauthorized. Admin access required.' \n }, 403)\n }\n \n const logger = getLogger(c.env.DB)\n await logger.cleanupByRetention()\n \n return c.html(html`\n <div class=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded\">\n Log cleanup completed successfully!\n </div>\n `)\n } catch (error) {\n console.error('Error cleaning up logs:', error)\n return c.html(html`\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded\">\n Failed to clean up logs. Please try again.\n </div>\n `)\n }\n})\n\n// Search logs (HTMX endpoint)\nadminLogsRoutes.post('/search', async (c) => {\n try {\n const formData = await c.req.formData()\n const search = formData.get('search') as string\n const level = formData.get('level') as string\n const category = formData.get('category') as string\n \n const logger = getLogger(c.env.DB)\n \n const filter: LogFilter = {\n limit: 20,\n offset: 0,\n sortBy: 'created_at',\n sortOrder: 'desc'\n }\n \n if (search) filter.search = search\n if (level) filter.level = [level] as LogLevel[]\n if (category) filter.category = [category] as LogCategory[]\n \n const { logs } = await logger.getLogs(filter)\n \n // Return just the logs table rows for HTMX\n const rows = logs.map(log => {\n const formattedLog = {\n ...log,\n formattedDate: new Date(log.createdAt).toLocaleString(),\n levelClass: getLevelClass(log.level),\n categoryClass: getCategoryClass(log.category)\n }\n\n return `\n <tr class=\"hover:bg-gray-50\">\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${formattedLog.levelClass}\">\n ${formattedLog.level}\n </span>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <span class=\"px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${formattedLog.categoryClass}\">\n ${formattedLog.category}\n </span>\n </td>\n <td class=\"px-6 py-4\">\n <div class=\"text-sm text-gray-900 max-w-md truncate\">${formattedLog.message}</div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">${formattedLog.source || '-'}</td>\n <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">${formattedLog.formattedDate}</td>\n <td class=\"px-6 py-4 whitespace-nowrap text-right text-sm font-medium\">\n <a href=\"/admin/logs/${formattedLog.id}\" class=\"text-indigo-600 hover:text-indigo-900\">View</a>\n </td>\n </tr>\n `\n }).join('')\n\n return c.html(rows)\n } catch (error) {\n console.error('Error searching logs:', error)\n return c.html(html`<tr><td colspan=\"6\" class=\"px-6 py-4 text-center text-red-500\">Error searching logs</td></tr>`)\n }\n})\n\n// Helper functions\nfunction getLevelClass(level: string): string {\n switch (level) {\n case 'debug': return 'bg-gray-100 text-gray-800'\n case 'info': return 'bg-blue-100 text-blue-800'\n case 'warn': return 'bg-yellow-100 text-yellow-800'\n case 'error': return 'bg-red-100 text-red-800'\n case 'fatal': return 'bg-purple-100 text-purple-800'\n default: return 'bg-gray-100 text-gray-800'\n }\n}\n\nfunction getCategoryClass(category: string): string {\n switch (category) {\n case 'auth': return 'bg-green-100 text-green-800'\n case 'api': return 'bg-blue-100 text-blue-800'\n case 'workflow': return 'bg-purple-100 text-purple-800'\n case 'plugin': return 'bg-indigo-100 text-indigo-800'\n case 'media': return 'bg-pink-100 text-pink-800'\n case 'system': return 'bg-gray-100 text-gray-800'\n case 'security': return 'bg-red-100 text-red-800'\n case 'error': return 'bg-red-100 text-red-800'\n default: return 'bg-gray-100 text-gray-800'\n }\n}\n\nexport { adminLogsRoutes }","import { Hono } from 'hono'\nimport { renderDesignPage, DesignPageData } from '../templates/pages/admin-design.template'\n\ntype Bindings = {\n DB: D1Database\n KV: KVNamespace\n}\n\ntype Variables = {\n user: {\n userId: string\n email: string\n role: string\n }\n}\n\nexport const adminDesignRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\nadminDesignRoutes.get('/', (c) => {\n const user = c.get('user')\n \n const pageData: DesignPageData = {\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n \n return c.html(renderDesignPage(pageData))\n})","import { Hono } from 'hono'\nimport { renderCheckboxPage, CheckboxPageData } from '../templates/pages/admin-checkboxes.template'\n\ntype Bindings = {\n DB: D1Database\n KV: KVNamespace\n}\n\ntype Variables = {\n user: {\n userId: string\n email: string\n role: string\n }\n}\n\nexport const adminCheckboxRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\nadminCheckboxRoutes.get('/', (c) => {\n const user = c.get('user')\n\n const pageData: CheckboxPageData = {\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }\n\n return c.html(renderCheckboxPage(pageData))\n})\n","import { renderAdminLayout, AdminLayoutData } from '../layouts/admin-layout-v2.template'\nimport { renderAlert } from '../alert.template'\n\ninterface FAQ {\n id?: number\n question: string\n answer: string\n category?: string\n tags?: string\n isPublished: boolean\n sortOrder: number\n}\n\ninterface FAQFormData {\n faq?: FAQ\n isEdit: boolean\n errors?: Record<string, string[]>\n user?: { name: string; email: string; role: string }\n message?: string\n messageType?: 'success' | 'error' | 'warning' | 'info'\n}\n\nexport function renderFAQForm(data: FAQFormData): string {\n const { faq, isEdit, errors, message, messageType } = data\n const pageTitle = isEdit ? 'Edit FAQ' : 'New FAQ'\n\n const pageContent = `\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6 space-y-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl font-semibold text-white\">${pageTitle}</h1>\n <p class=\"mt-2 text-sm text-gray-300\">\n ${isEdit ? 'Update the FAQ details below' : 'Create a new frequently asked question'}\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none\">\n <a href=\"/admin/faq\" \n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-white/10 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-white/20 transition-all\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 19l-7-7m0 0l7-7m-7 7h18\" />\n </svg>\n Back to List\n </a>\n </div>\n </div>\n\n ${message ? renderAlert({ type: messageType || 'info', message, dismissible: true }) : ''}\n\n <!-- Form -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl\">\n <form ${isEdit ? `hx-put=\"/admin/faq/${faq?.id}\"` : 'hx-post=\"/admin/faq\"'} \n hx-target=\"body\" \n hx-swap=\"outerHTML\"\n class=\"space-y-6 p-6\">\n \n <!-- Question -->\n <div>\n <label for=\"question\" class=\"block text-sm font-medium text-white\">\n Question <span class=\"text-red-400\">*</span>\n </label>\n <div class=\"mt-1\">\n <textarea name=\"question\" \n id=\"question\" \n rows=\"3\" \n required\n maxlength=\"500\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-xl px-3 py-2 text-white placeholder-gray-300 focus:border-blue-400 focus:outline-none transition-colors w-full\"\n placeholder=\"Enter the frequently asked question...\">${faq?.question || ''}</textarea>\n <p class=\"mt-1 text-sm text-gray-300\">\n <span id=\"question-count\">0</span>/500 characters\n </p>\n </div>\n ${errors?.question ? `\n <div class=\"mt-1\">\n ${errors.question.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Answer -->\n <div>\n <label for=\"answer\" class=\"block text-sm font-medium text-white\">\n Answer <span class=\"text-red-400\">*</span>\n </label>\n <div class=\"mt-1\">\n <textarea name=\"answer\" \n id=\"answer\" \n rows=\"6\" \n required\n maxlength=\"2000\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-xl px-3 py-2 text-white placeholder-gray-300 focus:border-blue-400 focus:outline-none transition-colors w-full\"\n placeholder=\"Enter the detailed answer...\">${faq?.answer || ''}</textarea>\n <p class=\"mt-1 text-sm text-gray-300\">\n <span id=\"answer-count\">0</span>/2000 characters. You can use basic HTML for formatting.\n </p>\n </div>\n ${errors?.answer ? `\n <div class=\"mt-1\">\n ${errors.answer.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Category and Tags Row -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <!-- Category -->\n <div>\n <label for=\"category\" class=\"block text-sm font-medium text-white\">Category</label>\n <div class=\"mt-1\">\n <select name=\"category\" \n id=\"category\" \n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\">\n <option value=\"\">Select a category</option>\n <option value=\"general\" ${faq?.category === 'general' ? 'selected' : ''}>General</option>\n <option value=\"technical\" ${faq?.category === 'technical' ? 'selected' : ''}>Technical</option>\n <option value=\"billing\" ${faq?.category === 'billing' ? 'selected' : ''}>Billing</option>\n <option value=\"support\" ${faq?.category === 'support' ? 'selected' : ''}>Support</option>\n <option value=\"account\" ${faq?.category === 'account' ? 'selected' : ''}>Account</option>\n <option value=\"features\" ${faq?.category === 'features' ? 'selected' : ''}>Features</option>\n </select>\n </div>\n ${errors?.category ? `\n <div class=\"mt-1\">\n ${errors.category.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Tags -->\n <div>\n <label for=\"tags\" class=\"block text-sm font-medium text-white\">Tags</label>\n <div class=\"mt-1\">\n <input type=\"text\" \n name=\"tags\" \n id=\"tags\" \n value=\"${faq?.tags || ''}\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\"\n placeholder=\"e.g., payment, setup, troubleshooting\">\n <p class=\"mt-1 text-sm text-gray-300\">Separate multiple tags with commas</p>\n </div>\n ${errors?.tags ? `\n <div class=\"mt-1\">\n ${errors.tags.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n\n <!-- Status and Sort Order Row -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <!-- Published Status -->\n <div>\n <label class=\"block text-sm font-medium text-white\">Status</label>\n <div class=\"mt-2 space-y-2\">\n <div class=\"flex items-center\">\n <input id=\"published\" \n name=\"isPublished\" \n type=\"radio\" \n value=\"true\"\n ${!faq || faq.isPublished ? 'checked' : ''}\n class=\"h-4 w-4 text-blue-600 focus:ring-blue-600 border-gray-600 bg-gray-700\">\n <label for=\"published\" class=\"ml-2 block text-sm text-white\">\n Published <span class=\"text-gray-300\">(visible to users)</span>\n </label>\n </div>\n <div class=\"flex items-center\">\n <input id=\"draft\" \n name=\"isPublished\" \n type=\"radio\" \n value=\"false\"\n ${faq && !faq.isPublished ? 'checked' : ''}\n class=\"h-4 w-4 text-blue-600 focus:ring-blue-600 border-gray-600 bg-gray-700\">\n <label for=\"draft\" class=\"ml-2 block text-sm text-white\">\n Draft <span class=\"text-gray-300\">(not visible to users)</span>\n </label>\n </div>\n </div>\n </div>\n\n <!-- Sort Order -->\n <div>\n <label for=\"sortOrder\" class=\"block text-sm font-medium text-white\">Sort Order</label>\n <div class=\"mt-1\">\n <input type=\"number\" \n name=\"sortOrder\" \n id=\"sortOrder\" \n value=\"${faq?.sortOrder || 0}\"\n min=\"0\"\n step=\"1\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\">\n <p class=\"mt-1 text-sm text-gray-300\">Lower numbers appear first (0 = highest priority)</p>\n </div>\n ${errors?.sortOrder ? `\n <div class=\"mt-1\">\n ${errors.sortOrder.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"flex items-center justify-end space-x-3 pt-6 border-t border-white/20\">\n <a href=\"/admin/faq\" \n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-white/10 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-white/20 transition-all\">\n Cancel\n </a>\n <button type=\"submit\" \n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-blue-500/80 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-blue-500 transition-all\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n ${isEdit ? 'Update FAQ' : 'Create FAQ'}\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <script>\n // Character count for question\n const questionTextarea = document.getElementById('question');\n const questionCount = document.getElementById('question-count');\n \n function updateQuestionCount() {\n questionCount.textContent = questionTextarea.value.length;\n }\n \n questionTextarea.addEventListener('input', updateQuestionCount);\n updateQuestionCount(); // Initial count\n\n // Character count for answer\n const answerTextarea = document.getElementById('answer');\n const answerCount = document.getElementById('answer-count');\n \n function updateAnswerCount() {\n answerCount.textContent = answerTextarea.value.length;\n }\n \n answerTextarea.addEventListener('input', updateAnswerCount);\n updateAnswerCount(); // Initial count\n </script>\n `\n\n const layoutData: AdminLayoutData = {\n title: `${pageTitle} - Admin`,\n pageTitle,\n currentPath: isEdit ? `/admin/faq/${faq?.id}` : '/admin/faq/new',\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayout(layoutData)\n}\n\nfunction escapeHtml(unsafe: string): string {\n return unsafe\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\")\n}","import { Hono } from 'hono'\nimport { z } from 'zod'\nimport { renderFAQList } from '../templates/pages/admin-faq-list.template'\nimport { renderFAQForm } from '../templates/pages/admin-faq-form.template'\n\ntype Bindings = {\n DB: D1Database\n KV: KVNamespace\n}\n\ntype Variables = {\n user?: {\n userId: string\n email: string\n role: string\n exp: number\n iat: number\n }\n}\n\nconst faqSchema = z.object({\n question: z.string().min(1, 'Question is required').max(500, 'Question must be under 500 characters'),\n answer: z.string().min(1, 'Answer is required').max(2000, 'Answer must be under 2000 characters'),\n category: z.string().optional(),\n tags: z.string().optional(),\n isPublished: z.string().transform(val => val === 'true'),\n sortOrder: z.string().transform(val => parseInt(val, 10)).pipe(z.number().min(0))\n})\n\nconst adminFAQRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\nadminFAQRoutes.get('/', async (c) => {\n try {\n const user = c.get('user')\n const { category, published, search, page = '1' } = c.req.query()\n const currentPage = parseInt(page, 10) || 1\n const limit = 20\n const offset = (currentPage - 1) * limit\n\n const db = (c as any).env?.DB\n if (!db) {\n return c.html(renderFAQList({\n faqs: [],\n totalCount: 0,\n currentPage: 1,\n totalPages: 1,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n let whereClause = 'WHERE 1=1'\n const params: any[] = []\n\n if (category) {\n whereClause += ' AND category = ?'\n params.push(category)\n }\n\n if (published !== undefined) {\n whereClause += ' AND isPublished = ?'\n params.push(published === 'true' ? 1 : 0)\n }\n\n if (search) {\n whereClause += ' AND (question LIKE ? OR answer LIKE ? OR tags LIKE ?)'\n const searchTerm = `%${search}%`\n params.push(searchTerm, searchTerm, searchTerm)\n }\n\n const countQuery = `SELECT COUNT(*) as count FROM faqs ${whereClause}`\n const { results: countResults } = await db.prepare(countQuery).bind(...params).all()\n const totalCount = countResults?.[0]?.count || 0\n\n const dataQuery = `\n SELECT * FROM faqs \n ${whereClause} \n ORDER BY sortOrder ASC, created_at DESC \n LIMIT ? OFFSET ?\n `\n const { results: faqs } = await db.prepare(dataQuery).bind(...params, limit, offset).all()\n\n const totalPages = Math.ceil(totalCount / limit)\n\n return c.html(renderFAQList({\n faqs: faqs || [],\n totalCount,\n currentPage,\n totalPages,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n } catch (error) {\n console.error('Error fetching FAQs:', error)\n const user = c.get('user')\n return c.html(renderFAQList({\n faqs: [],\n totalCount: 0,\n currentPage: 1,\n totalPages: 1,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to load FAQs',\n messageType: 'error'\n }))\n }\n})\n\nadminFAQRoutes.get('/new', async (c) => {\n const user = c.get('user')\n return c.html(renderFAQForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n})\n\nadminFAQRoutes.post('/', async (c) => {\n try {\n const formData = await c.req.formData()\n const data = Object.fromEntries(formData.entries())\n \n const validatedData = faqSchema.parse(data)\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderFAQForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare(`\n INSERT INTO faqs (question, answer, category, tags, isPublished, sortOrder)\n VALUES (?, ?, ?, ?, ?, ?)\n RETURNING *\n `).bind(\n validatedData.question,\n validatedData.answer,\n validatedData.category || null,\n validatedData.tags || null,\n validatedData.isPublished ? 1 : 0,\n validatedData.sortOrder\n ).all()\n\n if (results && results.length > 0) {\n return c.redirect('/admin/faq?message=FAQ created successfully')\n } else {\n return c.html(renderFAQForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to create FAQ',\n messageType: 'error'\n }))\n }\n } catch (error) {\n console.error('Error creating FAQ:', error)\n const user = c.get('user')\n \n if (error instanceof z.ZodError) {\n const errors: Record<string, string[]> = {}\n error.errors.forEach(err => {\n const field = err.path[0] as string\n if (!errors[field]) errors[field] = []\n errors[field].push(err.message)\n })\n \n return c.html(renderFAQForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n errors,\n message: 'Please correct the errors below',\n messageType: 'error'\n }))\n }\n\n return c.html(renderFAQForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to create FAQ',\n messageType: 'error'\n }))\n }\n})\n\nadminFAQRoutes.get('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderFAQForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare('SELECT * FROM faqs WHERE id = ?').bind(id).all()\n\n if (!results || results.length === 0) {\n return c.redirect('/admin/faq?message=FAQ not found&type=error')\n }\n\n const faq = results[0] as any\n \n return c.html(renderFAQForm({\n faq: {\n id: faq.id,\n question: faq.question,\n answer: faq.answer,\n category: faq.category,\n tags: faq.tags,\n isPublished: Boolean(faq.isPublished),\n sortOrder: faq.sortOrder\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n } catch (error) {\n console.error('Error fetching FAQ:', error)\n const user = c.get('user')\n return c.html(renderFAQForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to load FAQ',\n messageType: 'error'\n }))\n }\n})\n\nadminFAQRoutes.put('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const formData = await c.req.formData()\n const data = Object.fromEntries(formData.entries())\n \n const validatedData = faqSchema.parse(data)\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderFAQForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare(`\n UPDATE faqs \n SET question = ?, answer = ?, category = ?, tags = ?, isPublished = ?, sortOrder = ?\n WHERE id = ?\n RETURNING *\n `).bind(\n validatedData.question,\n validatedData.answer,\n validatedData.category || null,\n validatedData.tags || null,\n validatedData.isPublished ? 1 : 0,\n validatedData.sortOrder,\n id\n ).all()\n\n if (results && results.length > 0) {\n return c.redirect('/admin/faq?message=FAQ updated successfully')\n } else {\n return c.html(renderFAQForm({\n faq: {\n id,\n question: validatedData.question,\n answer: validatedData.answer,\n category: validatedData.category,\n tags: validatedData.tags,\n isPublished: validatedData.isPublished,\n sortOrder: validatedData.sortOrder\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'FAQ not found',\n messageType: 'error'\n }))\n }\n } catch (error) {\n console.error('Error updating FAQ:', error)\n const user = c.get('user')\n const id = parseInt(c.req.param('id'))\n \n if (error instanceof z.ZodError) {\n const errors: Record<string, string[]> = {}\n error.errors.forEach(err => {\n const field = err.path[0] as string\n if (!errors[field]) errors[field] = []\n errors[field].push(err.message)\n })\n \n return c.html(renderFAQForm({\n faq: {\n id,\n question: '',\n answer: '',\n category: '',\n tags: '',\n isPublished: true,\n sortOrder: 0\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n errors,\n message: 'Please correct the errors below',\n messageType: 'error'\n }))\n }\n\n return c.html(renderFAQForm({\n faq: {\n id,\n question: '',\n answer: '',\n category: '',\n tags: '',\n isPublished: true,\n sortOrder: 0\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to update FAQ',\n messageType: 'error'\n }))\n }\n})\n\nadminFAQRoutes.delete('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.json({ error: 'Database not available' }, 500)\n }\n\n const { changes } = await db.prepare('DELETE FROM faqs WHERE id = ?').bind(id).run()\n\n if (changes === 0) {\n return c.json({ error: 'FAQ not found' }, 404)\n }\n\n return c.redirect('/admin/faq?message=FAQ deleted successfully')\n } catch (error) {\n console.error('Error deleting FAQ:', error)\n return c.json({ error: 'Failed to delete FAQ' }, 500)\n }\n})\n\nexport default adminFAQRoutes","import { renderAdminLayout, AdminLayoutData } from '../layouts/admin-layout-v2.template'\nimport { renderAlert } from '../alert.template'\n\ninterface Testimonial {\n id?: number\n authorName: string\n authorTitle?: string\n authorCompany?: string\n testimonialText: string\n rating?: number\n isPublished: boolean\n sortOrder: number\n}\n\ninterface TestimonialsFormData {\n testimonial?: Testimonial\n isEdit: boolean\n errors?: Record<string, string[]>\n user?: { name: string; email: string; role: string }\n message?: string\n messageType?: 'success' | 'error' | 'warning' | 'info'\n}\n\nexport function renderTestimonialsForm(data: TestimonialsFormData): string {\n const { testimonial, isEdit, errors, message, messageType } = data\n const pageTitle = isEdit ? 'Edit Testimonial' : 'New Testimonial'\n\n const pageContent = `\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6 space-y-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl font-semibold text-white\">${pageTitle}</h1>\n <p class=\"mt-2 text-sm text-gray-300\">\n ${isEdit ? 'Update the testimonial details below' : 'Create a new customer testimonial'}\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none\">\n <a href=\"/admin/testimonials\"\n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-white/10 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-white/20 transition-all\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 19l-7-7m0 0l7-7m-7 7h18\" />\n </svg>\n Back to List\n </a>\n </div>\n </div>\n\n ${message ? renderAlert({ type: messageType || 'info', message, dismissible: true }) : ''}\n\n <!-- Form -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl\">\n <form ${isEdit ? `hx-put=\"/admin/testimonials/${testimonial?.id}\"` : 'hx-post=\"/admin/testimonials\"'}\n hx-target=\"body\"\n hx-swap=\"outerHTML\"\n class=\"space-y-6 p-6\">\n\n <!-- Author Information Section -->\n <div>\n <h2 class=\"text-lg font-medium text-white mb-4\">Author Information</h2>\n\n <!-- Author Name -->\n <div class=\"mb-4\">\n <label for=\"authorName\" class=\"block text-sm font-medium text-white\">\n Author Name <span class=\"text-red-400\">*</span>\n </label>\n <div class=\"mt-1\">\n <input type=\"text\"\n name=\"authorName\"\n id=\"authorName\"\n value=\"${testimonial?.authorName || ''}\"\n required\n maxlength=\"100\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\"\n placeholder=\"John Doe\">\n </div>\n ${errors?.authorName ? `\n <div class=\"mt-1\">\n ${errors.authorName.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <!-- Author Title -->\n <div>\n <label for=\"authorTitle\" class=\"block text-sm font-medium text-white\">Title/Position</label>\n <div class=\"mt-1\">\n <input type=\"text\"\n name=\"authorTitle\"\n id=\"authorTitle\"\n value=\"${testimonial?.authorTitle || ''}\"\n maxlength=\"100\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\"\n placeholder=\"CEO\">\n </div>\n ${errors?.authorTitle ? `\n <div class=\"mt-1\">\n ${errors.authorTitle.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Author Company -->\n <div>\n <label for=\"authorCompany\" class=\"block text-sm font-medium text-white\">Company</label>\n <div class=\"mt-1\">\n <input type=\"text\"\n name=\"authorCompany\"\n id=\"authorCompany\"\n value=\"${testimonial?.authorCompany || ''}\"\n maxlength=\"100\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\"\n placeholder=\"Acme Corp\">\n </div>\n ${errors?.authorCompany ? `\n <div class=\"mt-1\">\n ${errors.authorCompany.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n </div>\n\n <!-- Testimonial Content Section -->\n <div>\n <h2 class=\"text-lg font-medium text-white mb-4\">Testimonial</h2>\n\n <!-- Testimonial Text -->\n <div class=\"mb-4\">\n <label for=\"testimonialText\" class=\"block text-sm font-medium text-white\">\n Testimonial <span class=\"text-red-400\">*</span>\n </label>\n <div class=\"mt-1\">\n <textarea name=\"testimonialText\"\n id=\"testimonialText\"\n rows=\"6\"\n required\n maxlength=\"1000\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-xl px-3 py-2 text-white placeholder-gray-300 focus:border-blue-400 focus:outline-none transition-colors w-full\"\n placeholder=\"Enter the customer's testimonial...\">${testimonial?.testimonialText || ''}</textarea>\n <p class=\"mt-1 text-sm text-gray-300\">\n <span id=\"testimonial-count\">0</span>/1000 characters\n </p>\n </div>\n ${errors?.testimonialText ? `\n <div class=\"mt-1\">\n ${errors.testimonialText.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Rating -->\n <div>\n <label for=\"rating\" class=\"block text-sm font-medium text-white\">Rating (Optional)</label>\n <div class=\"mt-1\">\n <select name=\"rating\"\n id=\"rating\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\">\n <option value=\"\">No rating</option>\n <option value=\"5\" ${testimonial?.rating === 5 ? 'selected' : ''}>⭐⭐⭐⭐⭐ (5 stars)</option>\n <option value=\"4\" ${testimonial?.rating === 4 ? 'selected' : ''}>⭐⭐⭐⭐ (4 stars)</option>\n <option value=\"3\" ${testimonial?.rating === 3 ? 'selected' : ''}>⭐⭐⭐ (3 stars)</option>\n <option value=\"2\" ${testimonial?.rating === 2 ? 'selected' : ''}>⭐⭐ (2 stars)</option>\n <option value=\"1\" ${testimonial?.rating === 1 ? 'selected' : ''}>⭐ (1 star)</option>\n </select>\n </div>\n ${errors?.rating ? `\n <div class=\"mt-1\">\n ${errors.rating.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n\n <!-- Status and Sort Order Row -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <!-- Published Status -->\n <div>\n <label class=\"block text-sm font-medium text-white\">Status</label>\n <div class=\"mt-2 space-y-2\">\n <div class=\"flex items-center\">\n <input id=\"published\"\n name=\"isPublished\"\n type=\"radio\"\n value=\"true\"\n ${!testimonial || testimonial.isPublished ? 'checked' : ''}\n class=\"h-4 w-4 text-blue-600 focus:ring-blue-600 border-gray-600 bg-gray-700\">\n <label for=\"published\" class=\"ml-2 block text-sm text-white\">\n Published <span class=\"text-gray-300\">(visible to users)</span>\n </label>\n </div>\n <div class=\"flex items-center\">\n <input id=\"draft\"\n name=\"isPublished\"\n type=\"radio\"\n value=\"false\"\n ${testimonial && !testimonial.isPublished ? 'checked' : ''}\n class=\"h-4 w-4 text-blue-600 focus:ring-blue-600 border-gray-600 bg-gray-700\">\n <label for=\"draft\" class=\"ml-2 block text-sm text-white\">\n Draft <span class=\"text-gray-300\">(not visible to users)</span>\n </label>\n </div>\n </div>\n </div>\n\n <!-- Sort Order -->\n <div>\n <label for=\"sortOrder\" class=\"block text-sm font-medium text-white\">Sort Order</label>\n <div class=\"mt-1\">\n <input type=\"number\"\n name=\"sortOrder\"\n id=\"sortOrder\"\n value=\"${testimonial?.sortOrder || 0}\"\n min=\"0\"\n step=\"1\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6\">\n <p class=\"mt-1 text-sm text-gray-300\">Lower numbers appear first (0 = highest priority)</p>\n </div>\n ${errors?.sortOrder ? `\n <div class=\"mt-1\">\n ${errors.sortOrder.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"flex items-center justify-end space-x-3 pt-6 border-t border-white/20\">\n <a href=\"/admin/testimonials\"\n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-white/10 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-white/20 transition-all\">\n Cancel\n </a>\n <button type=\"submit\"\n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-blue-500/80 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-blue-500 transition-all\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n ${isEdit ? 'Update Testimonial' : 'Create Testimonial'}\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <script>\n // Character count for testimonial\n const testimonialTextarea = document.getElementById('testimonialText');\n const testimonialCount = document.getElementById('testimonial-count');\n\n function updateTestimonialCount() {\n testimonialCount.textContent = testimonialTextarea.value.length;\n }\n\n testimonialTextarea.addEventListener('input', updateTestimonialCount);\n updateTestimonialCount(); // Initial count\n </script>\n `\n\n const layoutData: AdminLayoutData = {\n title: `${pageTitle} - Admin`,\n pageTitle,\n currentPath: isEdit ? `/admin/testimonials/${testimonial?.id}` : '/admin/testimonials/new',\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayout(layoutData)\n}\n\nfunction escapeHtml(unsafe: string): string {\n return unsafe\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\")\n}\n","import { Hono } from 'hono'\nimport { z } from 'zod'\nimport { renderTestimonialsList } from '../templates/pages/admin-testimonials-list.template'\nimport { renderTestimonialsForm } from '../templates/pages/admin-testimonials-form.template'\n\ntype Bindings = {\n DB: D1Database\n KV: KVNamespace\n}\n\ntype Variables = {\n user?: {\n userId: string\n email: string\n role: string\n exp: number\n iat: number\n }\n}\n\nconst testimonialSchema = z.object({\n authorName: z.string().min(1, 'Author name is required').max(100, 'Author name must be under 100 characters'),\n authorTitle: z.string().optional(),\n authorCompany: z.string().optional(),\n testimonialText: z.string().min(1, 'Testimonial is required').max(1000, 'Testimonial must be under 1000 characters'),\n rating: z.string().transform(val => val ? parseInt(val, 10) : undefined).pipe(z.number().min(1).max(5).optional()),\n isPublished: z.string().transform(val => val === 'true'),\n sortOrder: z.string().transform(val => parseInt(val, 10)).pipe(z.number().min(0))\n})\n\nconst adminTestimonialsRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\nadminTestimonialsRoutes.get('/', async (c) => {\n try {\n const user = c.get('user')\n const { published, minRating, search, page = '1' } = c.req.query()\n const currentPage = parseInt(page, 10) || 1\n const limit = 20\n const offset = (currentPage - 1) * limit\n\n const db = (c as any).env?.DB\n if (!db) {\n return c.html(renderTestimonialsList({\n testimonials: [],\n totalCount: 0,\n currentPage: 1,\n totalPages: 1,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n let whereClause = 'WHERE 1=1'\n const params: any[] = []\n\n if (published !== undefined) {\n whereClause += ' AND isPublished = ?'\n params.push(published === 'true' ? 1 : 0)\n }\n\n if (minRating) {\n whereClause += ' AND rating >= ?'\n params.push(parseInt(minRating, 10))\n }\n\n if (search) {\n whereClause += ' AND (author_name LIKE ? OR testimonial_text LIKE ? OR author_company LIKE ?)'\n const searchTerm = `%${search}%`\n params.push(searchTerm, searchTerm, searchTerm)\n }\n\n const countQuery = `SELECT COUNT(*) as count FROM testimonials ${whereClause}`\n const { results: countResults } = await db.prepare(countQuery).bind(...params).all()\n const totalCount = countResults?.[0]?.count || 0\n\n const dataQuery = `\n SELECT * FROM testimonials\n ${whereClause}\n ORDER BY sortOrder ASC, created_at DESC\n LIMIT ? OFFSET ?\n `\n const { results: testimonials } = await db.prepare(dataQuery).bind(...params, limit, offset).all()\n\n const totalPages = Math.ceil(totalCount / limit)\n\n return c.html(renderTestimonialsList({\n testimonials: testimonials || [],\n totalCount,\n currentPage,\n totalPages,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n } catch (error) {\n console.error('Error fetching testimonials:', error)\n const user = c.get('user')\n return c.html(renderTestimonialsList({\n testimonials: [],\n totalCount: 0,\n currentPage: 1,\n totalPages: 1,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to load testimonials',\n messageType: 'error'\n }))\n }\n})\n\nadminTestimonialsRoutes.get('/new', async (c) => {\n const user = c.get('user')\n return c.html(renderTestimonialsForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n})\n\nadminTestimonialsRoutes.post('/', async (c) => {\n try {\n const formData = await c.req.formData()\n const data = Object.fromEntries(formData.entries())\n\n const validatedData = testimonialSchema.parse(data)\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderTestimonialsForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare(`\n INSERT INTO testimonials (author_name, author_title, author_company, testimonial_text, rating, isPublished, sortOrder)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n RETURNING *\n `).bind(\n validatedData.authorName,\n validatedData.authorTitle || null,\n validatedData.authorCompany || null,\n validatedData.testimonialText,\n validatedData.rating || null,\n validatedData.isPublished ? 1 : 0,\n validatedData.sortOrder\n ).all()\n\n if (results && results.length > 0) {\n return c.redirect('/admin/testimonials?message=Testimonial created successfully')\n } else {\n return c.html(renderTestimonialsForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to create testimonial',\n messageType: 'error'\n }))\n }\n } catch (error) {\n console.error('Error creating testimonial:', error)\n const user = c.get('user')\n\n if (error instanceof z.ZodError) {\n const errors: Record<string, string[]> = {}\n error.errors.forEach(err => {\n const field = err.path[0] as string\n if (!errors[field]) errors[field] = []\n errors[field].push(err.message)\n })\n\n return c.html(renderTestimonialsForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n errors,\n message: 'Please correct the errors below',\n messageType: 'error'\n }))\n }\n\n return c.html(renderTestimonialsForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to create testimonial',\n messageType: 'error'\n }))\n }\n})\n\nadminTestimonialsRoutes.get('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderTestimonialsForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare('SELECT * FROM testimonials WHERE id = ?').bind(id).all()\n\n if (!results || results.length === 0) {\n return c.redirect('/admin/testimonials?message=Testimonial not found&type=error')\n }\n\n const testimonial = results[0] as any\n\n return c.html(renderTestimonialsForm({\n testimonial: {\n id: testimonial.id,\n authorName: testimonial.author_name,\n authorTitle: testimonial.author_title,\n authorCompany: testimonial.author_company,\n testimonialText: testimonial.testimonial_text,\n rating: testimonial.rating,\n isPublished: Boolean(testimonial.isPublished),\n sortOrder: testimonial.sortOrder\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n } catch (error) {\n console.error('Error fetching testimonial:', error)\n const user = c.get('user')\n return c.html(renderTestimonialsForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to load testimonial',\n messageType: 'error'\n }))\n }\n})\n\nadminTestimonialsRoutes.put('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const formData = await c.req.formData()\n const data = Object.fromEntries(formData.entries())\n\n const validatedData = testimonialSchema.parse(data)\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderTestimonialsForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare(`\n UPDATE testimonials\n SET author_name = ?, author_title = ?, author_company = ?, testimonial_text = ?, rating = ?, isPublished = ?, sortOrder = ?\n WHERE id = ?\n RETURNING *\n `).bind(\n validatedData.authorName,\n validatedData.authorTitle || null,\n validatedData.authorCompany || null,\n validatedData.testimonialText,\n validatedData.rating || null,\n validatedData.isPublished ? 1 : 0,\n validatedData.sortOrder,\n id\n ).all()\n\n if (results && results.length > 0) {\n return c.redirect('/admin/testimonials?message=Testimonial updated successfully')\n } else {\n return c.html(renderTestimonialsForm({\n testimonial: {\n id,\n authorName: validatedData.authorName,\n authorTitle: validatedData.authorTitle,\n authorCompany: validatedData.authorCompany,\n testimonialText: validatedData.testimonialText,\n rating: validatedData.rating,\n isPublished: validatedData.isPublished,\n sortOrder: validatedData.sortOrder\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Testimonial not found',\n messageType: 'error'\n }))\n }\n } catch (error) {\n console.error('Error updating testimonial:', error)\n const user = c.get('user')\n const id = parseInt(c.req.param('id'))\n\n if (error instanceof z.ZodError) {\n const errors: Record<string, string[]> = {}\n error.errors.forEach(err => {\n const field = err.path[0] as string\n if (!errors[field]) errors[field] = []\n errors[field].push(err.message)\n })\n\n return c.html(renderTestimonialsForm({\n testimonial: {\n id,\n authorName: '',\n authorTitle: '',\n authorCompany: '',\n testimonialText: '',\n rating: undefined,\n isPublished: true,\n sortOrder: 0\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n errors,\n message: 'Please correct the errors below',\n messageType: 'error'\n }))\n }\n\n return c.html(renderTestimonialsForm({\n testimonial: {\n id,\n authorName: '',\n authorTitle: '',\n authorCompany: '',\n testimonialText: '',\n rating: undefined,\n isPublished: true,\n sortOrder: 0\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to update testimonial',\n messageType: 'error'\n }))\n }\n})\n\nadminTestimonialsRoutes.delete('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.json({ error: 'Database not available' }, 500)\n }\n\n const { changes } = await db.prepare('DELETE FROM testimonials WHERE id = ?').bind(id).run()\n\n if (changes === 0) {\n return c.json({ error: 'Testimonial not found' }, 404)\n }\n\n return c.redirect('/admin/testimonials?message=Testimonial deleted successfully')\n } catch (error) {\n console.error('Error deleting testimonial:', error)\n return c.json({ error: 'Failed to delete testimonial' }, 500)\n }\n})\n\nexport default adminTestimonialsRoutes\n","import { renderAdminLayout, AdminLayoutData } from '../layouts/admin-layout-v2.template'\nimport { renderAlert } from '../alert.template'\n\ninterface CodeExample {\n id?: number\n title: string\n description?: string\n code: string\n language: string\n category?: string\n tags?: string\n isPublished: boolean\n sortOrder: number\n}\n\ninterface CodeExamplesFormData {\n codeExample?: CodeExample\n isEdit: boolean\n errors?: Record<string, string[]>\n user?: { name: string; email: string; role: string }\n message?: string\n messageType?: 'success' | 'error' | 'warning' | 'info'\n}\n\nexport function renderCodeExamplesForm(data: CodeExamplesFormData): string {\n const { codeExample, isEdit, errors, message, messageType } = data\n const pageTitle = isEdit ? 'Edit Code Example' : 'New Code Example'\n\n const pageContent = `\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6 space-y-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6\">\n <div>\n <h1 class=\"text-2xl font-semibold text-white\">${pageTitle}</h1>\n <p class=\"mt-2 text-sm text-gray-300\">\n ${isEdit ? 'Update the code example details below' : 'Create a new code snippet or example'}\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 sm:ml-16 sm:flex-none\">\n <a href=\"/admin/code-examples\"\n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-white/10 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-white/20 transition-all\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 19l-7-7m0 0l7-7m-7 7h18\" />\n </svg>\n Back to List\n </a>\n </div>\n </div>\n\n ${message ? renderAlert({ type: messageType || 'info', message, dismissible: true }) : ''}\n\n <!-- Form -->\n <div class=\"backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl\">\n <form ${isEdit ? `hx-put=\"/admin/code-examples/${codeExample?.id}\"` : 'hx-post=\"/admin/code-examples\"'}\n hx-target=\"body\"\n hx-swap=\"outerHTML\"\n class=\"space-y-6 p-6\">\n\n <!-- Basic Information Section -->\n <div>\n <h2 class=\"text-lg font-medium text-white mb-4\">Basic Information</h2>\n\n <!-- Title -->\n <div class=\"mb-4\">\n <label for=\"title\" class=\"block text-sm font-medium text-white\">\n Title <span class=\"text-red-400\">*</span>\n </label>\n <div class=\"mt-1\">\n <input type=\"text\"\n name=\"title\"\n id=\"title\"\n value=\"${codeExample?.title || ''}\"\n required\n maxlength=\"200\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-purple-600 sm:text-sm sm:leading-6\"\n placeholder=\"e.g., React useState Hook Example\">\n </div>\n ${errors?.title ? `\n <div class=\"mt-1\">\n ${errors.title.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Description -->\n <div class=\"mb-4\">\n <label for=\"description\" class=\"block text-sm font-medium text-white\">Description</label>\n <div class=\"mt-1\">\n <textarea name=\"description\"\n id=\"description\"\n rows=\"3\"\n maxlength=\"500\"\n class=\"backdrop-blur-sm bg-white/10 border border-white/20 rounded-xl px-3 py-2 text-white placeholder-gray-300 focus:border-purple-400 focus:outline-none transition-colors w-full\"\n placeholder=\"Briefly describe what this code example demonstrates...\">${codeExample?.description || ''}</textarea>\n <p class=\"mt-1 text-sm text-gray-300\">\n <span id=\"description-count\">0</span>/500 characters\n </p>\n </div>\n ${errors?.description ? `\n <div class=\"mt-1\">\n ${errors.description.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n <!-- Language -->\n <div>\n <label for=\"language\" class=\"block text-sm font-medium text-white\">\n Language <span class=\"text-red-400\">*</span>\n </label>\n <div class=\"mt-1\">\n <select name=\"language\"\n id=\"language\"\n required\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 focus:ring-2 focus:ring-inset focus:ring-purple-600 sm:text-sm sm:leading-6\">\n <option value=\"\">Select language...</option>\n <option value=\"javascript\" ${codeExample?.language === 'javascript' ? 'selected' : ''}>JavaScript</option>\n <option value=\"typescript\" ${codeExample?.language === 'typescript' ? 'selected' : ''}>TypeScript</option>\n <option value=\"python\" ${codeExample?.language === 'python' ? 'selected' : ''}>Python</option>\n <option value=\"go\" ${codeExample?.language === 'go' ? 'selected' : ''}>Go</option>\n <option value=\"rust\" ${codeExample?.language === 'rust' ? 'selected' : ''}>Rust</option>\n <option value=\"java\" ${codeExample?.language === 'java' ? 'selected' : ''}>Java</option>\n <option value=\"php\" ${codeExample?.language === 'php' ? 'selected' : ''}>PHP</option>\n <option value=\"ruby\" ${codeExample?.language === 'ruby' ? 'selected' : ''}>Ruby</option>\n <option value=\"sql\" ${codeExample?.language === 'sql' ? 'selected' : ''}>SQL</option>\n </select>\n </div>\n ${errors?.language ? `\n <div class=\"mt-1\">\n ${errors.language.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Category -->\n <div>\n <label for=\"category\" class=\"block text-sm font-medium text-white\">Category</label>\n <div class=\"mt-1\">\n <input type=\"text\"\n name=\"category\"\n id=\"category\"\n value=\"${codeExample?.category || ''}\"\n maxlength=\"50\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-purple-600 sm:text-sm sm:leading-6\"\n placeholder=\"e.g., frontend, backend\">\n </div>\n ${errors?.category ? `\n <div class=\"mt-1\">\n ${errors.category.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n\n <!-- Tags -->\n <div>\n <label for=\"tags\" class=\"block text-sm font-medium text-white\">Tags</label>\n <div class=\"mt-1\">\n <input type=\"text\"\n name=\"tags\"\n id=\"tags\"\n value=\"${codeExample?.tags || ''}\"\n maxlength=\"200\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-purple-600 sm:text-sm sm:leading-6\"\n placeholder=\"e.g., react, hooks, state\">\n <p class=\"mt-1 text-sm text-gray-300\">Comma-separated tags</p>\n </div>\n ${errors?.tags ? `\n <div class=\"mt-1\">\n ${errors.tags.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n </div>\n\n <!-- Code Section -->\n <div>\n <h2 class=\"text-lg font-medium text-white mb-4\">Code</h2>\n\n <!-- Code Editor -->\n <div class=\"mb-4\">\n <label for=\"code\" class=\"block text-sm font-medium text-white\">\n Code <span class=\"text-red-400\">*</span>\n </label>\n <div class=\"mt-1\">\n <textarea name=\"code\"\n id=\"code\"\n rows=\"20\"\n required\n class=\"backdrop-blur-sm bg-gray-800/90 border border-white/20 rounded-xl px-3 py-2 text-white placeholder-gray-300 focus:border-purple-400 focus:outline-none transition-colors w-full font-mono text-sm\"\n placeholder=\"Paste your code here...\">${codeExample?.code || ''}</textarea>\n <p class=\"mt-1 text-sm text-gray-300\">\n <span id=\"code-count\">0</span> characters\n </p>\n </div>\n ${errors?.code ? `\n <div class=\"mt-1\">\n ${errors.code.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n\n <!-- Status and Sort Order Row -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <!-- Published Status -->\n <div>\n <label class=\"block text-sm font-medium text-white\">Status</label>\n <div class=\"mt-2 space-y-2\">\n <div class=\"flex items-center\">\n <input id=\"published\"\n name=\"isPublished\"\n type=\"radio\"\n value=\"true\"\n ${!codeExample || codeExample.isPublished ? 'checked' : ''}\n class=\"h-4 w-4 text-purple-600 focus:ring-purple-600 border-gray-600 bg-gray-700\">\n <label for=\"published\" class=\"ml-2 block text-sm text-white\">\n Published <span class=\"text-gray-300\">(visible to users)</span>\n </label>\n </div>\n <div class=\"flex items-center\">\n <input id=\"draft\"\n name=\"isPublished\"\n type=\"radio\"\n value=\"false\"\n ${codeExample && !codeExample.isPublished ? 'checked' : ''}\n class=\"h-4 w-4 text-purple-600 focus:ring-purple-600 border-gray-600 bg-gray-700\">\n <label for=\"draft\" class=\"ml-2 block text-sm text-white\">\n Draft <span class=\"text-gray-300\">(not visible to users)</span>\n </label>\n </div>\n </div>\n </div>\n\n <!-- Sort Order -->\n <div>\n <label for=\"sortOrder\" class=\"block text-sm font-medium text-white\">Sort Order</label>\n <div class=\"mt-1\">\n <input type=\"number\"\n name=\"sortOrder\"\n id=\"sortOrder\"\n value=\"${codeExample?.sortOrder || 0}\"\n min=\"0\"\n step=\"1\"\n class=\"block w-full rounded-md border-0 bg-gray-700 py-1.5 text-gray-100 shadow-sm ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-purple-600 sm:text-sm sm:leading-6\">\n <p class=\"mt-1 text-sm text-gray-300\">Lower numbers appear first (0 = highest priority)</p>\n </div>\n ${errors?.sortOrder ? `\n <div class=\"mt-1\">\n ${errors.sortOrder.map(error => `\n <p class=\"text-sm text-red-400\">${escapeHtml(error)}</p>\n `).join('')}\n </div>\n ` : ''}\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"flex items-center justify-end space-x-3 pt-6 border-t border-white/20\">\n <a href=\"/admin/code-examples\"\n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-white/10 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-white/20 transition-all\">\n Cancel\n </a>\n <button type=\"submit\"\n class=\"inline-flex items-center justify-center rounded-xl backdrop-blur-sm bg-purple-500/80 px-4 py-2 text-sm font-semibold text-white border border-white/20 hover:bg-purple-500 transition-all\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n ${isEdit ? 'Update Code Example' : 'Create Code Example'}\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <script>\n // Character count for description\n const descriptionTextarea = document.getElementById('description');\n const descriptionCount = document.getElementById('description-count');\n\n function updateDescriptionCount() {\n descriptionCount.textContent = descriptionTextarea.value.length;\n }\n\n descriptionTextarea.addEventListener('input', updateDescriptionCount);\n updateDescriptionCount(); // Initial count\n\n // Character count for code\n const codeTextarea = document.getElementById('code');\n const codeCount = document.getElementById('code-count');\n\n function updateCodeCount() {\n codeCount.textContent = codeTextarea.value.length;\n }\n\n codeTextarea.addEventListener('input', updateCodeCount);\n updateCodeCount(); // Initial count\n </script>\n `\n\n const layoutData: AdminLayoutData = {\n title: `${pageTitle} - Admin`,\n pageTitle,\n currentPath: isEdit ? `/admin/code-examples/${codeExample?.id}` : '/admin/code-examples/new',\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayout(layoutData)\n}\n\nfunction escapeHtml(unsafe: string): string {\n return unsafe\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\")\n}\n","import { Hono } from 'hono'\nimport { z } from 'zod'\nimport { renderCodeExamplesList } from '../templates/pages/admin-code-examples-list.template'\nimport { renderCodeExamplesForm } from '../templates/pages/admin-code-examples-form.template'\n\ntype Bindings = {\n DB: D1Database\n KV: KVNamespace\n}\n\ntype Variables = {\n user?: {\n userId: string\n email: string\n role: string\n exp: number\n iat: number\n }\n}\n\nconst codeExampleSchema = z.object({\n title: z.string().min(1, 'Title is required').max(200, 'Title must be under 200 characters'),\n description: z.string().max(500, 'Description must be under 500 characters').optional(),\n code: z.string().min(1, 'Code is required'),\n language: z.string().min(1, 'Language is required'),\n category: z.string().max(50, 'Category must be under 50 characters').optional(),\n tags: z.string().max(200, 'Tags must be under 200 characters').optional(),\n isPublished: z.string().transform(val => val === 'true'),\n sortOrder: z.string().transform(val => parseInt(val, 10)).pipe(z.number().min(0))\n})\n\nconst adminCodeExamplesRoutes = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\nadminCodeExamplesRoutes.get('/', async (c) => {\n try {\n const user = c.get('user')\n const { published, language, search, page = '1' } = c.req.query()\n const currentPage = parseInt(page, 10) || 1\n const limit = 20\n const offset = (currentPage - 1) * limit\n\n const db = (c as any).env?.DB\n if (!db) {\n return c.html(renderCodeExamplesList({\n codeExamples: [],\n totalCount: 0,\n currentPage: 1,\n totalPages: 1,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n let whereClause = 'WHERE 1=1'\n const params: any[] = []\n\n if (published !== undefined) {\n whereClause += ' AND isPublished = ?'\n params.push(published === 'true' ? 1 : 0)\n }\n\n if (language) {\n whereClause += ' AND language = ?'\n params.push(language)\n }\n\n if (search) {\n whereClause += ' AND (title LIKE ? OR description LIKE ? OR code LIKE ? OR tags LIKE ?)'\n const searchTerm = `%${search}%`\n params.push(searchTerm, searchTerm, searchTerm, searchTerm)\n }\n\n const countQuery = `SELECT COUNT(*) as count FROM code_examples ${whereClause}`\n const { results: countResults } = await db.prepare(countQuery).bind(...params).all()\n const totalCount = countResults?.[0]?.count || 0\n\n const dataQuery = `\n SELECT * FROM code_examples\n ${whereClause}\n ORDER BY sortOrder ASC, created_at DESC\n LIMIT ? OFFSET ?\n `\n const { results: codeExamples } = await db.prepare(dataQuery).bind(...params, limit, offset).all()\n\n const totalPages = Math.ceil(totalCount / limit)\n\n return c.html(renderCodeExamplesList({\n codeExamples: codeExamples || [],\n totalCount,\n currentPage,\n totalPages,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n } catch (error) {\n console.error('Error fetching code examples:', error)\n const user = c.get('user')\n return c.html(renderCodeExamplesList({\n codeExamples: [],\n totalCount: 0,\n currentPage: 1,\n totalPages: 1,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to load code examples',\n messageType: 'error'\n }))\n }\n})\n\nadminCodeExamplesRoutes.get('/new', async (c) => {\n const user = c.get('user')\n return c.html(renderCodeExamplesForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n})\n\nadminCodeExamplesRoutes.post('/', async (c) => {\n try {\n const formData = await c.req.formData()\n const data = Object.fromEntries(formData.entries())\n\n const validatedData = codeExampleSchema.parse(data)\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderCodeExamplesForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare(`\n INSERT INTO code_examples (title, description, code, language, category, tags, isPublished, sortOrder)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n RETURNING *\n `).bind(\n validatedData.title,\n validatedData.description || null,\n validatedData.code,\n validatedData.language,\n validatedData.category || null,\n validatedData.tags || null,\n validatedData.isPublished ? 1 : 0,\n validatedData.sortOrder\n ).all()\n\n if (results && results.length > 0) {\n return c.redirect('/admin/code-examples?message=Code example created successfully')\n } else {\n return c.html(renderCodeExamplesForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to create code example',\n messageType: 'error'\n }))\n }\n } catch (error) {\n console.error('Error creating code example:', error)\n const user = c.get('user')\n\n if (error instanceof z.ZodError) {\n const errors: Record<string, string[]> = {}\n error.errors.forEach(err => {\n const field = err.path[0] as string\n if (!errors[field]) errors[field] = []\n errors[field].push(err.message)\n })\n\n return c.html(renderCodeExamplesForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n errors,\n message: 'Please correct the errors below',\n messageType: 'error'\n }))\n }\n\n return c.html(renderCodeExamplesForm({\n isEdit: false,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to create code example',\n messageType: 'error'\n }))\n }\n})\n\nadminCodeExamplesRoutes.get('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderCodeExamplesForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare('SELECT * FROM code_examples WHERE id = ?').bind(id).all()\n\n if (!results || results.length === 0) {\n return c.redirect('/admin/code-examples?message=Code example not found&type=error')\n }\n\n const example = results[0] as any\n\n return c.html(renderCodeExamplesForm({\n codeExample: {\n id: example.id,\n title: example.title,\n description: example.description,\n code: example.code,\n language: example.language,\n category: example.category,\n tags: example.tags,\n isPublished: Boolean(example.isPublished),\n sortOrder: example.sortOrder\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined\n }))\n } catch (error) {\n console.error('Error fetching code example:', error)\n const user = c.get('user')\n return c.html(renderCodeExamplesForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to load code example',\n messageType: 'error'\n }))\n }\n})\n\nadminCodeExamplesRoutes.put('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const formData = await c.req.formData()\n const data = Object.fromEntries(formData.entries())\n\n const validatedData = codeExampleSchema.parse(data)\n const user = c.get('user')\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.html(renderCodeExamplesForm({\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Database not available',\n messageType: 'error'\n }))\n }\n\n const { results } = await db.prepare(`\n UPDATE code_examples\n SET title = ?, description = ?, code = ?, language = ?, category = ?, tags = ?, isPublished = ?, sortOrder = ?\n WHERE id = ?\n RETURNING *\n `).bind(\n validatedData.title,\n validatedData.description || null,\n validatedData.code,\n validatedData.language,\n validatedData.category || null,\n validatedData.tags || null,\n validatedData.isPublished ? 1 : 0,\n validatedData.sortOrder,\n id\n ).all()\n\n if (results && results.length > 0) {\n return c.redirect('/admin/code-examples?message=Code example updated successfully')\n } else {\n return c.html(renderCodeExamplesForm({\n codeExample: {\n id,\n title: validatedData.title,\n description: validatedData.description,\n code: validatedData.code,\n language: validatedData.language,\n category: validatedData.category,\n tags: validatedData.tags,\n isPublished: validatedData.isPublished,\n sortOrder: validatedData.sortOrder\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Code example not found',\n messageType: 'error'\n }))\n }\n } catch (error) {\n console.error('Error updating code example:', error)\n const user = c.get('user')\n const id = parseInt(c.req.param('id'))\n\n if (error instanceof z.ZodError) {\n const errors: Record<string, string[]> = {}\n error.errors.forEach(err => {\n const field = err.path[0] as string\n if (!errors[field]) errors[field] = []\n errors[field].push(err.message)\n })\n\n return c.html(renderCodeExamplesForm({\n codeExample: {\n id,\n title: '',\n description: '',\n code: '',\n language: '',\n category: '',\n tags: '',\n isPublished: true,\n sortOrder: 0\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n errors,\n message: 'Please correct the errors below',\n messageType: 'error'\n }))\n }\n\n return c.html(renderCodeExamplesForm({\n codeExample: {\n id,\n title: '',\n description: '',\n code: '',\n language: '',\n category: '',\n tags: '',\n isPublished: true,\n sortOrder: 0\n },\n isEdit: true,\n user: user ? {\n name: user.email,\n email: user.email,\n role: user.role\n } : undefined,\n message: 'Failed to update code example',\n messageType: 'error'\n }))\n }\n})\n\nadminCodeExamplesRoutes.delete('/:id', async (c) => {\n try {\n const id = parseInt(c.req.param('id'))\n const db = (c as any).env?.DB\n\n if (!db) {\n return c.json({ error: 'Database not available' }, 500)\n }\n\n const { changes } = await db.prepare('DELETE FROM code_examples WHERE id = ?').bind(id).run()\n\n if (changes === 0) {\n return c.json({ error: 'Code example not found' }, 404)\n }\n\n return c.redirect('/admin/code-examples?message=Code example deleted successfully')\n } catch (error) {\n console.error('Error deleting code example:', error)\n return c.json({ error: 'Failed to delete code example' }, 500)\n }\n})\n\nexport default adminCodeExamplesRoutes\n","/**\n * Routes Module Exports\n *\n * Routes are being migrated incrementally from the monolith.\n * Each route is refactored to remove monolith-specific dependencies.\n */\n\n// API routes\nexport { default as apiRoutes } from './api'\nexport { default as apiContentCrudRoutes } from './api-content-crud'\nexport { default as apiMediaRoutes } from './api-media'\nexport { default as apiSystemRoutes } from './api-system'\nexport { default as adminApiRoutes } from './admin-api'\n\n// Auth routes\nexport { default as authRoutes } from './auth'\n\n// Admin UI routes\nexport { default as adminContentRoutes } from './admin-content'\nexport { userRoutes as adminUsersRoutes } from './admin-users'\nexport { adminMediaRoutes } from './admin-media'\nexport { adminPluginRoutes } from './admin-plugins'\nexport { adminLogsRoutes } from './admin-logs'\nexport { adminDesignRoutes } from './admin-design'\nexport { adminCheckboxRoutes } from './admin-checkboxes'\nexport { default as adminFAQRoutes } from './admin-faq'\nexport { default as adminTestimonialsRoutes } from './admin-testimonials'\nexport { default as adminCodeExamplesRoutes } from './admin-code-examples'\n\nexport const ROUTES_INFO = {\n message: 'Core routes available',\n available: [\n 'apiRoutes',\n 'apiContentCrudRoutes',\n 'apiMediaRoutes',\n 'apiSystemRoutes',\n 'adminApiRoutes',\n 'authRoutes',\n 'adminContentRoutes',\n 'adminUsersRoutes',\n 'adminMediaRoutes',\n 'adminPluginRoutes',\n 'adminLogsRoutes',\n 'adminDesignRoutes',\n 'adminCheckboxRoutes',\n 'adminFAQRoutes',\n 'adminTestimonialsRoutes',\n 'adminCodeExamplesRoutes'\n ],\n status: 'Core package routes ready',\n reference: 'https://github.com/sonicjs/sonicjs'\n} as const\n"]}
|