@zenith-open/zenithcms-admin 1.0.0-beta.2 → 1.0.0-beta.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/assets/{ApiExplorerPage-UJpoKRI0.js → ApiExplorerPage-85UWt1EW.js} +1 -1
  2. package/dist/assets/{ApiExplorerPage-UJpoKRI0.js.map → ApiExplorerPage-85UWt1EW.js.map} +1 -1
  3. package/dist/assets/{AuditLogPage-8xYlRl1I.js → AuditLogPage-CwULx1tr.js} +1 -1
  4. package/dist/assets/{AuditLogPage-8xYlRl1I.js.map → AuditLogPage-CwULx1tr.js.map} +1 -1
  5. package/dist/assets/{BlockBuilderPage-DcOo3Vnt.js → BlockBuilderPage-XD1IjOgx.js} +1 -1
  6. package/dist/assets/{BlockBuilderPage-DcOo3Vnt.js.map → BlockBuilderPage-XD1IjOgx.js.map} +1 -1
  7. package/dist/assets/{CollectionHooksPage-Dn_ujtlp.js → CollectionHooksPage-DIaSrKDj.js} +1 -1
  8. package/dist/assets/{CollectionHooksPage-Dn_ujtlp.js.map → CollectionHooksPage-DIaSrKDj.js.map} +1 -1
  9. package/dist/assets/{CollectionsPage-BSPHf7H2.js → CollectionsPage-CL_t5JRI.js} +1 -1
  10. package/dist/assets/{CollectionsPage-BSPHf7H2.js.map → CollectionsPage-CL_t5JRI.js.map} +1 -1
  11. package/dist/assets/{ComponentBuilderPage-CT6S12LA.js → ComponentBuilderPage-C58Rr1cu.js} +1 -1
  12. package/dist/assets/{ComponentBuilderPage-CT6S12LA.js.map → ComponentBuilderPage-C58Rr1cu.js.map} +1 -1
  13. package/dist/assets/{DashboardBuilder-Cbi9Ddiu.js → DashboardBuilder-Chjyqyb7.js} +1 -1
  14. package/dist/assets/{DashboardBuilder-Cbi9Ddiu.js.map → DashboardBuilder-Chjyqyb7.js.map} +1 -1
  15. package/dist/assets/{PluginsPage-5YRpbP-N.js → PluginsPage-DAR4Fsz-.js} +1 -1
  16. package/dist/assets/{PluginsPage-5YRpbP-N.js.map → PluginsPage-DAR4Fsz-.js.map} +1 -1
  17. package/dist/assets/{RedirectsPage-D_4jAdaI.js → RedirectsPage-DfMTJsac.js} +1 -1
  18. package/dist/assets/{RedirectsPage-D_4jAdaI.js.map → RedirectsPage-DfMTJsac.js.map} +1 -1
  19. package/dist/assets/{SchemaBuilderPage-EFA5XIAa.js → SchemaBuilderPage-BYprOkEv.js} +1 -1
  20. package/dist/assets/{SchemaBuilderPage-EFA5XIAa.js.map → SchemaBuilderPage-BYprOkEv.js.map} +1 -1
  21. package/dist/assets/{SettingsPage-BRpcMw48.js → SettingsPage-B2r_uNVc.js} +1 -1
  22. package/dist/assets/{SettingsPage-BRpcMw48.js.map → SettingsPage-B2r_uNVc.js.map} +1 -1
  23. package/dist/assets/SetupWizard-CBA43yJr.js +62 -0
  24. package/dist/assets/SetupWizard-CBA43yJr.js.map +1 -0
  25. package/dist/assets/SpatialEditor-BohlovfE.js +3 -0
  26. package/dist/assets/SpatialEditor-BohlovfE.js.map +1 -0
  27. package/dist/assets/{TemplatesPage-B-nNYv3o.js → TemplatesPage-BplB2ksb.js} +1 -1
  28. package/dist/assets/{TemplatesPage-B-nNYv3o.js.map → TemplatesPage-BplB2ksb.js.map} +1 -1
  29. package/dist/assets/{TrashPage-Ccusal1w.js → TrashPage-BIhKrs5x.js} +1 -1
  30. package/dist/assets/{TrashPage-Ccusal1w.js.map → TrashPage-BIhKrs5x.js.map} +1 -1
  31. package/dist/assets/index-Umj4hIVD.css +1 -0
  32. package/dist/assets/{index-ChcKY5Xe.js → index-yE_3fruG.js} +3 -3
  33. package/dist/assets/index-yE_3fruG.js.map +1 -0
  34. package/dist/index.html +48 -6
  35. package/dist/manifest.webmanifest +1 -0
  36. package/dist/sw.js +1 -1
  37. package/dist/sw.js.map +1 -1
  38. package/dist/{workbox-9c191d2f.js → workbox-2fbc6a65.js} +3 -3
  39. package/dist/workbox-2fbc6a65.js.map +1 -0
  40. package/package.json +4 -4
  41. package/dist/assets/SetupWizard-D57HIkrs.js +0 -62
  42. package/dist/assets/SetupWizard-D57HIkrs.js.map +0 -1
  43. package/dist/assets/SpatialEditor-CPgS7Zrd.js +0 -3
  44. package/dist/assets/SpatialEditor-CPgS7Zrd.js.map +0 -1
  45. package/dist/assets/index-ChcKY5Xe.js.map +0 -1
  46. package/dist/assets/index-CxhwdV2K.css +0 -1
  47. package/dist/workbox-9c191d2f.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{$n as t,E as n,Ht as r,J as i,Jt as a,Ln as o,Mt as s,Zt as c,cn as l,in as u,ir as d,rr as f,sn as p,vr as m,xr as h}from"./vendor-react-DQVTOTFO.js";import{a as g,o as _,s as v,t as y}from"./utils-fgvbH6CB.js";import{d as b,f as x,p as S}from"./index-ChcKY5Xe.js";var C=e(h(),1),w=m(),T={get:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`,post:`bg-sky-500/10 text-sky-400 border-sky-500/20`,put:`bg-amber-500/10 text-amber-400 border-amber-500/20`,patch:`bg-violet-500/10 text-violet-400 border-violet-500/20`,delete:`bg-red-500/10 text-red-400 border-red-500/20`};function E(){let[e,m]=(0,C.useState)(`graphql`),{theme:h}=g(),E=h===`dark`,[D,O]=(0,C.useState)(null),k=(0,C.useRef)(null),A=v(e=>e.token),[j,M]=(0,C.useState)(null),[N,P]=(0,C.useState)(!1),[F,I]=(0,C.useState)(null),[L,R]=(0,C.useState)(null),z=`/graphql`,B=`/api/docs`,V=(0,C.useCallback)(async()=>{P(!0),I(null);try{M((await _.get(`/system/openapi.json`)).data)}catch{I(`Could not load API schema. Make sure the backend server is running.`)}finally{P(!1)}},[]);(0,C.useEffect)(()=>{e===`rest`&&!j&&V()},[e,j,V]);let H=(e,t)=>{navigator.clipboard.writeText(e),O(t),setTimeout(()=>O(null),2e3)},U=()=>{k.current?.contentWindow&&A&&k.current.contentWindow.postMessage({type:`ZENITH_AUTH_TOKEN`,token:A},`*`)},W=`3.7.1`,G=`18.3.1`,K=`
1
+ import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{$n as t,E as n,Ht as r,J as i,Jt as a,Ln as o,Mt as s,Zt as c,cn as l,in as u,ir as d,rr as f,sn as p,vr as m,xr as h}from"./vendor-react-DQVTOTFO.js";import{a as g,o as _,s as v,t as y}from"./utils-fgvbH6CB.js";import{d as b,f as x,p as S}from"./index-yE_3fruG.js";var C=e(h(),1),w=m(),T={get:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`,post:`bg-sky-500/10 text-sky-400 border-sky-500/20`,put:`bg-amber-500/10 text-amber-400 border-amber-500/20`,patch:`bg-violet-500/10 text-violet-400 border-violet-500/20`,delete:`bg-red-500/10 text-red-400 border-red-500/20`};function E(){let[e,m]=(0,C.useState)(`graphql`),{theme:h}=g(),E=h===`dark`,[D,O]=(0,C.useState)(null),k=(0,C.useRef)(null),A=v(e=>e.token),[j,M]=(0,C.useState)(null),[N,P]=(0,C.useState)(!1),[F,I]=(0,C.useState)(null),[L,R]=(0,C.useState)(null),z=`/graphql`,B=`/api/docs`,V=(0,C.useCallback)(async()=>{P(!0),I(null);try{M((await _.get(`/system/openapi.json`)).data)}catch{I(`Could not load API schema. Make sure the backend server is running.`)}finally{P(!1)}},[]);(0,C.useEffect)(()=>{e===`rest`&&!j&&V()},[e,j,V]);let H=(e,t)=>{navigator.clipboard.writeText(e),O(t),setTimeout(()=>O(null),2e3)},U=()=>{k.current?.contentWindow&&A&&k.current.contentWindow.postMessage({type:`ZENITH_AUTH_TOKEN`,token:A},`*`)},W=`3.7.1`,G=`18.3.1`,K=`
2
2
  <!DOCTYPE html>
3
3
  <html lang="en">
4
4
  <head>
@@ -1 +1 @@
1
- {"version":3,"file":"ApiExplorerPage-UJpoKRI0.js","names":[],"sources":["../../src/pages/ApiExplorerPage.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { Terminal, Braces, Code, Copy, Check, ExternalLink, RefreshCw, Globe, ChevronDown, ChevronUp, Loader2 } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport { useTheme } from '../context/ThemeContext'\nimport { PageHeader } from '../components/ui/PageHeader'\nimport { Card, CardContent } from '../components/ui/Card'\nimport { useTenantStore } from '../lib/tenantStore'\nimport api from '../lib/api'\n\nconst METHOD_COLORS: Record<string, string> = {\n get: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20',\n post: 'bg-sky-500/10 text-sky-400 border-sky-500/20',\n put: 'bg-amber-500/10 text-amber-400 border-amber-500/20',\n patch: 'bg-violet-500/10 text-violet-400 border-violet-500/20',\n delete: 'bg-red-500/10 text-red-400 border-red-500/20',\n}\n\nexport default function ApiExplorerPage() {\n const [activeTab, setActiveTab] = useState<'graphql' | 'rest'>('graphql')\n const { theme } = useTheme()\n const dark = theme === 'dark'\n const [copiedUrl, setCopiedUrl] = useState<string | null>(null)\n const iframeRef = useRef<HTMLIFrameElement>(null)\n const token = useTenantStore((s) => s.token)\n\n // REST inline spec state\n const [restSpec, setRestSpec] = useState<any>(null)\n const [restLoading, setRestLoading] = useState(false)\n const [restError, setRestError] = useState<string | null>(null)\n const [expandedPath, setExpandedPath] = useState<string | null>(null)\n\n const graphqlUrl = `${import.meta.env.VITE_API_URL || '/api/v1'}`.replace('/api/v1', '/graphql')\n const restDocsUrl = `${import.meta.env.VITE_API_URL || '/api/v1'}`.replace('/api/v1', '/api/docs')\n\n const fetchRestSpec = useCallback(async () => {\n setRestLoading(true)\n setRestError(null)\n try {\n const res = await api.get('/system/openapi.json')\n setRestSpec(res.data)\n } catch {\n setRestError('Could not load API schema. Make sure the backend server is running.')\n } finally {\n setRestLoading(false)\n }\n }, [])\n\n useEffect(() => {\n if (activeTab === 'rest' && !restSpec) fetchRestSpec()\n }, [activeTab, restSpec, fetchRestSpec])\n\n const handleCopy = (url: string, type: string) => {\n navigator.clipboard.writeText(url)\n setCopiedUrl(type)\n setTimeout(() => setCopiedUrl(null), 2000)\n }\n\n // Securely pass token to the iframe via postMessage after it loads\n const handleIframeLoad = () => {\n if (iframeRef.current?.contentWindow && token) {\n iframeRef.current.contentWindow.postMessage(\n { type: 'ZENITH_AUTH_TOKEN', token },\n '*'\n )\n }\n }\n\n // Version-pinned CDN resources for security and stability\n const GRAPHIQL_VERSION = '3.7.1'\n const REACT_VERSION = '18.3.1'\n\n const graphiqlHTML = `\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\" />\n <title>GraphiQL</title>\n <style>\n body { margin: 0; width: 100%; height: 100%; overflow: hidden; }\n #graphiql { height: 100vh; }\n </style>\n <link rel=\"stylesheet\" href=\"https://unpkg.com/graphiql@${GRAPHIQL_VERSION}/graphiql.min.css\" />\n </head>\n <body class=\"${dark ? 'graphiql-dark' : 'graphiql-light'}\">\n <div id=\"graphiql\">Loading...</div>\n <script src=\"https://unpkg.com/react@${REACT_VERSION}/umd/react.production.min.js\" crossorigin></script>\n <script src=\"https://unpkg.com/react-dom@${REACT_VERSION}/umd/react-dom.production.min.js\" crossorigin></script>\n <script src=\"https://unpkg.com/graphiql@${GRAPHIQL_VERSION}/graphiql.min.js\" crossorigin></script>\n <script>\n let authToken = '';\n\n window.addEventListener('message', function(event) {\n if (event.data && event.data.type === 'ZENITH_AUTH_TOKEN') {\n authToken = event.data.token || '';\n renderGraphiQL();\n }\n });\n\n function renderGraphiQL() {\n const fetcher = GraphiQL.createFetcher({\n url: '${graphqlUrl}',\n headers: { 'Authorization': 'Bearer ' + authToken }\n });\n const root = ReactDOM.createRoot(document.getElementById('graphiql'));\n root.render(React.createElement(GraphiQL, { fetcher: fetcher }));\n }\n\n renderGraphiQL();\n </script>\n </body>\n </html>\n `\n\n return (\n <div className=\"flex-1 overflow-y-auto bg-z-body text-z-text\">\n <PageHeader\n title=\"API Explorer\"\n description=\"Test and discover GraphQL and REST API endpoints instantly.\"\n icon={<Terminal size={24} />}\n breadcrumbs={[{ label: 'Development', path: '/api-explorer' }, { label: 'API Explorer' }]}\n actions={\n <div className=\"flex bg-z-input border border-z-border p-1 rounded-none-none\">\n <button\n onClick={() => setActiveTab('graphql')}\n className={cn(\n 'flex items-center gap-2 px-4 py-1.5 text-sm font-semibold transition-all',\n activeTab === 'graphql'\n ? 'bg-z-panel text-z-primary shadow-sm border border-z-border'\n : 'text-z-secondary hover:text-z-primary border border-transparent'\n )}\n >\n <Braces size={14} /> GraphQL\n </button>\n <button\n onClick={() => setActiveTab('rest')}\n className={cn(\n 'flex items-center gap-2 px-4 py-1.5 text-sm font-semibold transition-all',\n activeTab === 'rest'\n ? 'bg-z-panel text-z-primary shadow-sm border border-z-border'\n : 'text-z-secondary hover:text-z-primary border border-transparent'\n )}\n >\n <Code size={14} /> REST API\n </button>\n </div>\n }\n />\n\n <div className=\"p-6 max-w-7xl mx-auto space-y-6\">\n <Card>\n <CardContent className=\"p-4 flex flex-col md:flex-row items-start md:items-center justify-between gap-4\">\n <div>\n <h3 className=\"text-sm font-bold flex items-center gap-2\">\n <span className={cn('w-2 h-2 rounded-full', activeTab === 'graphql' ? 'bg-pink-500' : 'bg-emerald-500')} />\n {activeTab === 'graphql' ? 'GraphQL Endpoint' : 'REST API Explorer'}\n </h3>\n <p className=\"text-xs text-z-secondary mt-1\">\n {activeTab === 'graphql'\n ? 'Queries, Mutations, and automatic Schema Introspection via the Neural Schema Orchestrator.'\n : 'All collection endpoints auto-discovered from your active schema. Click an endpoint to expand.'}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <code className={cn('px-3 py-1.5 border text-xs font-mono font-medium', dark ? 'bg-app border-z-border text-z-primary' : 'bg-z-body border-z-border text-z-primary')}>\n {activeTab === 'graphql' ? graphqlUrl : restDocsUrl}\n </code>\n <button\n onClick={() => handleCopy(activeTab === 'graphql' ? graphqlUrl : restDocsUrl, activeTab)}\n className=\"p-1.5 border border-z-border hover:bg-z-hover text-z-secondary hover:text-z-primary transition-colors\"\n title=\"Copy URL\"\n >\n {copiedUrl === activeTab ? <Check size={14} className=\"text-green-500\" /> : <Copy size={14} />}\n </button>\n <a\n href={activeTab === 'graphql' ? graphqlUrl : restDocsUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"p-1.5 border border-z-border hover:bg-z-hover text-z-secondary hover:text-z-primary transition-colors\"\n title=\"Open in new tab\"\n >\n <ExternalLink size={14} />\n </a>\n </div>\n </CardContent>\n </Card>\n\n <Card className=\"flex flex-col overflow-hidden\" style={{ minHeight: '600px' }}>\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={activeTab}\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.15 }}\n className=\"flex-1 w-full\"\n style={{ minHeight: '600px' }}\n >\n {activeTab === 'graphql' ? (\n <iframe\n ref={iframeRef}\n title=\"GraphQL Playground\"\n srcDoc={graphiqlHTML}\n className=\"w-full border-none bg-white\"\n style={{ height: '700px' }}\n sandbox=\"allow-scripts allow-same-origin\"\n onLoad={handleIframeLoad}\n />\n ) : (\n /* ── Inline REST endpoint explorer ── */\n <div className=\"overflow-y-auto p-6 space-y-4\" style={{ maxHeight: '700px' }}>\n <div className=\"flex items-center justify-between mb-2\">\n <div>\n <h3 className=\"text-sm font-bold text-z-primary\">REST Endpoints</h3>\n <p className=\"text-xs text-z-secondary mt-0.5\">\n {restSpec ? `${Object.keys(restSpec.paths || {}).length} paths • Click to expand` : 'Fetching from server…'}\n </p>\n </div>\n <button\n onClick={fetchRestSpec}\n disabled={restLoading}\n className=\"p-2 border border-z-border hover:bg-z-hover text-z-secondary hover:text-z-primary transition-colors\"\n title=\"Reload schema\"\n >\n <RefreshCw size={13} className={restLoading ? 'animate-spin' : ''} />\n </button>\n </div>\n\n {restLoading ? (\n <div className=\"flex flex-col items-center justify-center py-24 gap-3\">\n <Loader2 size={28} className=\"animate-spin text-z-secondary\" />\n <p className=\"text-sm text-z-secondary\">Loading API schema…</p>\n </div>\n ) : restError ? (\n <div className=\"flex flex-col items-center justify-center py-24 gap-4 text-center\">\n <div className={cn('w-14 h-14 flex items-center justify-center border', dark ? 'bg-red-500/5 border-red-500/20' : 'bg-red-50 border-red-200')}>\n <Globe size={24} className=\"text-red-400\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-z-primary\">Schema unavailable</p>\n <p className=\"text-xs text-z-secondary mt-1 max-w-xs\">{restError}</p>\n </div>\n <button\n onClick={fetchRestSpec}\n className=\"flex items-center gap-2 px-4 py-2 border border-z-border hover:border-z-active-border hover:bg-z-hover text-sm font-semibold text-z-secondary hover:text-z-primary transition-all\"\n >\n <RefreshCw size={12} /> Retry\n </button>\n </div>\n ) : restSpec ? (\n <div className=\"space-y-1.5\">\n {Object.entries(restSpec.paths || {}).map(([path, methods]: [string, any]) => (\n <div key={path} className={cn('border overflow-hidden', dark ? 'border-z-border' : 'border-z-border')}>\n <button\n onClick={() => setExpandedPath(expandedPath === path ? null : path)}\n className={cn(\n 'w-full flex items-center justify-between px-4 py-3 transition-colors text-left gap-3',\n dark ? 'hover:bg-z-hover' : 'hover:bg-z-input'\n )}\n >\n <div className=\"flex items-center gap-2 flex-wrap min-w-0\">\n {Object.keys(methods).map(method => (\n <span\n key={method}\n className={cn('px-1.5 py-0.5 text-xs font-bold font-mono border uppercase shrink-0', METHOD_COLORS[method] || 'text-z-secondary border-z-border bg-z-hover')}\n >\n {method}\n </span>\n ))}\n <code className=\"text-xs font-mono text-z-primary truncate\">{path}</code>\n </div>\n <div className=\"shrink-0 text-z-secondary\">\n {expandedPath === path ? <ChevronUp size={13} /> : <ChevronDown size={13} />}\n </div>\n </button>\n <AnimatePresence>\n {expandedPath === path && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"overflow-hidden\"\n >\n <div className={cn('px-4 pb-4 pt-3 space-y-3 border-t', dark ? 'border-z-border bg-z-hover/20' : 'border-z-border bg-z-input/30')}>\n {Object.entries(methods).map(([method, op]: [string, any]) => (\n <div key={method} className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <span className={cn('px-1.5 py-0.5 text-xs font-bold font-mono border uppercase shrink-0', METHOD_COLORS[method] || 'text-z-secondary border-z-border')}>\n {method}\n </span>\n <span className=\"text-sm font-semibold text-z-primary\">{op.summary}</span>\n </div>\n {op.parameters && op.parameters.length > 0 && (\n <div className=\"ml-14 flex flex-wrap gap-1 text-xs\">\n <span className=\"text-z-secondary\">Params:</span>\n {op.parameters.map((p: any) => (\n <code key={p.name} className={cn('px-1.5 py-0.5 border font-mono', dark ? 'bg-z-panel border-z-border text-z-primary' : 'bg-white border-z-border text-z-primary')}>\n {p.name}\n {p.required && <span className=\"text-red-400 ml-0.5\">*</span>}\n </code>\n ))}\n </div>\n )}\n {op.responses && (\n <div className=\"ml-14 flex gap-1 text-xs\">\n <span className=\"text-z-secondary\">Responses:</span>\n {Object.keys(op.responses).map(code => (\n <span key={code} className={cn('px-1.5 py-0.5 border font-mono font-bold',\n code.startsWith('2') ? 'text-emerald-400 border-emerald-500/20 bg-emerald-500/10' : 'text-amber-400 border-amber-500/20 bg-amber-500/10'\n )}>{code}</span>\n ))}\n </div>\n )}\n </div>\n ))}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n )}\n </motion.div>\n </AnimatePresence>\n </Card>\n </div>\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ApiExplorerPage-85UWt1EW.js","names":[],"sources":["../../src/pages/ApiExplorerPage.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { Terminal, Braces, Code, Copy, Check, ExternalLink, RefreshCw, Globe, ChevronDown, ChevronUp, Loader2 } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport { useTheme } from '../context/ThemeContext'\nimport { PageHeader } from '../components/ui/PageHeader'\nimport { Card, CardContent } from '../components/ui/Card'\nimport { useTenantStore } from '../lib/tenantStore'\nimport api from '../lib/api'\n\nconst METHOD_COLORS: Record<string, string> = {\n get: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20',\n post: 'bg-sky-500/10 text-sky-400 border-sky-500/20',\n put: 'bg-amber-500/10 text-amber-400 border-amber-500/20',\n patch: 'bg-violet-500/10 text-violet-400 border-violet-500/20',\n delete: 'bg-red-500/10 text-red-400 border-red-500/20',\n}\n\nexport default function ApiExplorerPage() {\n const [activeTab, setActiveTab] = useState<'graphql' | 'rest'>('graphql')\n const { theme } = useTheme()\n const dark = theme === 'dark'\n const [copiedUrl, setCopiedUrl] = useState<string | null>(null)\n const iframeRef = useRef<HTMLIFrameElement>(null)\n const token = useTenantStore((s) => s.token)\n\n // REST inline spec state\n const [restSpec, setRestSpec] = useState<any>(null)\n const [restLoading, setRestLoading] = useState(false)\n const [restError, setRestError] = useState<string | null>(null)\n const [expandedPath, setExpandedPath] = useState<string | null>(null)\n\n const graphqlUrl = `${import.meta.env.VITE_API_URL || '/api/v1'}`.replace('/api/v1', '/graphql')\n const restDocsUrl = `${import.meta.env.VITE_API_URL || '/api/v1'}`.replace('/api/v1', '/api/docs')\n\n const fetchRestSpec = useCallback(async () => {\n setRestLoading(true)\n setRestError(null)\n try {\n const res = await api.get('/system/openapi.json')\n setRestSpec(res.data)\n } catch {\n setRestError('Could not load API schema. Make sure the backend server is running.')\n } finally {\n setRestLoading(false)\n }\n }, [])\n\n useEffect(() => {\n if (activeTab === 'rest' && !restSpec) fetchRestSpec()\n }, [activeTab, restSpec, fetchRestSpec])\n\n const handleCopy = (url: string, type: string) => {\n navigator.clipboard.writeText(url)\n setCopiedUrl(type)\n setTimeout(() => setCopiedUrl(null), 2000)\n }\n\n // Securely pass token to the iframe via postMessage after it loads\n const handleIframeLoad = () => {\n if (iframeRef.current?.contentWindow && token) {\n iframeRef.current.contentWindow.postMessage(\n { type: 'ZENITH_AUTH_TOKEN', token },\n '*'\n )\n }\n }\n\n // Version-pinned CDN resources for security and stability\n const GRAPHIQL_VERSION = '3.7.1'\n const REACT_VERSION = '18.3.1'\n\n const graphiqlHTML = `\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\" />\n <title>GraphiQL</title>\n <style>\n body { margin: 0; width: 100%; height: 100%; overflow: hidden; }\n #graphiql { height: 100vh; }\n </style>\n <link rel=\"stylesheet\" href=\"https://unpkg.com/graphiql@${GRAPHIQL_VERSION}/graphiql.min.css\" />\n </head>\n <body class=\"${dark ? 'graphiql-dark' : 'graphiql-light'}\">\n <div id=\"graphiql\">Loading...</div>\n <script src=\"https://unpkg.com/react@${REACT_VERSION}/umd/react.production.min.js\" crossorigin></script>\n <script src=\"https://unpkg.com/react-dom@${REACT_VERSION}/umd/react-dom.production.min.js\" crossorigin></script>\n <script src=\"https://unpkg.com/graphiql@${GRAPHIQL_VERSION}/graphiql.min.js\" crossorigin></script>\n <script>\n let authToken = '';\n\n window.addEventListener('message', function(event) {\n if (event.data && event.data.type === 'ZENITH_AUTH_TOKEN') {\n authToken = event.data.token || '';\n renderGraphiQL();\n }\n });\n\n function renderGraphiQL() {\n const fetcher = GraphiQL.createFetcher({\n url: '${graphqlUrl}',\n headers: { 'Authorization': 'Bearer ' + authToken }\n });\n const root = ReactDOM.createRoot(document.getElementById('graphiql'));\n root.render(React.createElement(GraphiQL, { fetcher: fetcher }));\n }\n\n renderGraphiQL();\n </script>\n </body>\n </html>\n `\n\n return (\n <div className=\"flex-1 overflow-y-auto bg-z-body text-z-text\">\n <PageHeader\n title=\"API Explorer\"\n description=\"Test and discover GraphQL and REST API endpoints instantly.\"\n icon={<Terminal size={24} />}\n breadcrumbs={[{ label: 'Development', path: '/api-explorer' }, { label: 'API Explorer' }]}\n actions={\n <div className=\"flex bg-z-input border border-z-border p-1 rounded-none-none\">\n <button\n onClick={() => setActiveTab('graphql')}\n className={cn(\n 'flex items-center gap-2 px-4 py-1.5 text-sm font-semibold transition-all',\n activeTab === 'graphql'\n ? 'bg-z-panel text-z-primary shadow-sm border border-z-border'\n : 'text-z-secondary hover:text-z-primary border border-transparent'\n )}\n >\n <Braces size={14} /> GraphQL\n </button>\n <button\n onClick={() => setActiveTab('rest')}\n className={cn(\n 'flex items-center gap-2 px-4 py-1.5 text-sm font-semibold transition-all',\n activeTab === 'rest'\n ? 'bg-z-panel text-z-primary shadow-sm border border-z-border'\n : 'text-z-secondary hover:text-z-primary border border-transparent'\n )}\n >\n <Code size={14} /> REST API\n </button>\n </div>\n }\n />\n\n <div className=\"p-6 max-w-7xl mx-auto space-y-6\">\n <Card>\n <CardContent className=\"p-4 flex flex-col md:flex-row items-start md:items-center justify-between gap-4\">\n <div>\n <h3 className=\"text-sm font-bold flex items-center gap-2\">\n <span className={cn('w-2 h-2 rounded-full', activeTab === 'graphql' ? 'bg-pink-500' : 'bg-emerald-500')} />\n {activeTab === 'graphql' ? 'GraphQL Endpoint' : 'REST API Explorer'}\n </h3>\n <p className=\"text-xs text-z-secondary mt-1\">\n {activeTab === 'graphql'\n ? 'Queries, Mutations, and automatic Schema Introspection via the Neural Schema Orchestrator.'\n : 'All collection endpoints auto-discovered from your active schema. Click an endpoint to expand.'}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <code className={cn('px-3 py-1.5 border text-xs font-mono font-medium', dark ? 'bg-app border-z-border text-z-primary' : 'bg-z-body border-z-border text-z-primary')}>\n {activeTab === 'graphql' ? graphqlUrl : restDocsUrl}\n </code>\n <button\n onClick={() => handleCopy(activeTab === 'graphql' ? graphqlUrl : restDocsUrl, activeTab)}\n className=\"p-1.5 border border-z-border hover:bg-z-hover text-z-secondary hover:text-z-primary transition-colors\"\n title=\"Copy URL\"\n >\n {copiedUrl === activeTab ? <Check size={14} className=\"text-green-500\" /> : <Copy size={14} />}\n </button>\n <a\n href={activeTab === 'graphql' ? graphqlUrl : restDocsUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"p-1.5 border border-z-border hover:bg-z-hover text-z-secondary hover:text-z-primary transition-colors\"\n title=\"Open in new tab\"\n >\n <ExternalLink size={14} />\n </a>\n </div>\n </CardContent>\n </Card>\n\n <Card className=\"flex flex-col overflow-hidden\" style={{ minHeight: '600px' }}>\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={activeTab}\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.15 }}\n className=\"flex-1 w-full\"\n style={{ minHeight: '600px' }}\n >\n {activeTab === 'graphql' ? (\n <iframe\n ref={iframeRef}\n title=\"GraphQL Playground\"\n srcDoc={graphiqlHTML}\n className=\"w-full border-none bg-white\"\n style={{ height: '700px' }}\n sandbox=\"allow-scripts allow-same-origin\"\n onLoad={handleIframeLoad}\n />\n ) : (\n /* ── Inline REST endpoint explorer ── */\n <div className=\"overflow-y-auto p-6 space-y-4\" style={{ maxHeight: '700px' }}>\n <div className=\"flex items-center justify-between mb-2\">\n <div>\n <h3 className=\"text-sm font-bold text-z-primary\">REST Endpoints</h3>\n <p className=\"text-xs text-z-secondary mt-0.5\">\n {restSpec ? `${Object.keys(restSpec.paths || {}).length} paths • Click to expand` : 'Fetching from server…'}\n </p>\n </div>\n <button\n onClick={fetchRestSpec}\n disabled={restLoading}\n className=\"p-2 border border-z-border hover:bg-z-hover text-z-secondary hover:text-z-primary transition-colors\"\n title=\"Reload schema\"\n >\n <RefreshCw size={13} className={restLoading ? 'animate-spin' : ''} />\n </button>\n </div>\n\n {restLoading ? (\n <div className=\"flex flex-col items-center justify-center py-24 gap-3\">\n <Loader2 size={28} className=\"animate-spin text-z-secondary\" />\n <p className=\"text-sm text-z-secondary\">Loading API schema…</p>\n </div>\n ) : restError ? (\n <div className=\"flex flex-col items-center justify-center py-24 gap-4 text-center\">\n <div className={cn('w-14 h-14 flex items-center justify-center border', dark ? 'bg-red-500/5 border-red-500/20' : 'bg-red-50 border-red-200')}>\n <Globe size={24} className=\"text-red-400\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-z-primary\">Schema unavailable</p>\n <p className=\"text-xs text-z-secondary mt-1 max-w-xs\">{restError}</p>\n </div>\n <button\n onClick={fetchRestSpec}\n className=\"flex items-center gap-2 px-4 py-2 border border-z-border hover:border-z-active-border hover:bg-z-hover text-sm font-semibold text-z-secondary hover:text-z-primary transition-all\"\n >\n <RefreshCw size={12} /> Retry\n </button>\n </div>\n ) : restSpec ? (\n <div className=\"space-y-1.5\">\n {Object.entries(restSpec.paths || {}).map(([path, methods]: [string, any]) => (\n <div key={path} className={cn('border overflow-hidden', dark ? 'border-z-border' : 'border-z-border')}>\n <button\n onClick={() => setExpandedPath(expandedPath === path ? null : path)}\n className={cn(\n 'w-full flex items-center justify-between px-4 py-3 transition-colors text-left gap-3',\n dark ? 'hover:bg-z-hover' : 'hover:bg-z-input'\n )}\n >\n <div className=\"flex items-center gap-2 flex-wrap min-w-0\">\n {Object.keys(methods).map(method => (\n <span\n key={method}\n className={cn('px-1.5 py-0.5 text-xs font-bold font-mono border uppercase shrink-0', METHOD_COLORS[method] || 'text-z-secondary border-z-border bg-z-hover')}\n >\n {method}\n </span>\n ))}\n <code className=\"text-xs font-mono text-z-primary truncate\">{path}</code>\n </div>\n <div className=\"shrink-0 text-z-secondary\">\n {expandedPath === path ? <ChevronUp size={13} /> : <ChevronDown size={13} />}\n </div>\n </button>\n <AnimatePresence>\n {expandedPath === path && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"overflow-hidden\"\n >\n <div className={cn('px-4 pb-4 pt-3 space-y-3 border-t', dark ? 'border-z-border bg-z-hover/20' : 'border-z-border bg-z-input/30')}>\n {Object.entries(methods).map(([method, op]: [string, any]) => (\n <div key={method} className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <span className={cn('px-1.5 py-0.5 text-xs font-bold font-mono border uppercase shrink-0', METHOD_COLORS[method] || 'text-z-secondary border-z-border')}>\n {method}\n </span>\n <span className=\"text-sm font-semibold text-z-primary\">{op.summary}</span>\n </div>\n {op.parameters && op.parameters.length > 0 && (\n <div className=\"ml-14 flex flex-wrap gap-1 text-xs\">\n <span className=\"text-z-secondary\">Params:</span>\n {op.parameters.map((p: any) => (\n <code key={p.name} className={cn('px-1.5 py-0.5 border font-mono', dark ? 'bg-z-panel border-z-border text-z-primary' : 'bg-white border-z-border text-z-primary')}>\n {p.name}\n {p.required && <span className=\"text-red-400 ml-0.5\">*</span>}\n </code>\n ))}\n </div>\n )}\n {op.responses && (\n <div className=\"ml-14 flex gap-1 text-xs\">\n <span className=\"text-z-secondary\">Responses:</span>\n {Object.keys(op.responses).map(code => (\n <span key={code} className={cn('px-1.5 py-0.5 border font-mono font-bold',\n code.startsWith('2') ? 'text-emerald-400 border-emerald-500/20 bg-emerald-500/10' : 'text-amber-400 border-amber-500/20 bg-amber-500/10'\n )}>{code}</span>\n ))}\n </div>\n )}\n </div>\n ))}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n )}\n </motion.div>\n </AnimatePresence>\n </Card>\n </div>\n </div>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{C as t,Ct as n,Dt as r,En as i,H as a,J as o,Kt as s,Ln as c,Ut as l,_n as u,an as d,l as f,on as p,rr as m,u as h,vr as g,xr as _}from"./vendor-react-DQVTOTFO.js";import{a as v,o as y,t as b}from"./utils-fgvbH6CB.js";import{p as x}from"./index-ChcKY5Xe.js";var S=e(_(),1),C=g(),w=()=>{let{theme:e}=v(),[g,_]=(0,S.useState)([]),[w,T]=(0,S.useState)(!0),[E,D]=(0,S.useState)(1),[O,k]=(0,S.useState)(0),[A,j]=(0,S.useState)(1),[M,N]=(0,S.useState)(``),[P,F]=(0,S.useState)(!1),[I,L]=(0,S.useState)(null),[R,z]=(0,S.useState)(!1),[B,V]=(0,S.useState)(null),[H,U]=(0,S.useState)(``),[W,G]=(0,S.useState)(!1),[K,q]=(0,S.useState)(``),[J,Y]=(0,S.useState)(``),[X,Z]=(0,S.useState)(30),Q=(0,S.useCallback)(async()=>{T(!0);try{let e={page:E,limit:25};M&&(e.search=M),H&&(e.action=H);let t=await y.get(`/system/audit-logs`,{params:e});_(t.data.data||[]),t.data.meta?.pagination&&(k(t.data.meta.pagination.total),j(t.data.meta.pagination.totalPages))}catch{f.error(`Failed to fetch audit logs`)}finally{setTimeout(()=>T(!1),300)}},[E,M,H]),$=(0,S.useCallback)(async()=>{try{let e=await y.get(`/system/audit-logs/stats`);e.data.data&&L(e.data.data)}catch{}},[]);(0,S.useEffect)(()=>{Q(),$()},[Q,$]);let ee=()=>{D(1),Q()},te=async()=>{F(!0);try{let e=await y.get(`/system/audit-logs`,{params:{limit:500}}),t=new Blob([JSON.stringify(e.data.data,null,2)],{type:`application/json`}),n=window.URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.setAttribute(`download`,`ZENITH_AUDIT_${new Date().toISOString().replace(/[:.]/g,`-`)}.json`),document.body.appendChild(r),r.click(),r.remove(),window.URL.revokeObjectURL(n),f.success(`Report exported`)}catch{f.error(`Export failed`)}finally{F(!1)}},ne=()=>{q(Math.floor(1e5+Math.random()*9e5).toString()),Y(``),Z(30),G(!0)},re=()=>{if(J!==K){f.error(`Authorization code does not match`);return}G(!1),z(!0);let e=new Date(Date.now()-X*24*60*60*1e3).toISOString();f.promise(y.post(`/system/audit-logs/purge`,{before:e}),{loading:`Purging audit logs...`,success:e=>(Q(),$(),e.data?.data?.message||`Purged ${e.data?.data?.deleted||0} audit log entries`),error:`Purge failed`}).finally(()=>z(!1))},ie=e=>e?.toUpperCase()||`UNKNOWN`,ae=e=>{let t=e?.toUpperCase();return t===`CREATE`?`bg-emerald-50 text-emerald-600 dark:bg-emerald-500/10 dark:text-emerald-400 border-emerald-200 dark:border-emerald-500/20`:t===`UPDATE`?`bg-blue-50 text-blue-600 dark:bg-blue-500/10 dark:text-blue-400 border-blue-200 dark:border-blue-500/20`:t===`DELETE`?`bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400 border-red-200 dark:border-red-500/20`:`bg-amber-50 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400 border-amber-200 dark:border-amber-500/20`},oe=e=>e.userName||e.userEmail||`System`;return(0,C.jsxs)(`div`,{className:`flex flex-col h-[calc(100vh-64px)] overflow-hidden`,children:[(0,C.jsx)(x,{title:`Audit Logs`,description:`System History`,icon:(0,C.jsx)(r,{size:24}),backLink:{to:`/`,label:`Dashboard`},actions:(0,C.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,C.jsxs)(`div`,{className:b(`px-6 py-2 border rounded-lg flex items-center gap-8 shadow-sm transition-all`,`bg-z-panel border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex flex-col items-end`,children:[(0,C.jsx)(`span`,{className:`text-sm font-semibold text-z-muted opacity-60`,children:`Total Logs`}),(0,C.jsx)(`span`,{className:`text-xl font-semibold leading-none text-z-secondary `,children:O.toLocaleString()})]}),I&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`div`,{className:b(`w-px h-8`,e===`dark`?`bg-z-hover`:`bg-[var(--z-bg-hover)]`)}),(0,C.jsxs)(`div`,{className:`flex flex-col items-end`,children:[(0,C.jsx)(`span`,{className:`text-sm font-semibold text-z-muted opacity-60`,children:`Failed`}),(0,C.jsx)(`span`,{className:`text-xl font-semibold leading-none text-red-500`,children:I.failed})]}),(0,C.jsx)(`div`,{className:b(`w-px h-8`,e===`dark`?`bg-z-hover`:`bg-[var(--z-bg-hover)]`)}),(0,C.jsxs)(`div`,{className:`flex flex-col items-end`,children:[(0,C.jsx)(`span`,{className:`text-sm font-semibold text-z-muted opacity-60`,children:`Status`}),(0,C.jsx)(`span`,{className:`text-xs font-semibold text-z-secondary leading-none`,children:`Stable`})]})]})]}),(0,C.jsx)(`button`,{onClick:()=>{D(1),Q()},className:b(`w-10 h-10 border rounded-lg flex items-center justify-center transition-all hover:scale-105 active:scale-95 shadow-sm`,e===`dark`?`bg-z-panel border-z-border text-z-muted hover:border-z-border`:`bg-z-panel border-z-border text-z-muted hover:border-[var(--z-border-strong)]`),children:(0,C.jsx)(o,{size:20,className:w?`animate-spin`:``})})]})}),(0,C.jsx)(`div`,{className:b(`flex-1 overflow-y-auto p-10 space-y-6 transition-colors duration-500`,e===`dark`?`bg-app text-z-primary`:`bg-[#fafafa] text-z-primary`),children:(0,C.jsxs)(`div`,{className:b(`flex flex-col border rounded-xl shadow-sm transition-all overflow-hidden`,`bg-z-panel border-z-border`),children:[(0,C.jsxs)(`div`,{className:b(`px-8 py-5 border-b flex items-center justify-between gap-6 transition-colors`,`border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-4 flex-1`,children:[(0,C.jsxs)(`div`,{className:b(`flex items-center gap-3 border px-4 py-2 rounded-md w-full max-w-md shadow-sm transition-all group relative overflow-hidden`,e===`dark`?`bg-[#1c1c1c] border-z-border focus-within:border-z-accent`:`bg-z-panel border-[var(--z-border-strong)] focus-within:border-z-accent`),children:[(0,C.jsx)(a,{size:16,className:`text-z-secondary group-focus-within:text-z-secondary transition-colors`}),(0,C.jsx)(`input`,{type:`text`,value:M,onChange:e=>N(e.target.value),onKeyDown:e=>e.key===`Enter`&&ee(),placeholder:`Search by email, name, collection...`,className:`bg-transparent border-none outline-none text-sm w-full placeholder:text-z-muted dark:placeholder:text-z-secondary`})]}),(0,C.jsxs)(`select`,{value:H,onChange:e=>{U(e.target.value),D(1)},className:b(`px-4 py-2 border rounded-md text-sm outline-none transition-all shadow-sm`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-primary focus:border-z-accent`:`bg-z-panel border-[var(--z-border-strong)] text-z-primary focus:border-z-accent`),children:[(0,C.jsx)(`option`,{value:``,children:`All Actions`}),(0,C.jsx)(`option`,{value:`create`,children:`Create`}),(0,C.jsx)(`option`,{value:`update`,children:`Update`}),(0,C.jsx)(`option`,{value:`delete`,children:`Delete`}),(0,C.jsx)(`option`,{value:`publish`,children:`Publish`}),(0,C.jsx)(`option`,{value:`unpublish`,children:`Unpublish`}),(0,C.jsx)(`option`,{value:`login`,children:`Login`})]})]}),(0,C.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,C.jsxs)(`button`,{onClick:ne,disabled:R,className:b(`flex items-center gap-2 px-4 py-2 border rounded-md text-sm font-medium transition-all hover:bg-red-50 hover:text-red-600 hover:border-red-200 dark:hover:bg-red-500/10 dark:hover:text-red-400 dark:hover:border-red-500/20`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-muted`:`bg-z-panel border-[var(--z-border-strong)] text-z-secondary`),children:[(0,C.jsx)(t,{size:14}),`Purge`]}),(0,C.jsxs)(`button`,{onClick:te,disabled:P,className:b(`flex items-center gap-2 px-5 py-2 rounded-md font-medium text-sm transition-all shadow-sm active:scale-95`,e===`dark`?`bg-z-panel text-z-primary hover:bg-[var(--z-border)]`:`bg-z-accent text-z-primary hover:brightness-110`),children:[P?(0,C.jsx)(o,{className:`animate-spin`,size:14}):(0,C.jsx)(l,{size:14}),`Export`]})]})]}),(0,C.jsx)(`div`,{className:`overflow-x-auto`,children:(0,C.jsx)(`div`,{className:`overflow-x-auto min-w-full pb-4`,children:(0,C.jsxs)(`table`,{className:`w-full border-collapse`,children:[(0,C.jsx)(`thead`,{children:(0,C.jsxs)(`tr`,{className:b(`border-b text-left`,e===`dark`?`border-z-border bg-[#1c1c1c]`:`border-z-border bg-[var(--z-bg-input)]`),children:[(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Operator`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Action`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Collection`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Status`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted text-right`,children:`Timestamp`})]})}),(0,C.jsx)(`tbody`,{className:b(`divide-y`,`divide-z-border`),children:w?(0,C.jsx)(`tr`,{children:(0,C.jsx)(`td`,{colSpan:5,className:`py-20 text-center`,children:(0,C.jsx)(c,{size:24,className:`animate-spin text-z-secondary mx-auto opacity-40`})})}):g.length===0?(0,C.jsx)(`tr`,{children:(0,C.jsx)(`td`,{colSpan:5,className:`py-20 text-center`,children:(0,C.jsx)(`div`,{className:`text-z-secondary text-sm font-bold`,children:`No audit logs found`})})}):g.map(t=>(0,C.jsxs)(m.tr,{initial:{opacity:0},animate:{opacity:1},onClick:()=>V(B===(t._id||t.id)?null:t._id||t.id),className:`hover:bg-z-border/[0.02] transition-colors cursor-pointer group`,children:[(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,C.jsx)(`div`,{className:b(`w-8 h-8 rounded-full border flex items-center justify-center flex-shrink-0`,e===`dark`?`bg-[#2c2c2c] border-z-border text-z-secondary`:`bg-[var(--z-bg-hover)] border-z-border text-z-secondary`),children:(0,C.jsx)(n,{size:14})}),(0,C.jsxs)(`div`,{className:`flex flex-col`,children:[(0,C.jsx)(`span`,{className:b(`text-sm font-semibold leading-none`,`text-z-primary`),children:oe(t)}),(0,C.jsx)(`span`,{className:`text-xs text-z-muted mt-1`,children:t.userId?`ID: ${t.userId.slice(-8).toUpperCase()}`:`SYSTEM`})]})]})}),(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsxs)(`div`,{className:b(`px-2.5 py-1 rounded-md text-xs font-semibold inline-flex items-center gap-1.5 border`,ae(t.action)),children:[(0,C.jsx)(h,{size:10,fill:`currentColor`}),ie(t.action)]})}),(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsxs)(`div`,{className:`flex flex-col`,children:[(0,C.jsx)(`span`,{className:b(`text-sm font-medium leading-none`,`text-z-primary`),children:t.collectionName||`SYSTEM`}),t.documentId&&(0,C.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1 text-z-muted`,children:[(0,C.jsx)(u,{size:10}),(0,C.jsxs)(`span`,{className:`text-xs font-mono`,children:[`DOC_`,t.documentId.slice(-12).toUpperCase()]})]})]})}),(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsx)(`span`,{className:b(`text-sm font-medium`,t.status===`failed`?`text-red-500`:`text-emerald-600 dark:text-emerald-400`),children:t.status===`failed`?`Failed`:`Success`})}),(0,C.jsx)(`td`,{className:`px-6 py-4 text-right`,children:(0,C.jsxs)(`div`,{className:`flex flex-col items-end gap-1`,children:[(0,C.jsx)(`span`,{className:b(`text-sm font-medium leading-none`,e===`dark`?`text-z-secondary`:`text-z-primary`),children:t.timestamp?new Date(t.timestamp).toLocaleDateString():`-`}),(0,C.jsx)(`span`,{className:`text-xs text-z-muted leading-none`,children:t.timestamp?new Date(t.timestamp).toLocaleTimeString():`-`})]})})]},t._id||t.id))})]})})}),B&&(()=>{let t=g.find(e=>(e._id||e.id)===B);return t?(0,C.jsxs)(`div`,{className:b(`px-8 py-6 border-t transition-colors`,e===`dark`?`bg-[#151515] border-z-border`:`bg-[#fafafa] border-z-border`),children:[(0,C.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 text-sm font-mono`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`IP Address`}),(0,C.jsx)(`div`,{className:`text-sm font-medium`,children:t.ip||`N/A`})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`User Agent`}),(0,C.jsx)(`div`,{className:`text-sm font-medium truncate`,title:t.userAgent,children:t.userAgent||`N/A`})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Resource`}),(0,C.jsx)(`div`,{className:`text-sm font-medium truncate`,title:t.resource,children:t.resource||`N/A`})]}),t.siteId&&(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Site ID`}),(0,C.jsx)(`div`,{className:`text-sm font-medium`,children:t.siteId})]}),t.hash&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Audit Hash`}),(0,C.jsxs)(`div`,{className:`text-sm font-medium truncate font-mono`,title:t.hash,children:[t.hash.slice(0,24),`...`]})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Prev Hash`}),(0,C.jsx)(`div`,{className:`text-sm font-medium truncate font-mono`,title:t.previousHash,children:t.previousHash?t.previousHash.slice(0,24)+`...`:`GENESIS`})]})]})]}),t.changes&&(0,C.jsxs)(`div`,{className:`mt-4`,children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-2`,children:`Changes`}),(0,C.jsx)(`pre`,{className:b(`p-4 rounded-md text-xs font-mono max-h-48 overflow-auto border shadow-sm`,e===`dark`?`bg-[#111111] border-z-border text-z-secondary`:`bg-z-panel border-z-border text-z-primary`),children:JSON.stringify(t.changes,null,2)})]})]}):null})(),(0,C.jsxs)(`div`,{className:b(`px-8 py-5 border-t flex items-center justify-between transition-colors rounded-b-xl`,e===`dark`?`bg-[#1c1c1c] border-z-border`:`bg-[var(--z-bg-input)] border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,C.jsx)(s,{size:14,className:`text-z-muted`}),(0,C.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`SECURE AUDIT TRAIL`}),I?.byAction&&Object.keys(I.byAction).length>0&&(0,C.jsx)(`div`,{className:`flex items-center gap-3 ml-4`,children:Object.entries(I.byAction).map(([e,t])=>(0,C.jsxs)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted`,children:[e,`:`,t]},e))})]}),(0,C.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,C.jsxs)(`span`,{className:`text-xs font-semibold text-z-muted tracking-wider uppercase mr-2`,children:[`Page `,E,` of `,A]}),(0,C.jsx)(`button`,{disabled:E===1,onClick:()=>D(E-1),className:b(`w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20`,e===`dark`?`bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]`:`bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]`),children:(0,C.jsx)(p,{size:16})}),(0,C.jsx)(`div`,{className:b(`px-3 py-1 rounded-md text-sm font-medium border shadow-sm`,e===`dark`?`bg-z-panel text-z-primary border-z-border`:`bg-z-accent border-z-border text-z-primary`),children:E}),(0,C.jsx)(`button`,{disabled:E>=A,onClick:()=>D(E+1),className:b(`w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20`,e===`dark`?`bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]`:`bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]`),children:(0,C.jsx)(d,{size:16})})]})]})]})}),W&&(0,C.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm`,children:(0,C.jsxs)(m.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:b(`w-full max-w-md rounded-xl p-8 shadow-2xl border`,`bg-z-panel border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-3 text-red-500 mb-4`,children:[(0,C.jsx)(i,{size:24}),(0,C.jsx)(`h2`,{className:`text-xl font-bold text-z-primary tracking-tight`,children:`Purge Audit Logs`})]}),(0,C.jsxs)(`p`,{className:b(`text-sm mb-6 leading-relaxed`,`text-z-muted`),children:[`This action is `,(0,C.jsx)(`span`,{className:`font-bold text-red-500`,children:`irreversible`}),`. It will permanently delete audit logs matching your criteria.`]}),(0,C.jsxs)(`div`,{className:`space-y-5 mb-8`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`label`,{className:b(`block text-xs font-semibold uppercase tracking-wider mb-2`,`text-z-secondary`),children:`Logs older than (days):`}),(0,C.jsx)(`input`,{type:`number`,min:`0`,value:X,onChange:e=>Z(parseInt(e.target.value)||0),className:b(`w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50`:`bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50`)}),(0,C.jsx)(`p`,{className:`text-[10px] text-z-muted mt-1.5 font-medium uppercase tracking-wide`,children:`Set to 0 to delete all logs.`})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsxs)(`label`,{className:b(`block text-xs font-semibold uppercase tracking-wider mb-2`,`text-z-secondary`),children:[`Authorization Code: `,(0,C.jsx)(`span`,{className:`text-red-400 font-mono select-all font-bold tracking-widest`,children:K})]}),(0,C.jsx)(`input`,{type:`text`,value:J,onChange:e=>Y(e.target.value),placeholder:`Enter the 6-digit code above`,className:b(`w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all font-mono tracking-widest`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50`:`bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50`)})]})]}),(0,C.jsxs)(`div`,{className:`flex justify-end gap-3 pt-2`,children:[(0,C.jsx)(`button`,{onClick:()=>G(!1),className:b(`px-5 py-2.5 text-sm font-semibold border rounded-md transition-all`,e===`dark`?`border-z-border bg-z-panel text-z-muted hover:text-z-primary hover:brightness-110`:`border-z-border bg-z-panel text-z-secondary hover:bg-[var(--z-bg-input)]`),children:`Cancel`}),(0,C.jsx)(`button`,{onClick:re,disabled:J!==K,className:`px-5 py-2.5 text-sm font-semibold bg-red-500/10 text-red-500 border border-red-500/20 rounded-md hover:bg-red-500 hover:text-z-primary transition-all duration-300 disabled:opacity-30 disabled:cursor-not-allowed shadow-sm`,children:`Confirm Purge`})]})]})})]})};export{w as default};
1
+ import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{C as t,Ct as n,Dt as r,En as i,H as a,J as o,Kt as s,Ln as c,Ut as l,_n as u,an as d,l as f,on as p,rr as m,u as h,vr as g,xr as _}from"./vendor-react-DQVTOTFO.js";import{a as v,o as y,t as b}from"./utils-fgvbH6CB.js";import{p as x}from"./index-yE_3fruG.js";var S=e(_(),1),C=g(),w=()=>{let{theme:e}=v(),[g,_]=(0,S.useState)([]),[w,T]=(0,S.useState)(!0),[E,D]=(0,S.useState)(1),[O,k]=(0,S.useState)(0),[A,j]=(0,S.useState)(1),[M,N]=(0,S.useState)(``),[P,F]=(0,S.useState)(!1),[I,L]=(0,S.useState)(null),[R,z]=(0,S.useState)(!1),[B,V]=(0,S.useState)(null),[H,U]=(0,S.useState)(``),[W,G]=(0,S.useState)(!1),[K,q]=(0,S.useState)(``),[J,Y]=(0,S.useState)(``),[X,Z]=(0,S.useState)(30),Q=(0,S.useCallback)(async()=>{T(!0);try{let e={page:E,limit:25};M&&(e.search=M),H&&(e.action=H);let t=await y.get(`/system/audit-logs`,{params:e});_(t.data.data||[]),t.data.meta?.pagination&&(k(t.data.meta.pagination.total),j(t.data.meta.pagination.totalPages))}catch{f.error(`Failed to fetch audit logs`)}finally{setTimeout(()=>T(!1),300)}},[E,M,H]),$=(0,S.useCallback)(async()=>{try{let e=await y.get(`/system/audit-logs/stats`);e.data.data&&L(e.data.data)}catch{}},[]);(0,S.useEffect)(()=>{Q(),$()},[Q,$]);let ee=()=>{D(1),Q()},te=async()=>{F(!0);try{let e=await y.get(`/system/audit-logs`,{params:{limit:500}}),t=new Blob([JSON.stringify(e.data.data,null,2)],{type:`application/json`}),n=window.URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.setAttribute(`download`,`ZENITH_AUDIT_${new Date().toISOString().replace(/[:.]/g,`-`)}.json`),document.body.appendChild(r),r.click(),r.remove(),window.URL.revokeObjectURL(n),f.success(`Report exported`)}catch{f.error(`Export failed`)}finally{F(!1)}},ne=()=>{q(Math.floor(1e5+Math.random()*9e5).toString()),Y(``),Z(30),G(!0)},re=()=>{if(J!==K){f.error(`Authorization code does not match`);return}G(!1),z(!0);let e=new Date(Date.now()-X*24*60*60*1e3).toISOString();f.promise(y.post(`/system/audit-logs/purge`,{before:e}),{loading:`Purging audit logs...`,success:e=>(Q(),$(),e.data?.data?.message||`Purged ${e.data?.data?.deleted||0} audit log entries`),error:`Purge failed`}).finally(()=>z(!1))},ie=e=>e?.toUpperCase()||`UNKNOWN`,ae=e=>{let t=e?.toUpperCase();return t===`CREATE`?`bg-emerald-50 text-emerald-600 dark:bg-emerald-500/10 dark:text-emerald-400 border-emerald-200 dark:border-emerald-500/20`:t===`UPDATE`?`bg-blue-50 text-blue-600 dark:bg-blue-500/10 dark:text-blue-400 border-blue-200 dark:border-blue-500/20`:t===`DELETE`?`bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400 border-red-200 dark:border-red-500/20`:`bg-amber-50 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400 border-amber-200 dark:border-amber-500/20`},oe=e=>e.userName||e.userEmail||`System`;return(0,C.jsxs)(`div`,{className:`flex flex-col h-[calc(100vh-64px)] overflow-hidden`,children:[(0,C.jsx)(x,{title:`Audit Logs`,description:`System History`,icon:(0,C.jsx)(r,{size:24}),backLink:{to:`/`,label:`Dashboard`},actions:(0,C.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,C.jsxs)(`div`,{className:b(`px-6 py-2 border rounded-lg flex items-center gap-8 shadow-sm transition-all`,`bg-z-panel border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex flex-col items-end`,children:[(0,C.jsx)(`span`,{className:`text-sm font-semibold text-z-muted opacity-60`,children:`Total Logs`}),(0,C.jsx)(`span`,{className:`text-xl font-semibold leading-none text-z-secondary `,children:O.toLocaleString()})]}),I&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`div`,{className:b(`w-px h-8`,e===`dark`?`bg-z-hover`:`bg-[var(--z-bg-hover)]`)}),(0,C.jsxs)(`div`,{className:`flex flex-col items-end`,children:[(0,C.jsx)(`span`,{className:`text-sm font-semibold text-z-muted opacity-60`,children:`Failed`}),(0,C.jsx)(`span`,{className:`text-xl font-semibold leading-none text-red-500`,children:I.failed})]}),(0,C.jsx)(`div`,{className:b(`w-px h-8`,e===`dark`?`bg-z-hover`:`bg-[var(--z-bg-hover)]`)}),(0,C.jsxs)(`div`,{className:`flex flex-col items-end`,children:[(0,C.jsx)(`span`,{className:`text-sm font-semibold text-z-muted opacity-60`,children:`Status`}),(0,C.jsx)(`span`,{className:`text-xs font-semibold text-z-secondary leading-none`,children:`Stable`})]})]})]}),(0,C.jsx)(`button`,{onClick:()=>{D(1),Q()},className:b(`w-10 h-10 border rounded-lg flex items-center justify-center transition-all hover:scale-105 active:scale-95 shadow-sm`,e===`dark`?`bg-z-panel border-z-border text-z-muted hover:border-z-border`:`bg-z-panel border-z-border text-z-muted hover:border-[var(--z-border-strong)]`),children:(0,C.jsx)(o,{size:20,className:w?`animate-spin`:``})})]})}),(0,C.jsx)(`div`,{className:b(`flex-1 overflow-y-auto p-10 space-y-6 transition-colors duration-500`,e===`dark`?`bg-app text-z-primary`:`bg-[#fafafa] text-z-primary`),children:(0,C.jsxs)(`div`,{className:b(`flex flex-col border rounded-xl shadow-sm transition-all overflow-hidden`,`bg-z-panel border-z-border`),children:[(0,C.jsxs)(`div`,{className:b(`px-8 py-5 border-b flex items-center justify-between gap-6 transition-colors`,`border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-4 flex-1`,children:[(0,C.jsxs)(`div`,{className:b(`flex items-center gap-3 border px-4 py-2 rounded-md w-full max-w-md shadow-sm transition-all group relative overflow-hidden`,e===`dark`?`bg-[#1c1c1c] border-z-border focus-within:border-z-accent`:`bg-z-panel border-[var(--z-border-strong)] focus-within:border-z-accent`),children:[(0,C.jsx)(a,{size:16,className:`text-z-secondary group-focus-within:text-z-secondary transition-colors`}),(0,C.jsx)(`input`,{type:`text`,value:M,onChange:e=>N(e.target.value),onKeyDown:e=>e.key===`Enter`&&ee(),placeholder:`Search by email, name, collection...`,className:`bg-transparent border-none outline-none text-sm w-full placeholder:text-z-muted dark:placeholder:text-z-secondary`})]}),(0,C.jsxs)(`select`,{value:H,onChange:e=>{U(e.target.value),D(1)},className:b(`px-4 py-2 border rounded-md text-sm outline-none transition-all shadow-sm`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-primary focus:border-z-accent`:`bg-z-panel border-[var(--z-border-strong)] text-z-primary focus:border-z-accent`),children:[(0,C.jsx)(`option`,{value:``,children:`All Actions`}),(0,C.jsx)(`option`,{value:`create`,children:`Create`}),(0,C.jsx)(`option`,{value:`update`,children:`Update`}),(0,C.jsx)(`option`,{value:`delete`,children:`Delete`}),(0,C.jsx)(`option`,{value:`publish`,children:`Publish`}),(0,C.jsx)(`option`,{value:`unpublish`,children:`Unpublish`}),(0,C.jsx)(`option`,{value:`login`,children:`Login`})]})]}),(0,C.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,C.jsxs)(`button`,{onClick:ne,disabled:R,className:b(`flex items-center gap-2 px-4 py-2 border rounded-md text-sm font-medium transition-all hover:bg-red-50 hover:text-red-600 hover:border-red-200 dark:hover:bg-red-500/10 dark:hover:text-red-400 dark:hover:border-red-500/20`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-muted`:`bg-z-panel border-[var(--z-border-strong)] text-z-secondary`),children:[(0,C.jsx)(t,{size:14}),`Purge`]}),(0,C.jsxs)(`button`,{onClick:te,disabled:P,className:b(`flex items-center gap-2 px-5 py-2 rounded-md font-medium text-sm transition-all shadow-sm active:scale-95`,e===`dark`?`bg-z-panel text-z-primary hover:bg-[var(--z-border)]`:`bg-z-accent text-z-primary hover:brightness-110`),children:[P?(0,C.jsx)(o,{className:`animate-spin`,size:14}):(0,C.jsx)(l,{size:14}),`Export`]})]})]}),(0,C.jsx)(`div`,{className:`overflow-x-auto`,children:(0,C.jsx)(`div`,{className:`overflow-x-auto min-w-full pb-4`,children:(0,C.jsxs)(`table`,{className:`w-full border-collapse`,children:[(0,C.jsx)(`thead`,{children:(0,C.jsxs)(`tr`,{className:b(`border-b text-left`,e===`dark`?`border-z-border bg-[#1c1c1c]`:`border-z-border bg-[var(--z-bg-input)]`),children:[(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Operator`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Action`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Collection`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`Status`}),(0,C.jsx)(`th`,{className:`px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted text-right`,children:`Timestamp`})]})}),(0,C.jsx)(`tbody`,{className:b(`divide-y`,`divide-z-border`),children:w?(0,C.jsx)(`tr`,{children:(0,C.jsx)(`td`,{colSpan:5,className:`py-20 text-center`,children:(0,C.jsx)(c,{size:24,className:`animate-spin text-z-secondary mx-auto opacity-40`})})}):g.length===0?(0,C.jsx)(`tr`,{children:(0,C.jsx)(`td`,{colSpan:5,className:`py-20 text-center`,children:(0,C.jsx)(`div`,{className:`text-z-secondary text-sm font-bold`,children:`No audit logs found`})})}):g.map(t=>(0,C.jsxs)(m.tr,{initial:{opacity:0},animate:{opacity:1},onClick:()=>V(B===(t._id||t.id)?null:t._id||t.id),className:`hover:bg-z-border/[0.02] transition-colors cursor-pointer group`,children:[(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,C.jsx)(`div`,{className:b(`w-8 h-8 rounded-full border flex items-center justify-center flex-shrink-0`,e===`dark`?`bg-[#2c2c2c] border-z-border text-z-secondary`:`bg-[var(--z-bg-hover)] border-z-border text-z-secondary`),children:(0,C.jsx)(n,{size:14})}),(0,C.jsxs)(`div`,{className:`flex flex-col`,children:[(0,C.jsx)(`span`,{className:b(`text-sm font-semibold leading-none`,`text-z-primary`),children:oe(t)}),(0,C.jsx)(`span`,{className:`text-xs text-z-muted mt-1`,children:t.userId?`ID: ${t.userId.slice(-8).toUpperCase()}`:`SYSTEM`})]})]})}),(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsxs)(`div`,{className:b(`px-2.5 py-1 rounded-md text-xs font-semibold inline-flex items-center gap-1.5 border`,ae(t.action)),children:[(0,C.jsx)(h,{size:10,fill:`currentColor`}),ie(t.action)]})}),(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsxs)(`div`,{className:`flex flex-col`,children:[(0,C.jsx)(`span`,{className:b(`text-sm font-medium leading-none`,`text-z-primary`),children:t.collectionName||`SYSTEM`}),t.documentId&&(0,C.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1 text-z-muted`,children:[(0,C.jsx)(u,{size:10}),(0,C.jsxs)(`span`,{className:`text-xs font-mono`,children:[`DOC_`,t.documentId.slice(-12).toUpperCase()]})]})]})}),(0,C.jsx)(`td`,{className:`px-6 py-4`,children:(0,C.jsx)(`span`,{className:b(`text-sm font-medium`,t.status===`failed`?`text-red-500`:`text-emerald-600 dark:text-emerald-400`),children:t.status===`failed`?`Failed`:`Success`})}),(0,C.jsx)(`td`,{className:`px-6 py-4 text-right`,children:(0,C.jsxs)(`div`,{className:`flex flex-col items-end gap-1`,children:[(0,C.jsx)(`span`,{className:b(`text-sm font-medium leading-none`,e===`dark`?`text-z-secondary`:`text-z-primary`),children:t.timestamp?new Date(t.timestamp).toLocaleDateString():`-`}),(0,C.jsx)(`span`,{className:`text-xs text-z-muted leading-none`,children:t.timestamp?new Date(t.timestamp).toLocaleTimeString():`-`})]})})]},t._id||t.id))})]})})}),B&&(()=>{let t=g.find(e=>(e._id||e.id)===B);return t?(0,C.jsxs)(`div`,{className:b(`px-8 py-6 border-t transition-colors`,e===`dark`?`bg-[#151515] border-z-border`:`bg-[#fafafa] border-z-border`),children:[(0,C.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 text-sm font-mono`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`IP Address`}),(0,C.jsx)(`div`,{className:`text-sm font-medium`,children:t.ip||`N/A`})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`User Agent`}),(0,C.jsx)(`div`,{className:`text-sm font-medium truncate`,title:t.userAgent,children:t.userAgent||`N/A`})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Resource`}),(0,C.jsx)(`div`,{className:`text-sm font-medium truncate`,title:t.resource,children:t.resource||`N/A`})]}),t.siteId&&(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Site ID`}),(0,C.jsx)(`div`,{className:`text-sm font-medium`,children:t.siteId})]}),t.hash&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Audit Hash`}),(0,C.jsxs)(`div`,{className:`text-sm font-medium truncate font-mono`,title:t.hash,children:[t.hash.slice(0,24),`...`]})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-1`,children:`Prev Hash`}),(0,C.jsx)(`div`,{className:`text-sm font-medium truncate font-mono`,title:t.previousHash,children:t.previousHash?t.previousHash.slice(0,24)+`...`:`GENESIS`})]})]})]}),t.changes&&(0,C.jsxs)(`div`,{className:`mt-4`,children:[(0,C.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted mb-2`,children:`Changes`}),(0,C.jsx)(`pre`,{className:b(`p-4 rounded-md text-xs font-mono max-h-48 overflow-auto border shadow-sm`,e===`dark`?`bg-[#111111] border-z-border text-z-secondary`:`bg-z-panel border-z-border text-z-primary`),children:JSON.stringify(t.changes,null,2)})]})]}):null})(),(0,C.jsxs)(`div`,{className:b(`px-8 py-5 border-t flex items-center justify-between transition-colors rounded-b-xl`,e===`dark`?`bg-[#1c1c1c] border-z-border`:`bg-[var(--z-bg-input)] border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,C.jsx)(s,{size:14,className:`text-z-muted`}),(0,C.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted`,children:`SECURE AUDIT TRAIL`}),I?.byAction&&Object.keys(I.byAction).length>0&&(0,C.jsx)(`div`,{className:`flex items-center gap-3 ml-4`,children:Object.entries(I.byAction).map(([e,t])=>(0,C.jsxs)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-z-muted`,children:[e,`:`,t]},e))})]}),(0,C.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,C.jsxs)(`span`,{className:`text-xs font-semibold text-z-muted tracking-wider uppercase mr-2`,children:[`Page `,E,` of `,A]}),(0,C.jsx)(`button`,{disabled:E===1,onClick:()=>D(E-1),className:b(`w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20`,e===`dark`?`bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]`:`bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]`),children:(0,C.jsx)(p,{size:16})}),(0,C.jsx)(`div`,{className:b(`px-3 py-1 rounded-md text-sm font-medium border shadow-sm`,e===`dark`?`bg-z-panel text-z-primary border-z-border`:`bg-z-accent border-z-border text-z-primary`),children:E}),(0,C.jsx)(`button`,{disabled:E>=A,onClick:()=>D(E+1),className:b(`w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20`,e===`dark`?`bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]`:`bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]`),children:(0,C.jsx)(d,{size:16})})]})]})]})}),W&&(0,C.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm`,children:(0,C.jsxs)(m.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:b(`w-full max-w-md rounded-xl p-8 shadow-2xl border`,`bg-z-panel border-z-border`),children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-3 text-red-500 mb-4`,children:[(0,C.jsx)(i,{size:24}),(0,C.jsx)(`h2`,{className:`text-xl font-bold text-z-primary tracking-tight`,children:`Purge Audit Logs`})]}),(0,C.jsxs)(`p`,{className:b(`text-sm mb-6 leading-relaxed`,`text-z-muted`),children:[`This action is `,(0,C.jsx)(`span`,{className:`font-bold text-red-500`,children:`irreversible`}),`. It will permanently delete audit logs matching your criteria.`]}),(0,C.jsxs)(`div`,{className:`space-y-5 mb-8`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`label`,{className:b(`block text-xs font-semibold uppercase tracking-wider mb-2`,`text-z-secondary`),children:`Logs older than (days):`}),(0,C.jsx)(`input`,{type:`number`,min:`0`,value:X,onChange:e=>Z(parseInt(e.target.value)||0),className:b(`w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50`:`bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50`)}),(0,C.jsx)(`p`,{className:`text-[10px] text-z-muted mt-1.5 font-medium uppercase tracking-wide`,children:`Set to 0 to delete all logs.`})]}),(0,C.jsxs)(`div`,{children:[(0,C.jsxs)(`label`,{className:b(`block text-xs font-semibold uppercase tracking-wider mb-2`,`text-z-secondary`),children:[`Authorization Code: `,(0,C.jsx)(`span`,{className:`text-red-400 font-mono select-all font-bold tracking-widest`,children:K})]}),(0,C.jsx)(`input`,{type:`text`,value:J,onChange:e=>Y(e.target.value),placeholder:`Enter the 6-digit code above`,className:b(`w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all font-mono tracking-widest`,e===`dark`?`bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50`:`bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50`)})]})]}),(0,C.jsxs)(`div`,{className:`flex justify-end gap-3 pt-2`,children:[(0,C.jsx)(`button`,{onClick:()=>G(!1),className:b(`px-5 py-2.5 text-sm font-semibold border rounded-md transition-all`,e===`dark`?`border-z-border bg-z-panel text-z-muted hover:text-z-primary hover:brightness-110`:`border-z-border bg-z-panel text-z-secondary hover:bg-[var(--z-bg-input)]`),children:`Cancel`}),(0,C.jsx)(`button`,{onClick:re,disabled:J!==K,className:`px-5 py-2.5 text-sm font-semibold bg-red-500/10 text-red-500 border border-red-500/20 rounded-md hover:bg-red-500 hover:text-z-primary transition-all duration-300 disabled:opacity-30 disabled:cursor-not-allowed shadow-sm`,children:`Confirm Purge`})]})]})})]})};export{w as default};
@@ -1 +1 @@
1
- {"version":3,"file":"AuditLogPage-8xYlRl1I.js","names":[],"sources":["../../src/pages/AuditLogPage.tsx"],"sourcesContent":["import React, { useEffect, useState, useCallback } from 'react'\nimport {\n History,\n Search,\n Download,\n RefreshCw,\n KeyRound,\n Zap,\n ArrowRight,\n Cpu,\n ChevronLeft,\n ChevronRight,\n Loader2,\n Trash2,\n Shield,\n Globe,\n AlertTriangle,\n} from 'lucide-react'\nimport api from '../lib/api'\nimport { cn } from '../lib/utils'\nimport { motion } from 'framer-motion'\nimport { useTheme } from '../context/ThemeContext'\nimport toast from 'react-hot-toast'\nimport { PageHeader } from '../components/ui/PageHeader'\nimport { Card } from '../components/ui/Card'\nimport { Badge } from '../components/ui/Badge'\n\ninterface AuditLogEntry {\n _id?: string\n id?: string\n userEmail?: string\n userName?: string\n userId?: string\n action: string\n collectionName?: string\n documentId?: string\n changes?: any\n ip?: string\n userAgent?: string\n timestamp: string\n status?: string\n resource?: string\n siteId?: string\n hash?: string\n previousHash?: string\n}\n\ninterface AuditStats {\n total: number\n failed: number\n success: number\n byAction: Record<string, number>\n}\n\nconst AuditLogPage: React.FC = () => {\n const { theme } = useTheme()\n const [logs, setLogs] = useState<AuditLogEntry[]>([])\n const [loading, setLoading] = useState(true)\n const [page, setPage] = useState(1)\n const [total, setTotal] = useState(0)\n const [totalPages, setTotalPages] = useState(1)\n const [searchQuery, setSearchQuery] = useState('')\n const [exporting, setExporting] = useState(false)\n const [stats, setStats] = useState<AuditStats | null>(null)\n const [purging, setPurging] = useState(false)\n const [showDetails, setShowDetails] = useState<string | null>(null)\n const [filterAction, setFilterAction] = useState('')\n const [showPurgeModal, setShowPurgeModal] = useState(false)\n const [purgeExpectedCode, setPurgeExpectedCode] = useState('')\n const [purgeInputCode, setPurgeInputCode] = useState('')\n const [purgeDays, setPurgeDays] = useState(30)\n\n const fetchLogs = useCallback(async () => {\n setLoading(true)\n try {\n const params: any = { page, limit: 25 }\n if (searchQuery) params.search = searchQuery\n if (filterAction) params.action = filterAction\n const res = await api.get('/system/audit-logs', { params })\n setLogs(res.data.data || [])\n if (res.data.meta?.pagination) {\n setTotal(res.data.meta.pagination.total)\n setTotalPages(res.data.meta.pagination.totalPages)\n }\n } catch {\n toast.error('Failed to fetch audit logs')\n } finally {\n setTimeout(() => setLoading(false), 300)\n }\n }, [page, searchQuery, filterAction])\n\n const fetchStats = useCallback(async () => {\n try {\n const res = await api.get('/system/audit-logs/stats')\n if (res.data.data) setStats(res.data.data)\n } catch {\n // stats are non-critical\n }\n }, [])\n\n useEffect(() => {\n fetchLogs()\n fetchStats()\n }, [fetchLogs, fetchStats])\n\n const handleSearch = () => {\n setPage(1)\n fetchLogs()\n }\n\n const handleExport = async () => {\n setExporting(true)\n try {\n const res = await api.get('/system/audit-logs', { params: { limit: 500 } })\n const blob = new Blob([JSON.stringify(res.data.data, null, 2)], { type: 'application/json' })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.setAttribute(\n 'download',\n `ZENITH_AUDIT_${new Date().toISOString().replace(/[:.]/g, '-')}.json`\n )\n document.body.appendChild(link)\n link.click()\n link.remove()\n window.URL.revokeObjectURL(url)\n toast.success('Report exported')\n } catch {\n toast.error('Export failed')\n } finally {\n setExporting(false)\n }\n }\n\n const handlePurgeClick = () => {\n setPurgeExpectedCode(Math.floor(100000 + Math.random() * 900000).toString())\n setPurgeInputCode('')\n setPurgeDays(30)\n setShowPurgeModal(true)\n }\n\n const executePurge = () => {\n if (purgeInputCode !== purgeExpectedCode) {\n toast.error('Authorization code does not match')\n return\n }\n \n setShowPurgeModal(false)\n setPurging(true)\n const before = new Date(Date.now() - purgeDays * 24 * 60 * 60 * 1000).toISOString()\n toast\n .promise(api.post('/system/audit-logs/purge', { before }), {\n loading: `Purging audit logs...`,\n success: (res: any) => {\n fetchLogs()\n fetchStats()\n return res.data?.data?.message || `Purged ${res.data?.data?.deleted || 0} audit log entries`\n },\n error: 'Purge failed',\n })\n .finally(() => setPurging(false))\n }\n\n const formatAction = (action: string): string => action?.toUpperCase() || 'UNKNOWN'\n\n const getActionColor = (action: string) => {\n const upper = action?.toUpperCase()\n if (upper === 'CREATE')\n return 'bg-emerald-50 text-emerald-600 dark:bg-emerald-500/10 dark:text-emerald-400 border-emerald-200 dark:border-emerald-500/20'\n if (upper === 'UPDATE')\n return 'bg-blue-50 text-blue-600 dark:bg-blue-500/10 dark:text-blue-400 border-blue-200 dark:border-blue-500/20'\n if (upper === 'DELETE') \n return 'bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400 border-red-200 dark:border-red-500/20'\n return 'bg-amber-50 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400 border-amber-200 dark:border-amber-500/20'\n }\n\n const displayName = (log: AuditLogEntry) => log.userName || log.userEmail || 'System'\n\n return (\n <div className=\"flex flex-col h-[calc(100vh-64px)] overflow-hidden\">\n {/* Header */}\n <PageHeader\n title=\"Audit Logs\"\n description=\"System History\"\n icon={<History size={24} />}\n backLink={{ to: '/', label: 'Dashboard' }}\n actions={\n <div className=\"flex items-center gap-4\">\n <div\n className={cn(\n 'px-6 py-2 border rounded-lg flex items-center gap-8 shadow-sm transition-all',\n theme === 'dark'\n ? 'bg-z-panel border-z-border'\n : 'bg-z-panel border-z-border'\n )}\n >\n <div className=\"flex flex-col items-end\">\n <span className=\"text-sm font-semibold text-z-muted opacity-60\">\n Total Logs\n </span>\n <span className=\"text-xl font-semibold leading-none text-z-secondary \">\n {total.toLocaleString()}\n </span>\n </div>\n {stats && (\n <>\n <div\n className={cn('w-px h-8', theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-hover)]')}\n />\n <div className=\"flex flex-col items-end\">\n <span className=\"text-sm font-semibold text-z-muted opacity-60\">\n Failed\n </span>\n <span className=\"text-xl font-semibold leading-none text-red-500\">\n {stats.failed}\n </span>\n </div>\n <div\n className={cn('w-px h-8', theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-hover)]')}\n />\n <div className=\"flex flex-col items-end\">\n <span className=\"text-sm font-semibold text-z-muted opacity-60\">\n Status\n </span>\n <span className=\"text-xs font-semibold text-z-secondary leading-none\">\n Stable\n </span>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n setPage(1)\n fetchLogs()\n }}\n className={cn(\n 'w-10 h-10 border rounded-lg flex items-center justify-center transition-all hover:scale-105 active:scale-95 shadow-sm',\n theme === 'dark'\n ? 'bg-z-panel border-z-border text-z-muted hover:border-z-border'\n : 'bg-z-panel border-z-border text-z-muted hover:border-[var(--z-border-strong)]'\n )}\n >\n <RefreshCw size={20} className={loading ? 'animate-spin' : ''} />\n </button>\n </div>\n }\n />\n\n <div\n className={cn(\n 'flex-1 overflow-y-auto p-10 space-y-6 transition-colors duration-500',\n theme === 'dark' ? 'bg-app text-z-primary' : 'bg-[#fafafa] text-z-primary'\n )}\n >\n {/* Table Card */}\n <div\n className={cn(\n 'flex flex-col border rounded-xl shadow-sm transition-all overflow-hidden',\n theme === 'dark'\n ? 'bg-z-panel border-z-border'\n : 'bg-z-panel border-z-border'\n )}\n >\n {/* Control Bar */}\n <div\n className={cn(\n 'px-8 py-5 border-b flex items-center justify-between gap-6 transition-colors',\n 'border-z-border'\n )}\n >\n <div className=\"flex items-center gap-4 flex-1\">\n <div\n className={cn(\n 'flex items-center gap-3 border px-4 py-2 rounded-md w-full max-w-md shadow-sm transition-all group relative overflow-hidden',\n theme === 'dark'\n ? 'bg-[#1c1c1c] border-z-border focus-within:border-z-accent'\n : 'bg-z-panel border-[var(--z-border-strong)] focus-within:border-z-accent'\n )}\n >\n <Search\n size={16}\n className=\"text-z-secondary group-focus-within:text-z-secondary transition-colors\"\n />\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleSearch()}\n placeholder=\"Search by email, name, collection...\"\n className=\"bg-transparent border-none outline-none text-sm w-full placeholder:text-z-muted dark:placeholder:text-z-secondary\"\n />\n </div>\n\n <select\n value={filterAction}\n onChange={(e) => {\n setFilterAction(e.target.value)\n setPage(1)\n }}\n className={cn(\n 'px-4 py-2 border rounded-md text-sm outline-none transition-all shadow-sm',\n theme === 'dark'\n ? 'bg-[#1c1c1c] border-z-border text-z-primary focus:border-z-accent'\n : 'bg-z-panel border-[var(--z-border-strong)] text-z-primary focus:border-z-accent'\n )}\n >\n <option value=\"\">All Actions</option>\n <option value=\"create\">Create</option>\n <option value=\"update\">Update</option>\n <option value=\"delete\">Delete</option>\n <option value=\"publish\">Publish</option>\n <option value=\"unpublish\">Unpublish</option>\n <option value=\"login\">Login</option>\n </select>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <button\n onClick={handlePurgeClick}\n disabled={purging}\n className={cn(\n 'flex items-center gap-2 px-4 py-2 border rounded-md text-sm font-medium transition-all hover:bg-red-50 hover:text-red-600 hover:border-red-200 dark:hover:bg-red-500/10 dark:hover:text-red-400 dark:hover:border-red-500/20',\n theme === 'dark'\n ? 'bg-[#1c1c1c] border-z-border text-z-muted'\n : 'bg-z-panel border-[var(--z-border-strong)] text-z-secondary'\n )}\n >\n <Trash2 size={14} />\n Purge\n </button>\n <button\n onClick={handleExport}\n disabled={exporting}\n className={cn(\n 'flex items-center gap-2 px-5 py-2 rounded-md font-medium text-sm transition-all shadow-sm active:scale-95',\n theme === 'dark'\n ? 'bg-z-panel text-z-primary hover:bg-[var(--z-border)]'\n : 'bg-z-accent text-z-primary hover:brightness-110'\n )}\n >\n {exporting ? (\n <RefreshCw className=\"animate-spin\" size={14} />\n ) : (\n <Download size={14} />\n )}\n Export\n </button>\n </div>\n </div>\n\n {/* Log Table */}\n <div className=\"overflow-x-auto\">\n <div className=\"overflow-x-auto min-w-full pb-4\">\n <table className=\"w-full border-collapse\">\n <thead>\n <tr\n className={cn(\n 'border-b text-left',\n theme === 'dark'\n ? 'border-z-border bg-[#1c1c1c]'\n : 'border-z-border bg-[var(--z-bg-input)]'\n )}\n >\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Operator\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Action\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Collection\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Status\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted text-right\">\n Timestamp\n </th>\n </tr>\n </thead>\n <tbody\n className={cn(\n 'divide-y',\n theme === 'dark' ? 'divide-z-border' : 'divide-z-border'\n )}\n >\n {loading ? (\n <tr>\n <td colSpan={5} className=\"py-20 text-center\">\n <Loader2\n size={24}\n className=\"animate-spin text-z-secondary mx-auto opacity-40\"\n />\n </td>\n </tr>\n ) : logs.length === 0 ? (\n <tr>\n <td colSpan={5} className=\"py-20 text-center\">\n <div className=\"text-z-secondary text-sm font-bold\">\n No audit logs found\n </div>\n </td>\n </tr>\n ) : (\n logs.map((log) => (\n <motion.tr\n key={log._id || log.id}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n onClick={() =>\n setShowDetails(\n showDetails === (log._id || log.id) ? null : log._id || log.id\n )\n }\n className=\"hover:bg-z-border/[0.02] transition-colors cursor-pointer group\"\n >\n <td className=\"px-6 py-4\">\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n 'w-8 h-8 rounded-full border flex items-center justify-center flex-shrink-0',\n theme === 'dark'\n ? 'bg-[#2c2c2c] border-z-border text-z-secondary'\n : 'bg-[var(--z-bg-hover)] border-z-border text-z-secondary'\n )}\n >\n <KeyRound size={14} />\n </div>\n <div className=\"flex flex-col\">\n <span className={cn(\"text-sm font-semibold leading-none\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")}>\n {displayName(log)}\n </span>\n <span className=\"text-xs text-z-muted mt-1\">\n {log.userId\n ? `ID: ${log.userId.slice(-8).toUpperCase()}`\n : 'SYSTEM'}\n </span>\n </div>\n </div>\n </td>\n <td className=\"px-6 py-4\">\n <div\n className={cn(\n 'px-2.5 py-1 rounded-md text-xs font-semibold inline-flex items-center gap-1.5 border',\n getActionColor(log.action)\n )}\n >\n <Zap size={10} fill=\"currentColor\" />\n {formatAction(log.action)}\n </div>\n </td>\n <td className=\"px-6 py-4\">\n <div className=\"flex flex-col\">\n <span className={cn(\"text-sm font-medium leading-none\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")}>\n {log.collectionName || 'SYSTEM'}\n </span>\n {log.documentId && (\n <div className=\"flex items-center gap-1.5 mt-1 text-z-muted\">\n <ArrowRight size={10} />\n <span className=\"text-xs font-mono\">\n DOC_{log.documentId.slice(-12).toUpperCase()}\n </span>\n </div>\n )}\n </div>\n </td>\n <td className=\"px-6 py-4\">\n <span\n className={cn(\n 'text-sm font-medium',\n log.status === 'failed'\n ? 'text-red-500'\n : 'text-emerald-600 dark:text-emerald-400'\n )}\n >\n {log.status === 'failed' ? 'Failed' : 'Success'}\n </span>\n </td>\n <td className=\"px-6 py-4 text-right\">\n <div className=\"flex flex-col items-end gap-1\">\n <span className={cn(\"text-sm font-medium leading-none\", theme === 'dark' ? \"text-z-secondary\" : \"text-z-primary\")}>\n {log.timestamp ? new Date(log.timestamp).toLocaleDateString() : '-'}\n </span>\n <span className=\"text-xs text-z-muted leading-none\">\n {log.timestamp ? new Date(log.timestamp).toLocaleTimeString() : '-'}\n </span>\n </div>\n </td>\n </motion.tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Detail Expand */}\n {showDetails &&\n (() => {\n const log = logs.find((l) => (l._id || l.id) === showDetails)\n if (!log) return null\n return (\n <div\n className={cn(\n 'px-8 py-6 border-t transition-colors',\n theme === 'dark'\n ? 'bg-[#151515] border-z-border'\n : 'bg-[#fafafa] border-z-border'\n )}\n >\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 text-sm font-mono\">\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n IP Address\n </div>\n <div className=\"text-sm font-medium\">{log.ip || 'N/A'}</div>\n </div>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n User Agent\n </div>\n <div className=\"text-sm font-medium truncate\" title={log.userAgent}>\n {log.userAgent || 'N/A'}\n </div>\n </div>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Resource\n </div>\n <div className=\"text-sm font-medium truncate\" title={log.resource}>\n {log.resource || 'N/A'}\n </div>\n </div>\n {log.siteId && (\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Site ID\n </div>\n <div className=\"text-sm font-medium\">{log.siteId}</div>\n </div>\n )}\n {log.hash && (\n <>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Audit Hash\n </div>\n <div className=\"text-sm font-medium truncate font-mono\" title={log.hash}>\n {log.hash.slice(0, 24)}...\n </div>\n </div>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Prev Hash\n </div>\n <div className=\"text-sm font-medium truncate font-mono\" title={log.previousHash}>\n {log.previousHash ? log.previousHash.slice(0, 24) + '...' : 'GENESIS'}\n </div>\n </div>\n </>\n )}\n </div>\n {log.changes && (\n <div className=\"mt-4\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-2\">\n Changes\n </div>\n <pre\n className={cn(\n 'p-4 rounded-md text-xs font-mono max-h-48 overflow-auto border shadow-sm',\n theme === 'dark'\n ? 'bg-[#111111] border-z-border text-z-secondary'\n : 'bg-z-panel border-z-border text-z-primary'\n )}\n >\n {JSON.stringify(log.changes, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )\n })()}\n\n {/* Footer */}\n <div\n className={cn(\n 'px-8 py-5 border-t flex items-center justify-between transition-colors rounded-b-xl',\n theme === 'dark' ? 'bg-[#1c1c1c] border-z-border' : 'bg-[var(--z-bg-input)] border-z-border'\n )}\n >\n <div className=\"flex items-center gap-4\">\n <Cpu size={14} className=\"text-z-muted\" />\n <span className=\"text-xs font-semibold uppercase tracking-wider text-z-muted\">\n SECURE AUDIT TRAIL\n </span>\n {stats?.byAction && Object.keys(stats.byAction).length > 0 && (\n <div className=\"flex items-center gap-3 ml-4\">\n {Object.entries(stats.byAction).map(([action, count]) => (\n <span\n key={action}\n className=\"text-xs font-semibold uppercase tracking-wider text-z-muted\"\n >\n {action}:{count}\n </span>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs font-semibold text-z-muted tracking-wider uppercase mr-2\">\n Page {page} of {totalPages}\n </span>\n <button\n disabled={page === 1}\n onClick={() => setPage(page - 1)}\n className={cn(\n 'w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20',\n theme === 'dark'\n ? 'bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]'\n : 'bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]'\n )}\n >\n <ChevronLeft size={16} />\n </button>\n\n <div\n className={cn(\n 'px-3 py-1 rounded-md text-sm font-medium border shadow-sm',\n theme === 'dark'\n ? 'bg-z-panel text-z-primary border-z-border'\n : 'bg-z-accent border-z-border text-z-primary'\n )}\n >\n {page}\n </div>\n\n <button\n disabled={page >= totalPages}\n onClick={() => setPage(page + 1)}\n className={cn(\n 'w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20',\n theme === 'dark'\n ? 'bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]'\n : 'bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]'\n )}\n >\n <ChevronRight size={16} />\n </button>\n </div>\n </div>\n </div>\n </div>\n\n {/* Custom Purge Modal */}\n {showPurgeModal && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm\">\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n className={cn(\n \"w-full max-w-md rounded-xl p-8 shadow-2xl border\",\n theme === 'dark' ? \"bg-z-panel border-z-border\" : \"bg-z-panel border-z-border\"\n )}\n >\n <div className=\"flex items-center gap-3 text-red-500 mb-4\">\n <AlertTriangle size={24} />\n <h2 className=\"text-xl font-bold text-z-primary tracking-tight\">Purge Audit Logs</h2>\n </div>\n <p className={cn(\"text-sm mb-6 leading-relaxed\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n This action is <span className=\"font-bold text-red-500\">irreversible</span>. It will permanently delete audit logs matching your criteria.\n </p>\n \n <div className=\"space-y-5 mb-8\">\n <div>\n <label className={cn(\"block text-xs font-semibold uppercase tracking-wider mb-2\", theme === 'dark' ? \"text-z-secondary\" : \"text-z-secondary\")}>\n Logs older than (days):\n </label>\n <input\n type=\"number\"\n min=\"0\"\n value={purgeDays}\n onChange={(e) => setPurgeDays(parseInt(e.target.value) || 0)}\n className={cn(\n \"w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all\",\n theme === 'dark' \n ? \"bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50\" \n : \"bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50\"\n )}\n />\n <p className=\"text-[10px] text-z-muted mt-1.5 font-medium uppercase tracking-wide\">Set to 0 to delete all logs.</p>\n </div>\n \n <div>\n <label className={cn(\"block text-xs font-semibold uppercase tracking-wider mb-2\", theme === 'dark' ? \"text-z-secondary\" : \"text-z-secondary\")}>\n Authorization Code: <span className=\"text-red-400 font-mono select-all font-bold tracking-widest\">{purgeExpectedCode}</span>\n </label>\n <input\n type=\"text\"\n value={purgeInputCode}\n onChange={(e) => setPurgeInputCode(e.target.value)}\n placeholder=\"Enter the 6-digit code above\"\n className={cn(\n \"w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all font-mono tracking-widest\",\n theme === 'dark' \n ? \"bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50\" \n : \"bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50\"\n )}\n />\n </div>\n </div>\n \n <div className=\"flex justify-end gap-3 pt-2\">\n <button\n onClick={() => setShowPurgeModal(false)}\n className={cn(\n \"px-5 py-2.5 text-sm font-semibold border rounded-md transition-all\",\n theme === 'dark' \n ? \"border-z-border bg-z-panel text-z-muted hover:text-z-primary hover:brightness-110\" \n : \"border-z-border bg-z-panel text-z-secondary hover:bg-[var(--z-bg-input)]\"\n )}\n >\n Cancel\n </button>\n <button\n onClick={executePurge}\n disabled={purgeInputCode !== purgeExpectedCode}\n className=\"px-5 py-2.5 text-sm font-semibold bg-red-500/10 text-red-500 border border-red-500/20 rounded-md hover:bg-red-500 hover:text-z-primary transition-all duration-300 disabled:opacity-30 disabled:cursor-not-allowed shadow-sm\"\n >\n Confirm Purge\n </button>\n </div>\n </motion.div>\n </div>\n )}\n\n </div>\n )\n}\n\nexport default AuditLogPage\n"],"mappings":"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"}
1
+ {"version":3,"file":"AuditLogPage-CwULx1tr.js","names":[],"sources":["../../src/pages/AuditLogPage.tsx"],"sourcesContent":["import React, { useEffect, useState, useCallback } from 'react'\nimport {\n History,\n Search,\n Download,\n RefreshCw,\n KeyRound,\n Zap,\n ArrowRight,\n Cpu,\n ChevronLeft,\n ChevronRight,\n Loader2,\n Trash2,\n Shield,\n Globe,\n AlertTriangle,\n} from 'lucide-react'\nimport api from '../lib/api'\nimport { cn } from '../lib/utils'\nimport { motion } from 'framer-motion'\nimport { useTheme } from '../context/ThemeContext'\nimport toast from 'react-hot-toast'\nimport { PageHeader } from '../components/ui/PageHeader'\nimport { Card } from '../components/ui/Card'\nimport { Badge } from '../components/ui/Badge'\n\ninterface AuditLogEntry {\n _id?: string\n id?: string\n userEmail?: string\n userName?: string\n userId?: string\n action: string\n collectionName?: string\n documentId?: string\n changes?: any\n ip?: string\n userAgent?: string\n timestamp: string\n status?: string\n resource?: string\n siteId?: string\n hash?: string\n previousHash?: string\n}\n\ninterface AuditStats {\n total: number\n failed: number\n success: number\n byAction: Record<string, number>\n}\n\nconst AuditLogPage: React.FC = () => {\n const { theme } = useTheme()\n const [logs, setLogs] = useState<AuditLogEntry[]>([])\n const [loading, setLoading] = useState(true)\n const [page, setPage] = useState(1)\n const [total, setTotal] = useState(0)\n const [totalPages, setTotalPages] = useState(1)\n const [searchQuery, setSearchQuery] = useState('')\n const [exporting, setExporting] = useState(false)\n const [stats, setStats] = useState<AuditStats | null>(null)\n const [purging, setPurging] = useState(false)\n const [showDetails, setShowDetails] = useState<string | null>(null)\n const [filterAction, setFilterAction] = useState('')\n const [showPurgeModal, setShowPurgeModal] = useState(false)\n const [purgeExpectedCode, setPurgeExpectedCode] = useState('')\n const [purgeInputCode, setPurgeInputCode] = useState('')\n const [purgeDays, setPurgeDays] = useState(30)\n\n const fetchLogs = useCallback(async () => {\n setLoading(true)\n try {\n const params: any = { page, limit: 25 }\n if (searchQuery) params.search = searchQuery\n if (filterAction) params.action = filterAction\n const res = await api.get('/system/audit-logs', { params })\n setLogs(res.data.data || [])\n if (res.data.meta?.pagination) {\n setTotal(res.data.meta.pagination.total)\n setTotalPages(res.data.meta.pagination.totalPages)\n }\n } catch {\n toast.error('Failed to fetch audit logs')\n } finally {\n setTimeout(() => setLoading(false), 300)\n }\n }, [page, searchQuery, filterAction])\n\n const fetchStats = useCallback(async () => {\n try {\n const res = await api.get('/system/audit-logs/stats')\n if (res.data.data) setStats(res.data.data)\n } catch {\n // stats are non-critical\n }\n }, [])\n\n useEffect(() => {\n fetchLogs()\n fetchStats()\n }, [fetchLogs, fetchStats])\n\n const handleSearch = () => {\n setPage(1)\n fetchLogs()\n }\n\n const handleExport = async () => {\n setExporting(true)\n try {\n const res = await api.get('/system/audit-logs', { params: { limit: 500 } })\n const blob = new Blob([JSON.stringify(res.data.data, null, 2)], { type: 'application/json' })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.setAttribute(\n 'download',\n `ZENITH_AUDIT_${new Date().toISOString().replace(/[:.]/g, '-')}.json`\n )\n document.body.appendChild(link)\n link.click()\n link.remove()\n window.URL.revokeObjectURL(url)\n toast.success('Report exported')\n } catch {\n toast.error('Export failed')\n } finally {\n setExporting(false)\n }\n }\n\n const handlePurgeClick = () => {\n setPurgeExpectedCode(Math.floor(100000 + Math.random() * 900000).toString())\n setPurgeInputCode('')\n setPurgeDays(30)\n setShowPurgeModal(true)\n }\n\n const executePurge = () => {\n if (purgeInputCode !== purgeExpectedCode) {\n toast.error('Authorization code does not match')\n return\n }\n \n setShowPurgeModal(false)\n setPurging(true)\n const before = new Date(Date.now() - purgeDays * 24 * 60 * 60 * 1000).toISOString()\n toast\n .promise(api.post('/system/audit-logs/purge', { before }), {\n loading: `Purging audit logs...`,\n success: (res: any) => {\n fetchLogs()\n fetchStats()\n return res.data?.data?.message || `Purged ${res.data?.data?.deleted || 0} audit log entries`\n },\n error: 'Purge failed',\n })\n .finally(() => setPurging(false))\n }\n\n const formatAction = (action: string): string => action?.toUpperCase() || 'UNKNOWN'\n\n const getActionColor = (action: string) => {\n const upper = action?.toUpperCase()\n if (upper === 'CREATE')\n return 'bg-emerald-50 text-emerald-600 dark:bg-emerald-500/10 dark:text-emerald-400 border-emerald-200 dark:border-emerald-500/20'\n if (upper === 'UPDATE')\n return 'bg-blue-50 text-blue-600 dark:bg-blue-500/10 dark:text-blue-400 border-blue-200 dark:border-blue-500/20'\n if (upper === 'DELETE') \n return 'bg-red-50 text-red-600 dark:bg-red-500/10 dark:text-red-400 border-red-200 dark:border-red-500/20'\n return 'bg-amber-50 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400 border-amber-200 dark:border-amber-500/20'\n }\n\n const displayName = (log: AuditLogEntry) => log.userName || log.userEmail || 'System'\n\n return (\n <div className=\"flex flex-col h-[calc(100vh-64px)] overflow-hidden\">\n {/* Header */}\n <PageHeader\n title=\"Audit Logs\"\n description=\"System History\"\n icon={<History size={24} />}\n backLink={{ to: '/', label: 'Dashboard' }}\n actions={\n <div className=\"flex items-center gap-4\">\n <div\n className={cn(\n 'px-6 py-2 border rounded-lg flex items-center gap-8 shadow-sm transition-all',\n theme === 'dark'\n ? 'bg-z-panel border-z-border'\n : 'bg-z-panel border-z-border'\n )}\n >\n <div className=\"flex flex-col items-end\">\n <span className=\"text-sm font-semibold text-z-muted opacity-60\">\n Total Logs\n </span>\n <span className=\"text-xl font-semibold leading-none text-z-secondary \">\n {total.toLocaleString()}\n </span>\n </div>\n {stats && (\n <>\n <div\n className={cn('w-px h-8', theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-hover)]')}\n />\n <div className=\"flex flex-col items-end\">\n <span className=\"text-sm font-semibold text-z-muted opacity-60\">\n Failed\n </span>\n <span className=\"text-xl font-semibold leading-none text-red-500\">\n {stats.failed}\n </span>\n </div>\n <div\n className={cn('w-px h-8', theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-hover)]')}\n />\n <div className=\"flex flex-col items-end\">\n <span className=\"text-sm font-semibold text-z-muted opacity-60\">\n Status\n </span>\n <span className=\"text-xs font-semibold text-z-secondary leading-none\">\n Stable\n </span>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n setPage(1)\n fetchLogs()\n }}\n className={cn(\n 'w-10 h-10 border rounded-lg flex items-center justify-center transition-all hover:scale-105 active:scale-95 shadow-sm',\n theme === 'dark'\n ? 'bg-z-panel border-z-border text-z-muted hover:border-z-border'\n : 'bg-z-panel border-z-border text-z-muted hover:border-[var(--z-border-strong)]'\n )}\n >\n <RefreshCw size={20} className={loading ? 'animate-spin' : ''} />\n </button>\n </div>\n }\n />\n\n <div\n className={cn(\n 'flex-1 overflow-y-auto p-10 space-y-6 transition-colors duration-500',\n theme === 'dark' ? 'bg-app text-z-primary' : 'bg-[#fafafa] text-z-primary'\n )}\n >\n {/* Table Card */}\n <div\n className={cn(\n 'flex flex-col border rounded-xl shadow-sm transition-all overflow-hidden',\n theme === 'dark'\n ? 'bg-z-panel border-z-border'\n : 'bg-z-panel border-z-border'\n )}\n >\n {/* Control Bar */}\n <div\n className={cn(\n 'px-8 py-5 border-b flex items-center justify-between gap-6 transition-colors',\n 'border-z-border'\n )}\n >\n <div className=\"flex items-center gap-4 flex-1\">\n <div\n className={cn(\n 'flex items-center gap-3 border px-4 py-2 rounded-md w-full max-w-md shadow-sm transition-all group relative overflow-hidden',\n theme === 'dark'\n ? 'bg-[#1c1c1c] border-z-border focus-within:border-z-accent'\n : 'bg-z-panel border-[var(--z-border-strong)] focus-within:border-z-accent'\n )}\n >\n <Search\n size={16}\n className=\"text-z-secondary group-focus-within:text-z-secondary transition-colors\"\n />\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleSearch()}\n placeholder=\"Search by email, name, collection...\"\n className=\"bg-transparent border-none outline-none text-sm w-full placeholder:text-z-muted dark:placeholder:text-z-secondary\"\n />\n </div>\n\n <select\n value={filterAction}\n onChange={(e) => {\n setFilterAction(e.target.value)\n setPage(1)\n }}\n className={cn(\n 'px-4 py-2 border rounded-md text-sm outline-none transition-all shadow-sm',\n theme === 'dark'\n ? 'bg-[#1c1c1c] border-z-border text-z-primary focus:border-z-accent'\n : 'bg-z-panel border-[var(--z-border-strong)] text-z-primary focus:border-z-accent'\n )}\n >\n <option value=\"\">All Actions</option>\n <option value=\"create\">Create</option>\n <option value=\"update\">Update</option>\n <option value=\"delete\">Delete</option>\n <option value=\"publish\">Publish</option>\n <option value=\"unpublish\">Unpublish</option>\n <option value=\"login\">Login</option>\n </select>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <button\n onClick={handlePurgeClick}\n disabled={purging}\n className={cn(\n 'flex items-center gap-2 px-4 py-2 border rounded-md text-sm font-medium transition-all hover:bg-red-50 hover:text-red-600 hover:border-red-200 dark:hover:bg-red-500/10 dark:hover:text-red-400 dark:hover:border-red-500/20',\n theme === 'dark'\n ? 'bg-[#1c1c1c] border-z-border text-z-muted'\n : 'bg-z-panel border-[var(--z-border-strong)] text-z-secondary'\n )}\n >\n <Trash2 size={14} />\n Purge\n </button>\n <button\n onClick={handleExport}\n disabled={exporting}\n className={cn(\n 'flex items-center gap-2 px-5 py-2 rounded-md font-medium text-sm transition-all shadow-sm active:scale-95',\n theme === 'dark'\n ? 'bg-z-panel text-z-primary hover:bg-[var(--z-border)]'\n : 'bg-z-accent text-z-primary hover:brightness-110'\n )}\n >\n {exporting ? (\n <RefreshCw className=\"animate-spin\" size={14} />\n ) : (\n <Download size={14} />\n )}\n Export\n </button>\n </div>\n </div>\n\n {/* Log Table */}\n <div className=\"overflow-x-auto\">\n <div className=\"overflow-x-auto min-w-full pb-4\">\n <table className=\"w-full border-collapse\">\n <thead>\n <tr\n className={cn(\n 'border-b text-left',\n theme === 'dark'\n ? 'border-z-border bg-[#1c1c1c]'\n : 'border-z-border bg-[var(--z-bg-input)]'\n )}\n >\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Operator\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Action\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Collection\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted\">\n Status\n </th>\n <th className=\"px-6 py-3 text-xs font-semibold uppercase tracking-wider text-z-muted text-right\">\n Timestamp\n </th>\n </tr>\n </thead>\n <tbody\n className={cn(\n 'divide-y',\n theme === 'dark' ? 'divide-z-border' : 'divide-z-border'\n )}\n >\n {loading ? (\n <tr>\n <td colSpan={5} className=\"py-20 text-center\">\n <Loader2\n size={24}\n className=\"animate-spin text-z-secondary mx-auto opacity-40\"\n />\n </td>\n </tr>\n ) : logs.length === 0 ? (\n <tr>\n <td colSpan={5} className=\"py-20 text-center\">\n <div className=\"text-z-secondary text-sm font-bold\">\n No audit logs found\n </div>\n </td>\n </tr>\n ) : (\n logs.map((log) => (\n <motion.tr\n key={log._id || log.id}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n onClick={() =>\n setShowDetails(\n showDetails === (log._id || log.id) ? null : log._id || log.id\n )\n }\n className=\"hover:bg-z-border/[0.02] transition-colors cursor-pointer group\"\n >\n <td className=\"px-6 py-4\">\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n 'w-8 h-8 rounded-full border flex items-center justify-center flex-shrink-0',\n theme === 'dark'\n ? 'bg-[#2c2c2c] border-z-border text-z-secondary'\n : 'bg-[var(--z-bg-hover)] border-z-border text-z-secondary'\n )}\n >\n <KeyRound size={14} />\n </div>\n <div className=\"flex flex-col\">\n <span className={cn(\"text-sm font-semibold leading-none\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")}>\n {displayName(log)}\n </span>\n <span className=\"text-xs text-z-muted mt-1\">\n {log.userId\n ? `ID: ${log.userId.slice(-8).toUpperCase()}`\n : 'SYSTEM'}\n </span>\n </div>\n </div>\n </td>\n <td className=\"px-6 py-4\">\n <div\n className={cn(\n 'px-2.5 py-1 rounded-md text-xs font-semibold inline-flex items-center gap-1.5 border',\n getActionColor(log.action)\n )}\n >\n <Zap size={10} fill=\"currentColor\" />\n {formatAction(log.action)}\n </div>\n </td>\n <td className=\"px-6 py-4\">\n <div className=\"flex flex-col\">\n <span className={cn(\"text-sm font-medium leading-none\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")}>\n {log.collectionName || 'SYSTEM'}\n </span>\n {log.documentId && (\n <div className=\"flex items-center gap-1.5 mt-1 text-z-muted\">\n <ArrowRight size={10} />\n <span className=\"text-xs font-mono\">\n DOC_{log.documentId.slice(-12).toUpperCase()}\n </span>\n </div>\n )}\n </div>\n </td>\n <td className=\"px-6 py-4\">\n <span\n className={cn(\n 'text-sm font-medium',\n log.status === 'failed'\n ? 'text-red-500'\n : 'text-emerald-600 dark:text-emerald-400'\n )}\n >\n {log.status === 'failed' ? 'Failed' : 'Success'}\n </span>\n </td>\n <td className=\"px-6 py-4 text-right\">\n <div className=\"flex flex-col items-end gap-1\">\n <span className={cn(\"text-sm font-medium leading-none\", theme === 'dark' ? \"text-z-secondary\" : \"text-z-primary\")}>\n {log.timestamp ? new Date(log.timestamp).toLocaleDateString() : '-'}\n </span>\n <span className=\"text-xs text-z-muted leading-none\">\n {log.timestamp ? new Date(log.timestamp).toLocaleTimeString() : '-'}\n </span>\n </div>\n </td>\n </motion.tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Detail Expand */}\n {showDetails &&\n (() => {\n const log = logs.find((l) => (l._id || l.id) === showDetails)\n if (!log) return null\n return (\n <div\n className={cn(\n 'px-8 py-6 border-t transition-colors',\n theme === 'dark'\n ? 'bg-[#151515] border-z-border'\n : 'bg-[#fafafa] border-z-border'\n )}\n >\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 text-sm font-mono\">\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n IP Address\n </div>\n <div className=\"text-sm font-medium\">{log.ip || 'N/A'}</div>\n </div>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n User Agent\n </div>\n <div className=\"text-sm font-medium truncate\" title={log.userAgent}>\n {log.userAgent || 'N/A'}\n </div>\n </div>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Resource\n </div>\n <div className=\"text-sm font-medium truncate\" title={log.resource}>\n {log.resource || 'N/A'}\n </div>\n </div>\n {log.siteId && (\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Site ID\n </div>\n <div className=\"text-sm font-medium\">{log.siteId}</div>\n </div>\n )}\n {log.hash && (\n <>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Audit Hash\n </div>\n <div className=\"text-sm font-medium truncate font-mono\" title={log.hash}>\n {log.hash.slice(0, 24)}...\n </div>\n </div>\n <div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-1\">\n Prev Hash\n </div>\n <div className=\"text-sm font-medium truncate font-mono\" title={log.previousHash}>\n {log.previousHash ? log.previousHash.slice(0, 24) + '...' : 'GENESIS'}\n </div>\n </div>\n </>\n )}\n </div>\n {log.changes && (\n <div className=\"mt-4\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-z-muted mb-2\">\n Changes\n </div>\n <pre\n className={cn(\n 'p-4 rounded-md text-xs font-mono max-h-48 overflow-auto border shadow-sm',\n theme === 'dark'\n ? 'bg-[#111111] border-z-border text-z-secondary'\n : 'bg-z-panel border-z-border text-z-primary'\n )}\n >\n {JSON.stringify(log.changes, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )\n })()}\n\n {/* Footer */}\n <div\n className={cn(\n 'px-8 py-5 border-t flex items-center justify-between transition-colors rounded-b-xl',\n theme === 'dark' ? 'bg-[#1c1c1c] border-z-border' : 'bg-[var(--z-bg-input)] border-z-border'\n )}\n >\n <div className=\"flex items-center gap-4\">\n <Cpu size={14} className=\"text-z-muted\" />\n <span className=\"text-xs font-semibold uppercase tracking-wider text-z-muted\">\n SECURE AUDIT TRAIL\n </span>\n {stats?.byAction && Object.keys(stats.byAction).length > 0 && (\n <div className=\"flex items-center gap-3 ml-4\">\n {Object.entries(stats.byAction).map(([action, count]) => (\n <span\n key={action}\n className=\"text-xs font-semibold uppercase tracking-wider text-z-muted\"\n >\n {action}:{count}\n </span>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs font-semibold text-z-muted tracking-wider uppercase mr-2\">\n Page {page} of {totalPages}\n </span>\n <button\n disabled={page === 1}\n onClick={() => setPage(page - 1)}\n className={cn(\n 'w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20',\n theme === 'dark'\n ? 'bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]'\n : 'bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]'\n )}\n >\n <ChevronLeft size={16} />\n </button>\n\n <div\n className={cn(\n 'px-3 py-1 rounded-md text-sm font-medium border shadow-sm',\n theme === 'dark'\n ? 'bg-z-panel text-z-primary border-z-border'\n : 'bg-z-accent border-z-border text-z-primary'\n )}\n >\n {page}\n </div>\n\n <button\n disabled={page >= totalPages}\n onClick={() => setPage(page + 1)}\n className={cn(\n 'w-8 h-8 border rounded-md flex items-center justify-center transition-all disabled:opacity-20',\n theme === 'dark'\n ? 'bg-[#2c2c2c] border-z-border text-z-secondary hover:bg-[#3c3c3c]'\n : 'bg-z-panel border-[var(--z-border-strong)] shadow-sm text-z-secondary hover:bg-[var(--z-bg-input)]'\n )}\n >\n <ChevronRight size={16} />\n </button>\n </div>\n </div>\n </div>\n </div>\n\n {/* Custom Purge Modal */}\n {showPurgeModal && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm\">\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n className={cn(\n \"w-full max-w-md rounded-xl p-8 shadow-2xl border\",\n theme === 'dark' ? \"bg-z-panel border-z-border\" : \"bg-z-panel border-z-border\"\n )}\n >\n <div className=\"flex items-center gap-3 text-red-500 mb-4\">\n <AlertTriangle size={24} />\n <h2 className=\"text-xl font-bold text-z-primary tracking-tight\">Purge Audit Logs</h2>\n </div>\n <p className={cn(\"text-sm mb-6 leading-relaxed\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n This action is <span className=\"font-bold text-red-500\">irreversible</span>. It will permanently delete audit logs matching your criteria.\n </p>\n \n <div className=\"space-y-5 mb-8\">\n <div>\n <label className={cn(\"block text-xs font-semibold uppercase tracking-wider mb-2\", theme === 'dark' ? \"text-z-secondary\" : \"text-z-secondary\")}>\n Logs older than (days):\n </label>\n <input\n type=\"number\"\n min=\"0\"\n value={purgeDays}\n onChange={(e) => setPurgeDays(parseInt(e.target.value) || 0)}\n className={cn(\n \"w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all\",\n theme === 'dark' \n ? \"bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50\" \n : \"bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50\"\n )}\n />\n <p className=\"text-[10px] text-z-muted mt-1.5 font-medium uppercase tracking-wide\">Set to 0 to delete all logs.</p>\n </div>\n \n <div>\n <label className={cn(\"block text-xs font-semibold uppercase tracking-wider mb-2\", theme === 'dark' ? \"text-z-secondary\" : \"text-z-secondary\")}>\n Authorization Code: <span className=\"text-red-400 font-mono select-all font-bold tracking-widest\">{purgeExpectedCode}</span>\n </label>\n <input\n type=\"text\"\n value={purgeInputCode}\n onChange={(e) => setPurgeInputCode(e.target.value)}\n placeholder=\"Enter the 6-digit code above\"\n className={cn(\n \"w-full border rounded-md px-4 py-2.5 text-sm outline-none transition-all font-mono tracking-widest\",\n theme === 'dark' \n ? \"bg-[#1c1c1c] border-z-border text-z-primary focus:border-red-500/50\" \n : \"bg-[var(--z-bg-input)] border-[var(--z-border-strong)] text-z-primary focus:border-red-500/50\"\n )}\n />\n </div>\n </div>\n \n <div className=\"flex justify-end gap-3 pt-2\">\n <button\n onClick={() => setShowPurgeModal(false)}\n className={cn(\n \"px-5 py-2.5 text-sm font-semibold border rounded-md transition-all\",\n theme === 'dark' \n ? \"border-z-border bg-z-panel text-z-muted hover:text-z-primary hover:brightness-110\" \n : \"border-z-border bg-z-panel text-z-secondary hover:bg-[var(--z-bg-input)]\"\n )}\n >\n Cancel\n </button>\n <button\n onClick={executePurge}\n disabled={purgeInputCode !== purgeExpectedCode}\n className=\"px-5 py-2.5 text-sm font-semibold bg-red-500/10 text-red-500 border border-red-500/20 rounded-md hover:bg-red-500 hover:text-z-primary transition-all duration-300 disabled:opacity-30 disabled:cursor-not-allowed shadow-sm\"\n >\n Confirm Purge\n </button>\n </div>\n </motion.div>\n </div>\n )}\n\n </div>\n )\n}\n\nexport default AuditLogPage\n"],"mappings":"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"}
@@ -1 +1 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{$n as t,C as n,Dn as r,Et as i,Ft as a,G as o,Ln as s,Lt as c,Mt as l,Ot as u,Q as d,R as f,Rn as p,Sn as m,T as h,Wt as g,Zt as _,_t as v,d as ee,fn as y,gt as b,ir as te,l as x,pt as S,rr as C,un as w,vr as T,xr as E}from"./vendor-react-DQVTOTFO.js";import{a as ne,o as D,t as O}from"./utils-fgvbH6CB.js";import{c as k,p as A}from"./index-ChcKY5Xe.js";var j=e(E(),1),M=T(),N=[{value:`text`,label:`Text`,icon:c,color:`#6b7280`,desc:`Small or long text like title or description`},{value:`textarea`,label:`Textarea`,icon:r,color:`#6b7280`,desc:`Multi-line text for longer descriptions`},{value:`number`,label:`Number`,icon:u,color:`#3b82f6`,desc:`Numbers (integer, float, decimal)`},{value:`email`,label:`Email`,icon:l,color:`var(--z-accent)`,desc:`Email field with validation format`},{value:`password`,label:`Password`,icon:S,color:`#ef4444`,desc:`Password field with encryption`},{value:`checkbox`,label:`Boolean`,icon:h,color:`var(--z-accent)`,desc:`Yes/No, 1/0, True/False`},{value:`date`,label:`Date`,icon:w,color:`#f59e0b`,desc:`A date picker with hours, minutes and seconds`},{value:`media`,label:`Media`,icon:i,color:`#06b6d4`,desc:`Files like images, videos, etc`},{value:`richtext`,label:`Rich Text`,icon:c,color:`#84cc16`,desc:`A rich text editor with formatting options`},{value:`relation`,label:`Relation`,icon:b,color:`#ec4899`,desc:`Refers to another collection`},{value:`json`,label:`JSON`,icon:t,color:`#6366f1`,desc:`Data in JSON format`},{value:`array`,label:`Array`,icon:p,color:`#f59e0b`,desc:`A repeating group of fields`},{value:`row`,label:`Row`,icon:v,color:`#ec4899`,desc:`Group fields side-by-side`},{value:`collapsible`,label:`Collapsible`,icon:m,color:`var(--z-accent)`,desc:`Wrap fields in an accordion`},{value:`tabs`,label:`Tabs`,icon:a,color:`#3b82f6`,desc:`Organize fields into tabs`}];function P(){let{theme:e}=ne(),t=e===`dark`,[r,i]=(0,j.useState)(`New Block`),[a,c]=(0,j.useState)(`new-block`),[u,m]=(0,j.useState)(`General`),[h,v]=(0,j.useState)(`Box`),[b,S]=(0,j.useState)(``),[w,T]=(0,j.useState)([]),[E,P]=(0,j.useState)([]),[F,I]=(0,j.useState)(!0),[L,R]=(0,j.useState)([]),[z,B]=(0,j.useState)(!1),[V,H]=(0,j.useState)(!1),[U,W]=(0,j.useState)(`TYPE`),[G,K]=(0,j.useState)(`BASIC`),[q,J]=(0,j.useState)(null),[Y,X]=(0,j.useState)(null),Z=(0,j.useCallback)(async()=>{try{let e=(await D.get(`/blocks`)).data?.data;P(Array.isArray(e)?e:[])}catch{P([])}finally{I(!1)}},[]);(0,j.useEffect)(()=>{Z(),R([`users`,`pages`,`media`,`categories`])},[Z]);let re=e=>{i(e.labels?.singular||e.slug),c(e.slug),m(e.admin?.category||`General`),v(e.admin?.icon||`Box`),S(e.admin?.description||``),T(e.fields||[]),x.success(`Loaded block: ${e.slug}`)},ie=()=>{i(`New Block`),c(`new-block`),m(`General`),v(`Box`),S(``),T([])},ae=async()=>{if(!a||!r)return x.error(`Name and slug required`);B(!0);try{let e={slug:a,title:r,description:b,category:u,icon:h,fields:w},t=await D.post(`/blocks/generate`,e);k(),x.success(t.data.message||`Block generated as JSON!`),await Z()}catch(e){x.error(e.response?.data?.error?.message||`Failed to generate block`)}finally{B(!1)}},oe=()=>{if(!q?.type)return x.error(`Field type required`);if(q.type!==`row`&&q.type!==`tabs`&&!q.name)return x.error(`Field name is required`);if(Y!==null){let e=[...w];e[Y]=q,T(e)}else T(e=>[...e,q]);H(!1)},se=e=>{T(t=>t.filter((t,n)=>n!==e))},Q=O(`border outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black text-sm font-bold transition-colors py-2.5 px-3 rounded-none shadow-sm`,t?`bg-z-panel backdrop-blur-md border-z-border focus:border-z-accent text-z-primary placeholder:text-z-muted`:`bg-z-panel border-z-border focus:border-z-accent text-z-primary placeholder:text-z-muted`),$=E.reduce((e,t)=>{let n=t.admin?.category||`General`;return e[n]||(e[n]=[]),e[n].push(t),e},{});return(0,M.jsxs)(`div`,{className:O(`flex h-[calc(100vh-4rem)] overflow-hidden`,t?`bg-app text-z-primary`:`bg-[var(--z-bg-input)] text-z-primary`),children:[(0,M.jsxs)(`div`,{className:O(`w-64 flex-shrink-0 border-r flex flex-col`,`border-z-border bg-z-panel`),children:[(0,M.jsxs)(`div`,{className:`p-4 border-b border-inherit flex items-center justify-between`,children:[(0,M.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,M.jsx)(g,{size:14,className:`text-z-secondary `}),` Blocks`]}),(0,M.jsx)(`button`,{onClick:ie,className:`p-1.5 bg-z-panel hover:bg-z-hover border-z-border-strong text-z-secondary rounded-none transition-colors`,title:`New Block`,children:(0,M.jsx)(d,{size:14})})]}),(0,M.jsx)(`div`,{className:`flex-1 overflow-auto p-4 space-y-4`,children:F?(0,M.jsx)(`div`,{className:`flex justify-center`,children:(0,M.jsx)(s,{className:`animate-spin text-z-muted`,size:16})}):Object.keys($).length===0?(0,M.jsx)(`div`,{className:`text-center text-sm text-z-secondary`,children:`No blocks yet`}):Object.entries($).map(([e,n])=>(0,M.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-semibold text-z-secondary`,children:e}),(0,M.jsx)(`div`,{className:`space-y-0.5`,children:n.map(e=>(0,M.jsxs)(`button`,{onClick:()=>re(e),className:O(`w-full flex items-center gap-2 text-left px-3 py-2 text-sm font-semibold transition-colors rounded-none truncate`,a===e.slug?`bg-z-accent text-z-logo-text shadow-sm`:t?`text-z-muted hover:bg-z-hover hover:text-z-primary`:`text-z-secondary hover:bg-[var(--z-bg-input)]`),children:[e.isGenerated?(0,M.jsx)(_,{size:12,className:a===e.slug?`text-z-primary`:`text-z-secondary/50`}):(0,M.jsx)(y,{size:12}),e.labels?.singular||e.slug]},e.slug))})]},e))})]}),(0,M.jsxs)(`div`,{className:`flex-1 flex flex-col overflow-hidden relative`,children:[(0,M.jsx)(A,{title:`Component Builder`,description:`${w.length} fields · Generating to config/blocks/${a}.json`,icon:(0,M.jsx)(p,{size:24}),backLink:{to:`/`,label:`Dashboard`},actions:(0,M.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,M.jsxs)(`button`,{onClick:ae,disabled:z,className:`flex items-center gap-2 px-6 py-2.5 bg-z-accent hover:brightness-110 text-z-logo-text text-sm font-semibold rounded-none transition-all shadow-sm disabled:opacity-50`,children:[z?(0,M.jsx)(s,{size:14,className:`animate-spin`}):(0,M.jsx)(o,{size:14}),` Save Code`]})})}),(0,M.jsxs)(`div`,{className:`flex-1 overflow-auto p-6 space-y-6`,children:[(0,M.jsxs)(`div`,{className:O(`rounded-none border p-6 space-y-4 shadow-sm transition-all`,`z-panel`),children:[(0,M.jsxs)(`h3`,{className:`text-sm font-semibold text-z-secondary flex items-center gap-2`,children:[(0,M.jsx)(f,{size:12}),` Component Settings`]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Display Name`}),(0,M.jsx)(`input`,{type:`text`,value:r,onChange:e=>{i(e.target.value),c(e.target.value.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``))},className:O(Q,`w-full rounded-none`),placeholder:`e.g. Hero Banner`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`API Slug (filename)`}),(0,M.jsx)(`input`,{type:`text`,value:a,onChange:e=>c(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g,``)),className:O(Q,`w-full rounded-none font-mono`),placeholder:`e.g. hero-banner`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Category`}),(0,M.jsx)(`input`,{type:`text`,value:u,onChange:e=>m(e.target.value),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Layout, Content, Media`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Description`}),(0,M.jsx)(`input`,{type:`text`,value:b,onChange:e=>S(e.target.value),className:O(Q,`w-full rounded-none`),placeholder:`Brief description for editors`})]})]})]}),(0,M.jsxs)(`div`,{className:O(`rounded-none border shadow-sm transition-all`,`z-panel`),children:[(0,M.jsxs)(`div`,{className:`px-6 py-4 border-b border-inherit flex items-center justify-between`,children:[(0,M.jsxs)(`h3`,{className:`text-sm font-semibold text-z-secondary flex items-center gap-2`,children:[(0,M.jsx)(p,{size:12}),` Fields (`,w.length,`)`]}),(0,M.jsxs)(`button`,{onClick:()=>{W(`TYPE`),J({}),X(null),K(`BASIC`),H(!0)},className:`flex items-center gap-1.5 px-3 py-1.5 bg-z-panel hover:bg-z-hover border-z-border-strong text-z-secondary text-sm font-semibold rounded-none transition-all`,children:[(0,M.jsx)(d,{size:12}),` Add new field`]})]}),(0,M.jsx)(`div`,{className:`p-0`,children:w.length===0?(0,M.jsxs)(`div`,{className:`py-16 text-center`,children:[(0,M.jsx)(p,{size:40,className:`mx-auto text-z-primary mb-4`,strokeWidth:1}),(0,M.jsx)(`p`,{className:`text-sm font-semibold text-z-secondary`,children:`No fields yet`})]}):(0,M.jsx)(`div`,{className:`divide-y divide-z-border dark:divide-z-border`,children:w.map((e,t)=>(0,M.jsxs)(`div`,{className:`flex items-center justify-between px-6 py-4 hover:bg-z-hover transition-colors group cursor-pointer`,onClick:()=>{J(e),X(t),W(`SETTINGS`),K(`BASIC`),H(!0)},children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,M.jsx)(`div`,{className:`w-8 h-8 rounded-none bg-z-panel flex items-center justify-center`,children:(()=>{let t=N.find(t=>t.value===e.type);return(0,M.jsx)(t?t.icon:y,{size:14,className:`text-z-secondary `})})()}),(0,M.jsxs)(`div`,{children:[(0,M.jsxs)(`div`,{className:`text-sm font-bold text-z-primary dark:text-z-primary flex items-center gap-2`,children:[e.name||`[${e.type}]`,e.required&&(0,M.jsx)(`span`,{className:`text-sm text-red-500`,children:`*`}),e.i18n&&(0,M.jsx)(l,{size:10,className:`text-z-active-text`})]}),(0,M.jsxs)(`div`,{className:`text-sm font-bold text-z-secondary mt-0.5`,children:[e.type,` `,e.label?`· ${e.label}`:``]})]})]}),(0,M.jsx)(`button`,{onClick:e=>{e.stopPropagation(),se(t)},className:`opacity-0 group-hover:opacity-100 p-2 text-red-500 hover:bg-red-500/10 rounded-none transition-all`,children:(0,M.jsx)(n,{size:14})})]},t))})})]})]})]}),(0,M.jsx)(te,{children:V&&(0,M.jsx)(C.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`fixed inset-0 z-50 flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm p-4`,children:(0,M.jsxs)(C.div,{initial:{scale:.95,y:10},animate:{scale:1,y:0},exit:{scale:.95,y:10},className:`w-full max-w-4xl border rounded-none shadow-sm flex flex-col max-h-[85vh] bg-app border-z-border overflow-hidden`,children:[(0,M.jsxs)(`div`,{className:`px-6 py-4 border-b border-z-border flex items-center justify-between bg-app/50`,children:[(0,M.jsx)(`h2`,{className:`text-sm font-semibold text-z-primary flex items-center gap-2`,children:U===`TYPE`?`Select a field for your Component`:`Configure ${q?.type} field`}),(0,M.jsx)(`button`,{onClick:()=>H(!1),className:`text-z-secondary hover:text-z-primary p-1`,children:(0,M.jsx)(ee,{size:18})})]}),U===`TYPE`&&(0,M.jsx)(`div`,{className:`flex-1 overflow-auto p-6 grid grid-cols-2 lg:grid-cols-3 gap-4`,children:N.map(e=>{let t=e.icon;return(0,M.jsxs)(`button`,{onClick:()=>{J({type:e.value,admin:{}}),W(`SETTINGS`)},className:`flex items-start gap-4 p-4 rounded-none border border-z-border bg-z-hover hover:border-z-accent/50 hover:opacity-90/5 transition-all text-left`,children:[(0,M.jsx)(`div`,{className:`mt-1 p-2 rounded-none bg-app/50 border border-z-border`,children:(0,M.jsx)(t,{size:18,style:{color:e.color}})}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`div`,{className:`text-sm font-semibold text-z-primary mb-1`,children:e.label}),(0,M.jsx)(`div`,{className:`text-sm text-z-muted leading-relaxed font-bold`,children:e.desc})]})]},e.value)})}),U===`SETTINGS`&&(0,M.jsxs)(`div`,{className:`flex flex-col flex-1 overflow-hidden`,children:[(0,M.jsx)(`div`,{className:`flex border-b border-z-border px-6 pt-4 gap-6 bg-app/20`,children:[`BASIC`,`VALIDATION`,`ADMIN`].map(e=>(0,M.jsxs)(`button`,{onClick:()=>K(e),className:O(`pb-3 text-sm font-semibold transition-colors relative`,G===e?`text-z-secondary `:`text-z-secondary hover:text-z-primary`),children:[e,G===e&&(0,M.jsx)(C.div,{layoutId:`tab-indicator`,className:`absolute bottom-0 left-0 right-0 h-0.5 bg-z-border`})]},e))}),(0,M.jsxs)(`div`,{className:`flex-1 overflow-auto p-6 max-w-3xl mx-auto w-full`,children:[G===`BASIC`&&(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{className:`col-span-2 sm:col-span-1`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Name (Key in JSON)*`}),(0,M.jsx)(`input`,{type:`text`,value:q?.name||``,onChange:e=>J(t=>({...t,name:e.target.value.replace(/\s+/g,`_`).replace(/[^a-zA-Z0-9_]/g,``)})),className:O(Q,`w-full rounded-none font-mono`),placeholder:`e.g. heroTitle`})]}),(0,M.jsxs)(`div`,{className:`col-span-2 sm:col-span-1`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Display Label`}),(0,M.jsx)(`input`,{type:`text`,value:q?.label||``,onChange:e=>J(t=>({...t,label:e.target.value})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Hero Title`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Description`}),(0,M.jsx)(`input`,{type:`text`,value:q?.description||``,onChange:e=>J(t=>({...t,description:e.target.value})),className:O(Q,`w-full rounded-none`),placeholder:`Help text for content editors`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Default Value`}),(0,M.jsx)(`input`,{type:`text`,value:q?.defaultValue||``,onChange:e=>J(t=>({...t,defaultValue:e.target.value})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Welcome`})]}),q?.type===`relation`&&(0,M.jsxs)(`div`,{className:`col-span-2 pt-4 border-t border-z-border space-y-4`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block`,children:`Relation Options`}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Relates To`}),(0,M.jsxs)(`select`,{value:q.relationTo||``,onChange:e=>J(t=>({...t,relationTo:e.target.value})),className:O(Q,`w-full rounded-none cursor-pointer`),children:[(0,M.jsx)(`option`,{value:``,children:`-- Select Collection --`}),L.map(e=>(0,M.jsx)(`option`,{value:e,children:e},e))]})]}),(0,M.jsx)(`div`,{className:`flex items-center`,children:(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer mt-4`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.hasMany,onChange:e=>J(t=>({...t,hasMany:e.target.checked})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Has Many (Array of references)`})]})})]})]})]}),G===`VALIDATION`&&(0,M.jsxs)(`div`,{className:`space-y-6`,children:[(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4 bg-z-hover p-4 rounded-none border border-z-border`,children:[(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.required,onChange:e=>J(t=>({...t,required:e.target.checked})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Required field`})]}),(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.unique,onChange:e=>J(t=>({...t,unique:e.target.checked})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Unique field`})]})]}),(q?.type===`text`||q?.type===`textarea`)&&(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Min Length`}),(0,M.jsx)(`input`,{type:`number`,value:q?.minLength||``,onChange:e=>J(t=>({...t,minLength:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 5`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Max Length`}),(0,M.jsx)(`input`,{type:`number`,value:q?.maxLength||``,onChange:e=>J(t=>({...t,maxLength:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 100`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Regex Pattern`}),(0,M.jsx)(`input`,{type:`text`,value:q?.regex||``,onChange:e=>J(t=>({...t,regex:e.target.value})),className:O(Q,`w-full rounded-none font-mono`),placeholder:`^[A-Za-z]+$`})]})]}),q?.type===`number`&&(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Minimum Value`}),(0,M.jsx)(`input`,{type:`number`,value:q?.min||``,onChange:e=>J(t=>({...t,min:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 0`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Maximum Value`}),(0,M.jsx)(`input`,{type:`number`,value:q?.max||``,onChange:e=>J(t=>({...t,max:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 100`})]})]}),q?.type===`date`&&(0,M.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Date Mode`}),(0,M.jsxs)(`select`,{value:q?.dateFormat||`date`,onChange:e=>J(t=>({...t,dateFormat:e.target.value})),className:O(Q,`w-full rounded-none cursor-pointer`),children:[(0,M.jsx)(`option`,{value:`date`,children:`Date Only`}),(0,M.jsx)(`option`,{value:`datetime`,children:`Date & Time`}),(0,M.jsx)(`option`,{value:`time`,children:`Time Only`})]})]})})]}),G===`ADMIN`&&(0,M.jsxs)(`div`,{className:`space-y-6`,children:[(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4 bg-z-hover p-4 rounded-none border border-z-border`,children:[(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.i18n,onChange:e=>J(t=>({...t,i18n:e.target.checked})),className:`accent-z-accent w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Enable Localization (i18n)`})]}),(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.admin?.hidden,onChange:e=>J(t=>({...t,admin:{...t.admin,hidden:e.target.checked}})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Hidden in UI`})]}),(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.admin?.readOnly,onChange:e=>J(t=>({...t,admin:{...t.admin,readOnly:e.target.checked}})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Read-Only`})]})]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Field Width`}),(0,M.jsxs)(`select`,{value:q?.admin?.width||`100%`,onChange:e=>J(t=>({...t,admin:{...t.admin,width:e.target.value}})),className:O(Q,`w-full rounded-none cursor-pointer`),children:[(0,M.jsx)(`option`,{value:`100%`,children:`100% (Full Width)`}),(0,M.jsx)(`option`,{value:`50%`,children:`50% (Half Width)`}),(0,M.jsx)(`option`,{value:`33%`,children:`33% (One Third)`}),(0,M.jsx)(`option`,{value:`25%`,children:`25% (One Quarter)`})]})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Placeholder`}),(0,M.jsx)(`input`,{type:`text`,value:q?.admin?.placeholder||``,onChange:e=>J(t=>({...t,admin:{...t.admin,placeholder:e.target.value}})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Enter a value...`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Conditional Visibility JSON`}),(0,M.jsx)(`textarea`,{rows:3,value:q?.admin?.condition?JSON.stringify(q.admin.condition):``,onChange:e=>{try{let t=e.target.value?JSON.parse(e.target.value):void 0;J(e=>({...e,admin:{...e.admin,condition:t}}))}catch{}},className:O(Q,`w-full rounded-none font-mono`),placeholder:`{"field": "theme", "equals": "dark"}`})]})]})]})]})]}),(0,M.jsxs)(`div`,{className:`px-6 py-4 border-t border-z-border bg-app/50 flex justify-between`,children:[U===`SETTINGS`?(0,M.jsx)(`button`,{onClick:()=>W(`TYPE`),className:`px-4 py-2 text-sm font-bold text-z-muted hover:text-z-primary transition-colors`,children:`← Back to Types`}):(0,M.jsx)(`div`,{}),U===`SETTINGS`&&(0,M.jsx)(`button`,{onClick:oe,className:`px-6 py-2 bg-z-accent hover:brightness-110 text-z-logo-text text-sm font-semibold rounded-none transition-all shadow-sm`,children:Y===null?`Add Field`:`Update Field`})]})]})})})]})}export{P as default};
1
+ import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{$n as t,C as n,Dn as r,Et as i,Ft as a,G as o,Ln as s,Lt as c,Mt as l,Ot as u,Q as d,R as f,Rn as p,Sn as m,T as h,Wt as g,Zt as _,_t as v,d as ee,fn as y,gt as b,ir as te,l as x,pt as S,rr as C,un as w,vr as T,xr as E}from"./vendor-react-DQVTOTFO.js";import{a as ne,o as D,t as O}from"./utils-fgvbH6CB.js";import{c as k,p as A}from"./index-yE_3fruG.js";var j=e(E(),1),M=T(),N=[{value:`text`,label:`Text`,icon:c,color:`#6b7280`,desc:`Small or long text like title or description`},{value:`textarea`,label:`Textarea`,icon:r,color:`#6b7280`,desc:`Multi-line text for longer descriptions`},{value:`number`,label:`Number`,icon:u,color:`#3b82f6`,desc:`Numbers (integer, float, decimal)`},{value:`email`,label:`Email`,icon:l,color:`var(--z-accent)`,desc:`Email field with validation format`},{value:`password`,label:`Password`,icon:S,color:`#ef4444`,desc:`Password field with encryption`},{value:`checkbox`,label:`Boolean`,icon:h,color:`var(--z-accent)`,desc:`Yes/No, 1/0, True/False`},{value:`date`,label:`Date`,icon:w,color:`#f59e0b`,desc:`A date picker with hours, minutes and seconds`},{value:`media`,label:`Media`,icon:i,color:`#06b6d4`,desc:`Files like images, videos, etc`},{value:`richtext`,label:`Rich Text`,icon:c,color:`#84cc16`,desc:`A rich text editor with formatting options`},{value:`relation`,label:`Relation`,icon:b,color:`#ec4899`,desc:`Refers to another collection`},{value:`json`,label:`JSON`,icon:t,color:`#6366f1`,desc:`Data in JSON format`},{value:`array`,label:`Array`,icon:p,color:`#f59e0b`,desc:`A repeating group of fields`},{value:`row`,label:`Row`,icon:v,color:`#ec4899`,desc:`Group fields side-by-side`},{value:`collapsible`,label:`Collapsible`,icon:m,color:`var(--z-accent)`,desc:`Wrap fields in an accordion`},{value:`tabs`,label:`Tabs`,icon:a,color:`#3b82f6`,desc:`Organize fields into tabs`}];function P(){let{theme:e}=ne(),t=e===`dark`,[r,i]=(0,j.useState)(`New Block`),[a,c]=(0,j.useState)(`new-block`),[u,m]=(0,j.useState)(`General`),[h,v]=(0,j.useState)(`Box`),[b,S]=(0,j.useState)(``),[w,T]=(0,j.useState)([]),[E,P]=(0,j.useState)([]),[F,I]=(0,j.useState)(!0),[L,R]=(0,j.useState)([]),[z,B]=(0,j.useState)(!1),[V,H]=(0,j.useState)(!1),[U,W]=(0,j.useState)(`TYPE`),[G,K]=(0,j.useState)(`BASIC`),[q,J]=(0,j.useState)(null),[Y,X]=(0,j.useState)(null),Z=(0,j.useCallback)(async()=>{try{let e=(await D.get(`/blocks`)).data?.data;P(Array.isArray(e)?e:[])}catch{P([])}finally{I(!1)}},[]);(0,j.useEffect)(()=>{Z(),R([`users`,`pages`,`media`,`categories`])},[Z]);let re=e=>{i(e.labels?.singular||e.slug),c(e.slug),m(e.admin?.category||`General`),v(e.admin?.icon||`Box`),S(e.admin?.description||``),T(e.fields||[]),x.success(`Loaded block: ${e.slug}`)},ie=()=>{i(`New Block`),c(`new-block`),m(`General`),v(`Box`),S(``),T([])},ae=async()=>{if(!a||!r)return x.error(`Name and slug required`);B(!0);try{let e={slug:a,title:r,description:b,category:u,icon:h,fields:w},t=await D.post(`/blocks/generate`,e);k(),x.success(t.data.message||`Block generated as JSON!`),await Z()}catch(e){x.error(e.response?.data?.error?.message||`Failed to generate block`)}finally{B(!1)}},oe=()=>{if(!q?.type)return x.error(`Field type required`);if(q.type!==`row`&&q.type!==`tabs`&&!q.name)return x.error(`Field name is required`);if(Y!==null){let e=[...w];e[Y]=q,T(e)}else T(e=>[...e,q]);H(!1)},se=e=>{T(t=>t.filter((t,n)=>n!==e))},Q=O(`border outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black text-sm font-bold transition-colors py-2.5 px-3 rounded-none shadow-sm`,t?`bg-z-panel backdrop-blur-md border-z-border focus:border-z-accent text-z-primary placeholder:text-z-muted`:`bg-z-panel border-z-border focus:border-z-accent text-z-primary placeholder:text-z-muted`),$=E.reduce((e,t)=>{let n=t.admin?.category||`General`;return e[n]||(e[n]=[]),e[n].push(t),e},{});return(0,M.jsxs)(`div`,{className:O(`flex h-[calc(100vh-4rem)] overflow-hidden`,t?`bg-app text-z-primary`:`bg-[var(--z-bg-input)] text-z-primary`),children:[(0,M.jsxs)(`div`,{className:O(`w-64 flex-shrink-0 border-r flex flex-col`,`border-z-border bg-z-panel`),children:[(0,M.jsxs)(`div`,{className:`p-4 border-b border-inherit flex items-center justify-between`,children:[(0,M.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,M.jsx)(g,{size:14,className:`text-z-secondary `}),` Blocks`]}),(0,M.jsx)(`button`,{onClick:ie,className:`p-1.5 bg-z-panel hover:bg-z-hover border-z-border-strong text-z-secondary rounded-none transition-colors`,title:`New Block`,children:(0,M.jsx)(d,{size:14})})]}),(0,M.jsx)(`div`,{className:`flex-1 overflow-auto p-4 space-y-4`,children:F?(0,M.jsx)(`div`,{className:`flex justify-center`,children:(0,M.jsx)(s,{className:`animate-spin text-z-muted`,size:16})}):Object.keys($).length===0?(0,M.jsx)(`div`,{className:`text-center text-sm text-z-secondary`,children:`No blocks yet`}):Object.entries($).map(([e,n])=>(0,M.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-semibold text-z-secondary`,children:e}),(0,M.jsx)(`div`,{className:`space-y-0.5`,children:n.map(e=>(0,M.jsxs)(`button`,{onClick:()=>re(e),className:O(`w-full flex items-center gap-2 text-left px-3 py-2 text-sm font-semibold transition-colors rounded-none truncate`,a===e.slug?`bg-z-accent text-z-logo-text shadow-sm`:t?`text-z-muted hover:bg-z-hover hover:text-z-primary`:`text-z-secondary hover:bg-[var(--z-bg-input)]`),children:[e.isGenerated?(0,M.jsx)(_,{size:12,className:a===e.slug?`text-z-primary`:`text-z-secondary/50`}):(0,M.jsx)(y,{size:12}),e.labels?.singular||e.slug]},e.slug))})]},e))})]}),(0,M.jsxs)(`div`,{className:`flex-1 flex flex-col overflow-hidden relative`,children:[(0,M.jsx)(A,{title:`Component Builder`,description:`${w.length} fields · Generating to config/blocks/${a}.json`,icon:(0,M.jsx)(p,{size:24}),backLink:{to:`/`,label:`Dashboard`},actions:(0,M.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,M.jsxs)(`button`,{onClick:ae,disabled:z,className:`flex items-center gap-2 px-6 py-2.5 bg-z-accent hover:brightness-110 text-z-logo-text text-sm font-semibold rounded-none transition-all shadow-sm disabled:opacity-50`,children:[z?(0,M.jsx)(s,{size:14,className:`animate-spin`}):(0,M.jsx)(o,{size:14}),` Save Code`]})})}),(0,M.jsxs)(`div`,{className:`flex-1 overflow-auto p-6 space-y-6`,children:[(0,M.jsxs)(`div`,{className:O(`rounded-none border p-6 space-y-4 shadow-sm transition-all`,`z-panel`),children:[(0,M.jsxs)(`h3`,{className:`text-sm font-semibold text-z-secondary flex items-center gap-2`,children:[(0,M.jsx)(f,{size:12}),` Component Settings`]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Display Name`}),(0,M.jsx)(`input`,{type:`text`,value:r,onChange:e=>{i(e.target.value),c(e.target.value.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``))},className:O(Q,`w-full rounded-none`),placeholder:`e.g. Hero Banner`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`API Slug (filename)`}),(0,M.jsx)(`input`,{type:`text`,value:a,onChange:e=>c(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g,``)),className:O(Q,`w-full rounded-none font-mono`),placeholder:`e.g. hero-banner`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Category`}),(0,M.jsx)(`input`,{type:`text`,value:u,onChange:e=>m(e.target.value),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Layout, Content, Media`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Description`}),(0,M.jsx)(`input`,{type:`text`,value:b,onChange:e=>S(e.target.value),className:O(Q,`w-full rounded-none`),placeholder:`Brief description for editors`})]})]})]}),(0,M.jsxs)(`div`,{className:O(`rounded-none border shadow-sm transition-all`,`z-panel`),children:[(0,M.jsxs)(`div`,{className:`px-6 py-4 border-b border-inherit flex items-center justify-between`,children:[(0,M.jsxs)(`h3`,{className:`text-sm font-semibold text-z-secondary flex items-center gap-2`,children:[(0,M.jsx)(p,{size:12}),` Fields (`,w.length,`)`]}),(0,M.jsxs)(`button`,{onClick:()=>{W(`TYPE`),J({}),X(null),K(`BASIC`),H(!0)},className:`flex items-center gap-1.5 px-3 py-1.5 bg-z-panel hover:bg-z-hover border-z-border-strong text-z-secondary text-sm font-semibold rounded-none transition-all`,children:[(0,M.jsx)(d,{size:12}),` Add new field`]})]}),(0,M.jsx)(`div`,{className:`p-0`,children:w.length===0?(0,M.jsxs)(`div`,{className:`py-16 text-center`,children:[(0,M.jsx)(p,{size:40,className:`mx-auto text-z-primary mb-4`,strokeWidth:1}),(0,M.jsx)(`p`,{className:`text-sm font-semibold text-z-secondary`,children:`No fields yet`})]}):(0,M.jsx)(`div`,{className:`divide-y divide-z-border dark:divide-z-border`,children:w.map((e,t)=>(0,M.jsxs)(`div`,{className:`flex items-center justify-between px-6 py-4 hover:bg-z-hover transition-colors group cursor-pointer`,onClick:()=>{J(e),X(t),W(`SETTINGS`),K(`BASIC`),H(!0)},children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,M.jsx)(`div`,{className:`w-8 h-8 rounded-none bg-z-panel flex items-center justify-center`,children:(()=>{let t=N.find(t=>t.value===e.type);return(0,M.jsx)(t?t.icon:y,{size:14,className:`text-z-secondary `})})()}),(0,M.jsxs)(`div`,{children:[(0,M.jsxs)(`div`,{className:`text-sm font-bold text-z-primary dark:text-z-primary flex items-center gap-2`,children:[e.name||`[${e.type}]`,e.required&&(0,M.jsx)(`span`,{className:`text-sm text-red-500`,children:`*`}),e.i18n&&(0,M.jsx)(l,{size:10,className:`text-z-active-text`})]}),(0,M.jsxs)(`div`,{className:`text-sm font-bold text-z-secondary mt-0.5`,children:[e.type,` `,e.label?`· ${e.label}`:``]})]})]}),(0,M.jsx)(`button`,{onClick:e=>{e.stopPropagation(),se(t)},className:`opacity-0 group-hover:opacity-100 p-2 text-red-500 hover:bg-red-500/10 rounded-none transition-all`,children:(0,M.jsx)(n,{size:14})})]},t))})})]})]})]}),(0,M.jsx)(te,{children:V&&(0,M.jsx)(C.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`fixed inset-0 z-50 flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm p-4`,children:(0,M.jsxs)(C.div,{initial:{scale:.95,y:10},animate:{scale:1,y:0},exit:{scale:.95,y:10},className:`w-full max-w-4xl border rounded-none shadow-sm flex flex-col max-h-[85vh] bg-app border-z-border overflow-hidden`,children:[(0,M.jsxs)(`div`,{className:`px-6 py-4 border-b border-z-border flex items-center justify-between bg-app/50`,children:[(0,M.jsx)(`h2`,{className:`text-sm font-semibold text-z-primary flex items-center gap-2`,children:U===`TYPE`?`Select a field for your Component`:`Configure ${q?.type} field`}),(0,M.jsx)(`button`,{onClick:()=>H(!1),className:`text-z-secondary hover:text-z-primary p-1`,children:(0,M.jsx)(ee,{size:18})})]}),U===`TYPE`&&(0,M.jsx)(`div`,{className:`flex-1 overflow-auto p-6 grid grid-cols-2 lg:grid-cols-3 gap-4`,children:N.map(e=>{let t=e.icon;return(0,M.jsxs)(`button`,{onClick:()=>{J({type:e.value,admin:{}}),W(`SETTINGS`)},className:`flex items-start gap-4 p-4 rounded-none border border-z-border bg-z-hover hover:border-z-accent/50 hover:opacity-90/5 transition-all text-left`,children:[(0,M.jsx)(`div`,{className:`mt-1 p-2 rounded-none bg-app/50 border border-z-border`,children:(0,M.jsx)(t,{size:18,style:{color:e.color}})}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`div`,{className:`text-sm font-semibold text-z-primary mb-1`,children:e.label}),(0,M.jsx)(`div`,{className:`text-sm text-z-muted leading-relaxed font-bold`,children:e.desc})]})]},e.value)})}),U===`SETTINGS`&&(0,M.jsxs)(`div`,{className:`flex flex-col flex-1 overflow-hidden`,children:[(0,M.jsx)(`div`,{className:`flex border-b border-z-border px-6 pt-4 gap-6 bg-app/20`,children:[`BASIC`,`VALIDATION`,`ADMIN`].map(e=>(0,M.jsxs)(`button`,{onClick:()=>K(e),className:O(`pb-3 text-sm font-semibold transition-colors relative`,G===e?`text-z-secondary `:`text-z-secondary hover:text-z-primary`),children:[e,G===e&&(0,M.jsx)(C.div,{layoutId:`tab-indicator`,className:`absolute bottom-0 left-0 right-0 h-0.5 bg-z-border`})]},e))}),(0,M.jsxs)(`div`,{className:`flex-1 overflow-auto p-6 max-w-3xl mx-auto w-full`,children:[G===`BASIC`&&(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{className:`col-span-2 sm:col-span-1`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Name (Key in JSON)*`}),(0,M.jsx)(`input`,{type:`text`,value:q?.name||``,onChange:e=>J(t=>({...t,name:e.target.value.replace(/\s+/g,`_`).replace(/[^a-zA-Z0-9_]/g,``)})),className:O(Q,`w-full rounded-none font-mono`),placeholder:`e.g. heroTitle`})]}),(0,M.jsxs)(`div`,{className:`col-span-2 sm:col-span-1`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Display Label`}),(0,M.jsx)(`input`,{type:`text`,value:q?.label||``,onChange:e=>J(t=>({...t,label:e.target.value})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Hero Title`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Description`}),(0,M.jsx)(`input`,{type:`text`,value:q?.description||``,onChange:e=>J(t=>({...t,description:e.target.value})),className:O(Q,`w-full rounded-none`),placeholder:`Help text for content editors`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Default Value`}),(0,M.jsx)(`input`,{type:`text`,value:q?.defaultValue||``,onChange:e=>J(t=>({...t,defaultValue:e.target.value})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Welcome`})]}),q?.type===`relation`&&(0,M.jsxs)(`div`,{className:`col-span-2 pt-4 border-t border-z-border space-y-4`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block`,children:`Relation Options`}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Relates To`}),(0,M.jsxs)(`select`,{value:q.relationTo||``,onChange:e=>J(t=>({...t,relationTo:e.target.value})),className:O(Q,`w-full rounded-none cursor-pointer`),children:[(0,M.jsx)(`option`,{value:``,children:`-- Select Collection --`}),L.map(e=>(0,M.jsx)(`option`,{value:e,children:e},e))]})]}),(0,M.jsx)(`div`,{className:`flex items-center`,children:(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer mt-4`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.hasMany,onChange:e=>J(t=>({...t,hasMany:e.target.checked})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Has Many (Array of references)`})]})})]})]})]}),G===`VALIDATION`&&(0,M.jsxs)(`div`,{className:`space-y-6`,children:[(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4 bg-z-hover p-4 rounded-none border border-z-border`,children:[(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.required,onChange:e=>J(t=>({...t,required:e.target.checked})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Required field`})]}),(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.unique,onChange:e=>J(t=>({...t,unique:e.target.checked})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Unique field`})]})]}),(q?.type===`text`||q?.type===`textarea`)&&(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Min Length`}),(0,M.jsx)(`input`,{type:`number`,value:q?.minLength||``,onChange:e=>J(t=>({...t,minLength:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 5`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Max Length`}),(0,M.jsx)(`input`,{type:`number`,value:q?.maxLength||``,onChange:e=>J(t=>({...t,maxLength:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 100`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Regex Pattern`}),(0,M.jsx)(`input`,{type:`text`,value:q?.regex||``,onChange:e=>J(t=>({...t,regex:e.target.value})),className:O(Q,`w-full rounded-none font-mono`),placeholder:`^[A-Za-z]+$`})]})]}),q?.type===`number`&&(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Minimum Value`}),(0,M.jsx)(`input`,{type:`number`,value:q?.min||``,onChange:e=>J(t=>({...t,min:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 0`})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Maximum Value`}),(0,M.jsx)(`input`,{type:`number`,value:q?.max||``,onChange:e=>J(t=>({...t,max:parseInt(e.target.value)||void 0})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. 100`})]})]}),q?.type===`date`&&(0,M.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Date Mode`}),(0,M.jsxs)(`select`,{value:q?.dateFormat||`date`,onChange:e=>J(t=>({...t,dateFormat:e.target.value})),className:O(Q,`w-full rounded-none cursor-pointer`),children:[(0,M.jsx)(`option`,{value:`date`,children:`Date Only`}),(0,M.jsx)(`option`,{value:`datetime`,children:`Date & Time`}),(0,M.jsx)(`option`,{value:`time`,children:`Time Only`})]})]})})]}),G===`ADMIN`&&(0,M.jsxs)(`div`,{className:`space-y-6`,children:[(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4 bg-z-hover p-4 rounded-none border border-z-border`,children:[(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.i18n,onChange:e=>J(t=>({...t,i18n:e.target.checked})),className:`accent-z-accent w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Enable Localization (i18n)`})]}),(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.admin?.hidden,onChange:e=>J(t=>({...t,admin:{...t.admin,hidden:e.target.checked}})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Hidden in UI`})]}),(0,M.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:!!q?.admin?.readOnly,onChange:e=>J(t=>({...t,admin:{...t.admin,readOnly:e.target.checked}})),className:`accent-gray-500 w-4 h-4`}),(0,M.jsx)(`span`,{className:`text-xs font-bold text-z-secondary`,children:`Read-Only`})]})]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Field Width`}),(0,M.jsxs)(`select`,{value:q?.admin?.width||`100%`,onChange:e=>J(t=>({...t,admin:{...t.admin,width:e.target.value}})),className:O(Q,`w-full rounded-none cursor-pointer`),children:[(0,M.jsx)(`option`,{value:`100%`,children:`100% (Full Width)`}),(0,M.jsx)(`option`,{value:`50%`,children:`50% (Half Width)`}),(0,M.jsx)(`option`,{value:`33%`,children:`33% (One Third)`}),(0,M.jsx)(`option`,{value:`25%`,children:`25% (One Quarter)`})]})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Placeholder`}),(0,M.jsx)(`input`,{type:`text`,value:q?.admin?.placeholder||``,onChange:e=>J(t=>({...t,admin:{...t.admin,placeholder:e.target.value}})),className:O(Q,`w-full rounded-none`),placeholder:`e.g. Enter a value...`})]}),(0,M.jsxs)(`div`,{className:`col-span-2`,children:[(0,M.jsx)(`label`,{className:`text-sm font-semibold text-z-secondary block mb-1.5`,children:`Conditional Visibility JSON`}),(0,M.jsx)(`textarea`,{rows:3,value:q?.admin?.condition?JSON.stringify(q.admin.condition):``,onChange:e=>{try{let t=e.target.value?JSON.parse(e.target.value):void 0;J(e=>({...e,admin:{...e.admin,condition:t}}))}catch{}},className:O(Q,`w-full rounded-none font-mono`),placeholder:`{"field": "theme", "equals": "dark"}`})]})]})]})]})]}),(0,M.jsxs)(`div`,{className:`px-6 py-4 border-t border-z-border bg-app/50 flex justify-between`,children:[U===`SETTINGS`?(0,M.jsx)(`button`,{onClick:()=>W(`TYPE`),className:`px-4 py-2 text-sm font-bold text-z-muted hover:text-z-primary transition-colors`,children:`← Back to Types`}):(0,M.jsx)(`div`,{}),U===`SETTINGS`&&(0,M.jsx)(`button`,{onClick:oe,className:`px-6 py-2 bg-z-accent hover:brightness-110 text-z-logo-text text-sm font-semibold rounded-none transition-all shadow-sm`,children:Y===null?`Add Field`:`Update Field`})]})]})})})]})}export{P as default};