gavaengine 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DashboardSplashTrigger-CRpueuUi.d.ts → DashboardSplashTrigger-Bz4Z4edN.d.ts} +1 -1
- package/dist/{chunk-4LM22T36.js → chunk-3ZYJ4C6R.js} +4 -3
- package/dist/chunk-3ZYJ4C6R.js.map +1 -0
- package/dist/{chunk-MC3FBYWV.js → chunk-PHT76VW6.js} +26 -2
- package/dist/chunk-PHT76VW6.js.map +1 -0
- package/dist/{chunk-YSVQQBBU.js → chunk-XUWBLDOW.js} +172 -50
- package/dist/chunk-XUWBLDOW.js.map +1 -0
- package/dist/components/index.d.ts +24 -22
- package/dist/components/index.js +12 -3
- package/dist/handlers/index.d.ts +75 -1
- package/dist/handlers/index.js +66 -0
- package/dist/handlers/index.js.map +1 -1
- package/dist/{index-CCsSC4nF.d.ts → index-ByyETmJM.d.ts} +2 -1
- package/dist/index.d.ts +24 -6
- package/dist/index.js +75 -3
- package/dist/index.js.map +1 -1
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +2 -2
- package/dist/{types-X07o_zKf.d.ts → registry-Do5nzO7_.d.ts} +45 -1
- package/package.json +1 -1
- package/src/prisma/schema.partial.prisma +9 -0
- package/dist/chunk-4LM22T36.js.map +0 -1
- package/dist/chunk-MC3FBYWV.js.map +0 -1
- package/dist/chunk-YSVQQBBU.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { Editor, NodeViewProps } from '@tiptap/react';
|
|
|
3
3
|
import * as _tiptap_core from '@tiptap/core';
|
|
4
4
|
import { Node } from '@tiptap/core';
|
|
5
5
|
import * as _tiptap_extension_youtube from '@tiptap/extension-youtube';
|
|
6
|
-
import {
|
|
6
|
+
import { m as GEMedia } from './registry-Do5nzO7_.js';
|
|
7
7
|
import { LucideIcon } from 'lucide-react';
|
|
8
8
|
|
|
9
9
|
interface ArticleData {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
ActionsProvider,
|
|
4
|
+
ComponentRegistryProvider,
|
|
4
5
|
ConfigProvider,
|
|
5
6
|
SplashProvider
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PHT76VW6.js";
|
|
7
8
|
|
|
8
9
|
// src/providers/GavaEngineProvider.tsx
|
|
9
10
|
import { useRouter } from "next/navigation";
|
|
@@ -30,7 +31,7 @@ function GavaEngineProvider({
|
|
|
30
31
|
children
|
|
31
32
|
}) {
|
|
32
33
|
const router = useRouter();
|
|
33
|
-
return /* @__PURE__ */ jsx3(SessionProvider, { children: /* @__PURE__ */ jsx3(ThemeProvider, { children: /* @__PURE__ */ jsx3(ConfigProvider, { config, children: /* @__PURE__ */ jsx3(ActionsProvider, { actions, children: /* @__PURE__ */ jsx3(SplashProvider, { navigate: (url) => router.push(url), children }) }) }) }) });
|
|
34
|
+
return /* @__PURE__ */ jsx3(SessionProvider, { children: /* @__PURE__ */ jsx3(ThemeProvider, { children: /* @__PURE__ */ jsx3(ConfigProvider, { config, children: /* @__PURE__ */ jsx3(ActionsProvider, { actions, children: /* @__PURE__ */ jsx3(ComponentRegistryProvider, { overrides: config.components ?? {}, children: /* @__PURE__ */ jsx3(SplashProvider, { navigate: (url) => router.push(url), children }) }) }) }) }) });
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// src/providers/ThemeToggle.tsx
|
|
@@ -64,4 +65,4 @@ export {
|
|
|
64
65
|
GavaEngineProvider,
|
|
65
66
|
ThemeToggle
|
|
66
67
|
};
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
68
|
+
//# sourceMappingURL=chunk-3ZYJ4C6R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/GavaEngineProvider.tsx","../src/providers/SessionProvider.tsx","../src/providers/ThemeProvider.tsx","../src/providers/ThemeToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport { useRouter } from \"next/navigation\";\nimport { type GavaEngineConfig } from \"../config.js\";\nimport type { GEActions } from \"../types.js\";\nimport { ConfigProvider } from \"./ConfigContext.js\";\nimport { ActionsProvider } from \"./ActionsContext.js\";\nimport { SplashProvider } from \"./SplashContext.js\";\nimport { SessionProvider } from \"./SessionProvider.js\";\nimport { ThemeProvider } from \"./ThemeProvider.js\";\nimport { ComponentRegistryProvider } from \"../components/registry.js\";\n\ninterface GavaEngineProviderProps {\n config: GavaEngineConfig;\n actions: GEActions;\n children: ReactNode;\n}\n\nexport function GavaEngineProvider({\n config,\n actions,\n children,\n}: GavaEngineProviderProps) {\n const router = useRouter();\n\n return (\n <SessionProvider>\n <ThemeProvider>\n <ConfigProvider config={config}>\n <ActionsProvider actions={actions}>\n <ComponentRegistryProvider overrides={config.components ?? {}}>\n <SplashProvider navigate={(url) => router.push(url)}>\n {children}\n </SplashProvider>\n </ComponentRegistryProvider>\n </ActionsProvider>\n </ConfigProvider>\n </ThemeProvider>\n </SessionProvider>\n );\n}\n","\"use client\";\n\nimport { SessionProvider as NextAuthSessionProvider } from \"next-auth/react\";\nimport { type ReactNode } from \"react\";\n\nexport function SessionProvider({ children }: { children: ReactNode }) {\n return <NextAuthSessionProvider>{children}</NextAuthSessionProvider>;\n}\n","\"use client\";\n\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\nimport { type ReactNode } from \"react\";\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n return (\n <NextThemesProvider attribute=\"class\" defaultTheme=\"system\" enableSystem>\n {children}\n </NextThemesProvider>\n );\n}\n","\"use client\";\n\nimport { useTheme } from \"next-themes\";\nimport { useEffect, useState } from \"react\";\nimport { Sun, Moon } from \"lucide-react\";\n\nexport function ThemeToggle() {\n const [mounted, setMounted] = useState(false);\n const { theme, setTheme } = useTheme();\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!mounted) {\n return (\n <button className=\"p-2 rounded-lg bg-card border border-card-border\">\n <div className=\"w-5 h-5\" />\n </button>\n );\n }\n\n return (\n <button\n onClick={() => setTheme(theme === \"dark\" ? \"light\" : \"dark\")}\n className=\"p-2 rounded-lg bg-card border border-card-border hover:bg-card-border transition-colors\"\n aria-label=\"Toggle theme\"\n >\n {theme === \"dark\" ? (\n <Sun className=\"w-5 h-5 text-foreground\" />\n ) : (\n <Moon className=\"w-5 h-5 text-foreground\" />\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;AAGA,SAAS,iBAAiB;;;ACD1B,SAAS,mBAAmB,+BAA+B;AAIlD;AADF,SAAS,gBAAgB,EAAE,SAAS,GAA4B;AACrE,SAAO,oBAAC,2BAAyB,UAAS;AAC5C;;;ACLA,SAAS,iBAAiB,0BAA0B;AAKhD,gBAAAA,YAAA;AAFG,SAAS,cAAc,EAAE,SAAS,GAA4B;AACnE,SACE,gBAAAA,KAAC,sBAAmB,WAAU,SAAQ,cAAa,UAAS,cAAY,MACrE,UACH;AAEJ;;;AFqBc,gBAAAC,YAAA;AAbP,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,SAAS,UAAU;AAEzB,SACE,gBAAAA,KAAC,mBACC,0BAAAA,KAAC,iBACC,0BAAAA,KAAC,kBAAe,QACd,0BAAAA,KAAC,mBAAgB,SACf,0BAAAA,KAAC,6BAA0B,WAAW,OAAO,cAAc,CAAC,GAC1D,0BAAAA,KAAC,kBAAe,UAAU,CAAC,QAAQ,OAAO,KAAK,GAAG,GAC/C,UACH,GACF,GACF,GACF,GACF,GACF;AAEJ;;;AGvCA,SAAS,gBAAgB;AACzB,SAAS,WAAW,gBAAgB;AACpC,SAAS,KAAK,YAAY;AAalB,gBAAAC,YAAA;AAXD,SAAS,cAAc;AAC5B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,EAAE,OAAO,SAAS,IAAI,SAAS;AAErC,YAAU,MAAM;AACd,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,CAAC;AAEL,MAAI,CAAC,SAAS;AACZ,WACE,gBAAAA,KAAC,YAAO,WAAU,oDAChB,0BAAAA,KAAC,SAAI,WAAU,WAAU,GAC3B;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,MAAM,SAAS,UAAU,SAAS,UAAU,MAAM;AAAA,MAC3D,WAAU;AAAA,MACV,cAAW;AAAA,MAEV,oBAAU,SACT,gBAAAA,KAAC,OAAI,WAAU,2BAA0B,IAEzC,gBAAAA,KAAC,QAAK,WAAU,2BAA0B;AAAA;AAAA,EAE9C;AAEJ;","names":["jsx","jsx","jsx"]}
|
|
@@ -514,6 +514,27 @@ function SplashProvider({
|
|
|
514
514
|
return /* @__PURE__ */ jsx3(SplashContext.Provider, { value: { phase, navigateWithSplash, openSplash }, children });
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
+
// src/components/registry.tsx
|
|
518
|
+
import {
|
|
519
|
+
createContext as createContext4,
|
|
520
|
+
useContext as useContext4
|
|
521
|
+
} from "react";
|
|
522
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
523
|
+
var RegistryContext = createContext4({});
|
|
524
|
+
function ComponentRegistryProvider({
|
|
525
|
+
overrides,
|
|
526
|
+
children
|
|
527
|
+
}) {
|
|
528
|
+
return /* @__PURE__ */ jsx4(RegistryContext.Provider, { value: overrides, children });
|
|
529
|
+
}
|
|
530
|
+
function useRegisteredComponent(name, fallback) {
|
|
531
|
+
const registry = useContext4(RegistryContext);
|
|
532
|
+
return registry[name] ?? fallback;
|
|
533
|
+
}
|
|
534
|
+
function useComponentRegistry() {
|
|
535
|
+
return useContext4(RegistryContext);
|
|
536
|
+
}
|
|
537
|
+
|
|
517
538
|
export {
|
|
518
539
|
it,
|
|
519
540
|
en,
|
|
@@ -529,6 +550,9 @@ export {
|
|
|
529
550
|
useGavaActions,
|
|
530
551
|
ActionsProvider,
|
|
531
552
|
useSplash,
|
|
532
|
-
SplashProvider
|
|
553
|
+
SplashProvider,
|
|
554
|
+
ComponentRegistryProvider,
|
|
555
|
+
useRegisteredComponent,
|
|
556
|
+
useComponentRegistry
|
|
533
557
|
};
|
|
534
|
-
//# sourceMappingURL=chunk-
|
|
558
|
+
//# sourceMappingURL=chunk-PHT76VW6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/i18n/it.ts","../src/i18n/en.ts","../src/i18n/index.ts","../src/config.ts","../src/providers/ConfigContext.tsx","../src/providers/ActionsContext.tsx","../src/providers/SplashContext.tsx","../src/components/registry.tsx"],"sourcesContent":["import type { GELocale } from \"./types.js\";\n\nexport const it: GELocale = {\n content: {\n articles: \"Articoli\",\n newArticle: \"Nuovo articolo\",\n titlePlaceholder: \"Titolo dell'articolo\",\n excerptPlaceholder: \"Breve descrizione dell'articolo...\",\n slugPlaceholder: \"slug-articolo\",\n authorPlaceholder: \"Nome dell'autore\",\n category: \"Categoria\",\n selectCategory: \"Seleziona categoria\",\n excerpt: \"Estratto\",\n author: \"Autore\",\n slugUrl: \"Slug URL\",\n noArticles: \"Nessun articolo.\",\n noArticlesSearch: \"Nessun articolo trovato.\",\n searchArticles: \"Cerca articoli...\",\n coverImageLabel: \"Immagine di copertina\",\n coverImageHint: \"Scegli dalla libreria o carica un nuovo file\",\n viewArticle: \"Vedi articolo pubblicato\",\n untitled: \"Senza titolo\",\n },\n editor: {\n publish: \"Pubblica\",\n unpublish: \"Ritira\",\n saveDraft: \"Salva bozza\",\n revisions: \"Cronologia\",\n saving: \"Salvando...\",\n saved: \"Salvato\",\n saveError: \"Errore nel salvataggio\",\n noRevisions: \"Nessuna revisione salvata.\",\n restore: \"Ripristina\",\n restoreConfirm:\n \"Ripristinare questa revisione? Lo stato attuale verrà salvato prima del ripristino.\",\n beforeRestore: \"Prima del ripristino\",\n publishedNote: \"Pubblicato\",\n preview: \"Anteprima\",\n placeholder: \"Inizia a scrivere il tuo articolo...\",\n },\n media: {\n media: \"Media\",\n noMedia: \"Nessun file caricato.\",\n noMediaSearch: \"Nessun file trovato.\",\n chooseFile: \"Scegli file\",\n dragHint: \"Trascina un'immagine qui oppure\",\n uploadHint: \"JPEG, PNG, WebP, GIF (max 5MB)\",\n mediaLibrary: \"Libreria media\",\n uploadNew: \"Carica nuovo\",\n searchFiles: \"Cerca file...\",\n selectImage: \"Seleziona immagine\",\n noImages: \"Nessuna immagine nella libreria.\",\n noImagesSearch: \"Nessuna immagine trovata.\",\n copyUrl: \"Copia URL\",\n editImage: \"Modifica immagine\",\n restoreOriginal: \"Ripristina originale\",\n freeAspect: \"Libero\",\n },\n users: {\n users: \"Utenti\",\n name: \"Nome\",\n email: \"Email\",\n password: \"Password\",\n passwordEditHint: \" (lascia vuoto per non modificarla)\",\n role: \"Ruolo\",\n createdAt: \"Creato il\",\n actions: \"Azioni\",\n createUser: \"Crea utente\",\n unauthorized: \"Non autorizzato\",\n notAuthenticated: \"Non autenticato\",\n allFieldsRequired: \"Tutti i campi sono obbligatori.\",\n passwordMinLength: \"La password deve avere almeno 6 caratteri.\",\n emailExists: \"Esiste già un utente con questa email.\",\n invalidRole: \"Ruolo non valido.\",\n cannotDeleteSelf: \"Non puoi eliminare il tuo stesso account.\",\n },\n common: {\n statistics: \"Statistiche\",\n settings: \"Impostazioni\",\n delete: \"Elimina\",\n edit: \"Modifica\",\n search: \"Cerca\",\n draft: \"Bozza\",\n published: \"Pubblicato\",\n all: \"Tutti\",\n drafts: \"Bozze\",\n loading: \"Caricamento...\",\n confirm: \"Conferma\",\n cancel: \"Annulla\",\n apply: \"Applica\",\n change: \"Cambia\",\n logout: \"Esci\",\n saveChanges: \"Salva modifiche\",\n updated: \"Aggiornato\",\n status: \"Stato\",\n title: \"Titolo\",\n deleteConfirm: (title) => `Eliminare \"${title || \"Senza titolo\"}\"?`,\n unpublishConfirm: (title) =>\n `Ritirare \"${title || \"Senza titolo\"}\"? L'articolo tornerà in bozza.`,\n deleteUserConfirm: (name) =>\n `Sei sicuro di voler eliminare l'utente \"${name}\"?`,\n totalArticles: (count) =>\n `${count} articol${count === 1 ? \"o\" : \"i\"} totali`,\n totalFiles: (count) => `${count} file caricati`,\n },\n};\n","import type { GELocale } from \"./types.js\";\n\nexport const en: GELocale = {\n content: {\n articles: \"Articles\",\n newArticle: \"New article\",\n titlePlaceholder: \"Article title\",\n excerptPlaceholder: \"Brief description of the article...\",\n slugPlaceholder: \"article-slug\",\n authorPlaceholder: \"Author name\",\n category: \"Category\",\n selectCategory: \"Select category\",\n excerpt: \"Excerpt\",\n author: \"Author\",\n slugUrl: \"URL Slug\",\n noArticles: \"No articles.\",\n noArticlesSearch: \"No articles found.\",\n searchArticles: \"Search articles...\",\n coverImageLabel: \"Cover image\",\n coverImageHint: \"Choose from library or upload a new file\",\n viewArticle: \"View published article\",\n untitled: \"Untitled\",\n },\n editor: {\n publish: \"Publish\",\n unpublish: \"Unpublish\",\n saveDraft: \"Save draft\",\n revisions: \"History\",\n saving: \"Saving...\",\n saved: \"Saved\",\n saveError: \"Error saving\",\n noRevisions: \"No revisions saved.\",\n restore: \"Restore\",\n restoreConfirm:\n \"Restore this revision? The current state will be saved before restoring.\",\n beforeRestore: \"Before restore\",\n publishedNote: \"Published\",\n preview: \"Preview\",\n placeholder: \"Start writing your article...\",\n },\n media: {\n media: \"Media\",\n noMedia: \"No files uploaded.\",\n noMediaSearch: \"No files found.\",\n chooseFile: \"Choose file\",\n dragHint: \"Drag an image here or\",\n uploadHint: \"JPEG, PNG, WebP, GIF (max 5MB)\",\n mediaLibrary: \"Media library\",\n uploadNew: \"Upload new\",\n searchFiles: \"Search files...\",\n selectImage: \"Select image\",\n noImages: \"No images in library.\",\n noImagesSearch: \"No images found.\",\n copyUrl: \"Copy URL\",\n editImage: \"Edit image\",\n restoreOriginal: \"Restore original\",\n freeAspect: \"Free\",\n },\n users: {\n users: \"Users\",\n name: \"Name\",\n email: \"Email\",\n password: \"Password\",\n passwordEditHint: \" (leave blank to keep current)\",\n role: \"Role\",\n createdAt: \"Created at\",\n actions: \"Actions\",\n createUser: \"Create user\",\n unauthorized: \"Unauthorized\",\n notAuthenticated: \"Not authenticated\",\n allFieldsRequired: \"All fields are required.\",\n passwordMinLength: \"Password must be at least 6 characters.\",\n emailExists: \"A user with this email already exists.\",\n invalidRole: \"Invalid role.\",\n cannotDeleteSelf: \"You cannot delete your own account.\",\n },\n common: {\n statistics: \"Statistics\",\n settings: \"Settings\",\n delete: \"Delete\",\n edit: \"Edit\",\n search: \"Search\",\n draft: \"Draft\",\n published: \"Published\",\n all: \"All\",\n drafts: \"Drafts\",\n loading: \"Loading...\",\n confirm: \"Confirm\",\n cancel: \"Cancel\",\n apply: \"Apply\",\n change: \"Change\",\n logout: \"Logout\",\n saveChanges: \"Save changes\",\n updated: \"Updated\",\n status: \"Status\",\n title: \"Title\",\n deleteConfirm: (title) => `Delete \"${title || \"Untitled\"}\"?`,\n unpublishConfirm: (title) =>\n `Unpublish \"${title || \"Untitled\"}\"? The article will go back to draft.`,\n deleteUserConfirm: (name) =>\n `Are you sure you want to delete user \"${name}\"?`,\n totalArticles: (count) =>\n `${count} total article${count === 1 ? \"\" : \"s\"}`,\n totalFiles: (count) => `${count} uploaded file${count === 1 ? \"\" : \"s\"}`,\n },\n};\n","import type { GELocale } from \"./types.js\";\nimport { it } from \"./it.js\";\nimport { en } from \"./en.js\";\n\nexport type { GELocale } from \"./types.js\";\nexport { it } from \"./it.js\";\nexport { en } from \"./en.js\";\n\nconst builtinLocales: Record<string, GELocale> = { it, en };\n\nexport function loadLocale(locale: string): GELocale {\n const found = builtinLocales[locale];\n if (!found) {\n throw new Error(\n `Locale \"${locale}\" not found. Available: ${Object.keys(builtinLocales).join(\", \")}`\n );\n }\n return found;\n}\n\nexport function defineLocale(locale: GELocale): GELocale {\n return locale;\n}\n\nexport function mergeLocales(\n base: GELocale,\n overrides: DeepPartial<GELocale>\n): GELocale {\n return deepMergeLocale(base, overrides);\n}\n\nexport function registerLocale(key: string, locale: GELocale): void {\n builtinLocales[key] = locale;\n}\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends (...args: any[]) => any\n ? T[P]\n : T[P] extends object\n ? DeepPartial<T[P]>\n : T[P];\n};\n\nfunction deepMergeLocale<T extends Record<string, any>>(\n target: T,\n source: DeepPartial<T>\n): T {\n const result = { ...target };\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal) &&\n typeof sourceVal !== \"function\"\n ) {\n (result as any)[key] = deepMergeLocale(\n targetVal as Record<string, any>,\n sourceVal as Record<string, any>\n );\n } else if (sourceVal !== undefined) {\n (result as any)[key] = sourceVal;\n }\n }\n return result;\n}\n","import { loadLocale } from \"./i18n/index.js\";\nimport type { GELocale } from \"./i18n/types.js\";\nimport type { GEAuthAdapter } from \"./auth/types.js\";\nimport type { GEContentType } from \"./content/types.js\";\nimport type { GEComponentOverrides } from \"./components/registry.js\";\n\nexport interface GavaEngineConfig {\n branding: {\n name: string;\n logo?: string;\n };\n roles: {\n list: string[];\n labels: Record<string, string>;\n canEdit: (role: string) => boolean;\n canPublish: (role: string) => boolean;\n adminRole: string;\n };\n statuses: {\n draft: string;\n published: string;\n };\n locale: string;\n models: {\n article: string;\n articleRevision: string;\n articleView: string;\n media: string;\n user: string;\n };\n auth?: GEAuthAdapter;\n contentTypes?: GEContentType[];\n components?: GEComponentOverrides;\n categories: string[];\n upload: {\n endpoint: string;\n imageTypes: string[];\n videoTypes: string[];\n maxImageSize: number;\n maxVideoSize: number;\n };\n editor: {\n placeholder: string;\n autoSaveDelay: number;\n revisionThrottleMinutes: number;\n headingLevels: number[];\n };\n routes: {\n articles: string;\n articleEdit: (id: string) => string;\n articleNew: string;\n articleView: (slug: string) => string;\n articlePreview: (id: string) => string;\n users: string;\n userEdit: (id: string) => string;\n userNew: string;\n media: string;\n dashboard: string;\n login: string;\n home: string;\n };\n strings: {\n articles: string;\n newArticle: string;\n media: string;\n users: string;\n statistics: string;\n settings: string;\n revisions: string;\n publish: string;\n unpublish: string;\n saveDraft: string;\n delete: string;\n edit: string;\n search: string;\n titlePlaceholder: string;\n excerptPlaceholder: string;\n slugPlaceholder: string;\n authorPlaceholder: string;\n category: string;\n selectCategory: string;\n excerpt: string;\n author: string;\n slugUrl: string;\n draft: string;\n published: string;\n all: string;\n drafts: string;\n saving: string;\n saved: string;\n saveError: string;\n noArticles: string;\n noArticlesSearch: string;\n noMedia: string;\n noMediaSearch: string;\n noRevisions: string;\n loading: string;\n confirm: string;\n cancel: string;\n apply: string;\n change: string;\n logout: string;\n viewArticle: string;\n preview: string;\n restore: string;\n restoreConfirm: string;\n beforeRestore: string;\n publishedNote: string;\n deleteConfirm: (title: string) => string;\n unpublishConfirm: (title: string) => string;\n deleteUserConfirm: (name: string) => string;\n totalArticles: (count: number) => string;\n totalFiles: (count: number) => string;\n coverImageLabel: string;\n coverImageHint: string;\n chooseFile: string;\n dragHint: string;\n uploadHint: string;\n mediaLibrary: string;\n uploadNew: string;\n searchFiles: string;\n searchArticles: string;\n selectImage: string;\n noImages: string;\n noImagesSearch: string;\n copyUrl: string;\n editImage: string;\n restoreOriginal: string;\n freeAspect: string;\n unauthorized: string;\n notAuthenticated: string;\n allFieldsRequired: string;\n passwordMinLength: string;\n emailExists: string;\n invalidRole: string;\n cannotDeleteSelf: string;\n name: string;\n email: string;\n password: string;\n passwordEditHint: string;\n role: string;\n createdAt: string;\n actions: string;\n createUser: string;\n saveChanges: string;\n updated: string;\n status: string;\n title: string;\n untitled: string;\n };\n}\n\nfunction localeToStrings(locale: GELocale): GavaEngineConfig[\"strings\"] {\n return {\n // content\n articles: locale.content.articles,\n newArticle: locale.content.newArticle,\n titlePlaceholder: locale.content.titlePlaceholder,\n excerptPlaceholder: locale.content.excerptPlaceholder,\n slugPlaceholder: locale.content.slugPlaceholder,\n authorPlaceholder: locale.content.authorPlaceholder,\n category: locale.content.category,\n selectCategory: locale.content.selectCategory,\n excerpt: locale.content.excerpt,\n author: locale.content.author,\n slugUrl: locale.content.slugUrl,\n noArticles: locale.content.noArticles,\n noArticlesSearch: locale.content.noArticlesSearch,\n searchArticles: locale.content.searchArticles,\n coverImageLabel: locale.content.coverImageLabel,\n coverImageHint: locale.content.coverImageHint,\n viewArticle: locale.content.viewArticle,\n untitled: locale.content.untitled,\n // editor\n publish: locale.editor.publish,\n unpublish: locale.editor.unpublish,\n saveDraft: locale.editor.saveDraft,\n revisions: locale.editor.revisions,\n saving: locale.editor.saving,\n saved: locale.editor.saved,\n saveError: locale.editor.saveError,\n noRevisions: locale.editor.noRevisions,\n restore: locale.editor.restore,\n restoreConfirm: locale.editor.restoreConfirm,\n beforeRestore: locale.editor.beforeRestore,\n publishedNote: locale.editor.publishedNote,\n preview: locale.editor.preview,\n // media\n media: locale.media.media,\n noMedia: locale.media.noMedia,\n noMediaSearch: locale.media.noMediaSearch,\n chooseFile: locale.media.chooseFile,\n dragHint: locale.media.dragHint,\n uploadHint: locale.media.uploadHint,\n mediaLibrary: locale.media.mediaLibrary,\n uploadNew: locale.media.uploadNew,\n searchFiles: locale.media.searchFiles,\n selectImage: locale.media.selectImage,\n noImages: locale.media.noImages,\n noImagesSearch: locale.media.noImagesSearch,\n copyUrl: locale.media.copyUrl,\n editImage: locale.media.editImage,\n restoreOriginal: locale.media.restoreOriginal,\n freeAspect: locale.media.freeAspect,\n // users\n users: locale.users.users,\n name: locale.users.name,\n email: locale.users.email,\n password: locale.users.password,\n passwordEditHint: locale.users.passwordEditHint,\n role: locale.users.role,\n createdAt: locale.users.createdAt,\n actions: locale.users.actions,\n createUser: locale.users.createUser,\n unauthorized: locale.users.unauthorized,\n notAuthenticated: locale.users.notAuthenticated,\n allFieldsRequired: locale.users.allFieldsRequired,\n passwordMinLength: locale.users.passwordMinLength,\n emailExists: locale.users.emailExists,\n invalidRole: locale.users.invalidRole,\n cannotDeleteSelf: locale.users.cannotDeleteSelf,\n // common\n statistics: locale.common.statistics,\n settings: locale.common.settings,\n delete: locale.common.delete,\n edit: locale.common.edit,\n search: locale.common.search,\n draft: locale.common.draft,\n published: locale.common.published,\n all: locale.common.all,\n drafts: locale.common.drafts,\n loading: locale.common.loading,\n confirm: locale.common.confirm,\n cancel: locale.common.cancel,\n apply: locale.common.apply,\n change: locale.common.change,\n logout: locale.common.logout,\n saveChanges: locale.common.saveChanges,\n updated: locale.common.updated,\n status: locale.common.status,\n title: locale.common.title,\n deleteConfirm: locale.common.deleteConfirm,\n unpublishConfirm: locale.common.unpublishConfirm,\n deleteUserConfirm: locale.common.deleteUserConfirm,\n totalArticles: locale.common.totalArticles,\n totalFiles: locale.common.totalFiles,\n };\n}\n\nconst DEFAULT_STRINGS = localeToStrings(loadLocale(\"it\"));\n\nconst DEFAULT_CONFIG: GavaEngineConfig = {\n branding: {\n name: \"GavaEngine\",\n },\n roles: {\n list: [\"admin\", \"redattore\", \"scrittore\", \"lettore\"],\n labels: {\n admin: \"Amministratore\",\n redattore: \"Redattore\",\n scrittore: \"Scrittore\",\n lettore: \"Lettore\",\n },\n canEdit: (role: string) => role !== \"lettore\",\n canPublish: (role: string) => role === \"admin\" || role === \"redattore\",\n adminRole: \"admin\",\n },\n statuses: {\n draft: \"bozza\",\n published: \"pubblicato\",\n },\n locale: \"it\",\n models: {\n article: \"article\",\n articleRevision: \"articleRevision\",\n articleView: \"articleView\",\n media: \"media\",\n user: \"user\",\n },\n categories: [\n \"Cultura ed Intercultura\",\n \"Fatti ed Eventi\",\n \"Poeti e Prosatori\",\n \"Famiglia, Istituzioni e Territorio\",\n \"Amici del Meucci\",\n ],\n upload: {\n endpoint: \"/api/upload\",\n imageTypes: [\"image/jpeg\", \"image/png\", \"image/webp\", \"image/gif\"],\n videoTypes: [\"video/mp4\", \"video/webm\", \"video/quicktime\"],\n maxImageSize: 5 * 1024 * 1024,\n maxVideoSize: 50 * 1024 * 1024,\n },\n editor: {\n placeholder: \"Inizia a scrivere il tuo articolo...\",\n autoSaveDelay: 2000,\n revisionThrottleMinutes: 5,\n headingLevels: [2, 3],\n },\n routes: {\n articles: \"/dashboard/articoli\",\n articleEdit: (id) => `/dashboard/articoli/${id}`,\n articleNew: \"/dashboard/articoli/nuovo\",\n articleView: (slug) => `/articoli/${slug}`,\n articlePreview: (id) => `/anteprima/${id}`,\n users: \"/dashboard/utenti\",\n userEdit: (id) => `/dashboard/utenti/${id}`,\n userNew: \"/dashboard/utenti/nuovo\",\n media: \"/dashboard/media\",\n dashboard: \"/dashboard\",\n login: \"/login\",\n home: \"/\",\n },\n strings: DEFAULT_STRINGS,\n};\n\nfunction deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal) &&\n typeof sourceVal !== \"function\"\n ) {\n (result as any)[key] = deepMerge(\n targetVal as Record<string, any>,\n sourceVal as Record<string, any>\n );\n } else if (sourceVal !== undefined) {\n (result as any)[key] = sourceVal;\n }\n }\n return result;\n}\n\nexport function defineConfig(\n overrides: Partial<GavaEngineConfig> = {}\n): GavaEngineConfig {\n // If a different locale is specified, load it as base strings\n const locale = overrides.locale ?? DEFAULT_CONFIG.locale;\n const baseStrings = localeToStrings(loadLocale(locale));\n\n // Build config with locale-based strings as default\n const configWithLocale = {\n ...DEFAULT_CONFIG,\n strings: baseStrings,\n };\n\n // Also update editor.placeholder from locale if not overridden\n if (!overrides.editor?.placeholder) {\n const localeData = loadLocale(locale);\n configWithLocale.editor = {\n ...configWithLocale.editor,\n placeholder: localeData.editor.placeholder,\n };\n }\n\n return deepMerge(configWithLocale, overrides);\n}\n\nexport { DEFAULT_CONFIG, localeToStrings };\n","\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport { type GavaEngineConfig, DEFAULT_CONFIG } from \"../config.js\";\n\nconst ConfigContext = createContext<GavaEngineConfig>(DEFAULT_CONFIG);\n\nexport function useGavaConfig() {\n return useContext(ConfigContext);\n}\n\nexport function ConfigProvider({\n config,\n children,\n}: {\n config: GavaEngineConfig;\n children: ReactNode;\n}) {\n return (\n <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>\n );\n}\n","\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport type { GEActions } from \"../types.js\";\n\nconst ActionsContext = createContext<GEActions | null>(null);\n\nexport function useGavaActions(): GEActions {\n const ctx = useContext(ActionsContext);\n if (!ctx) {\n throw new Error(\n \"useGavaActions must be used within a <GavaEngineProvider> with actions provided.\"\n );\n }\n return ctx;\n}\n\nexport function ActionsProvider({\n actions,\n children,\n}: {\n actions: GEActions;\n children: ReactNode;\n}) {\n return (\n <ActionsContext.Provider value={actions}>{children}</ActionsContext.Provider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useState,\n useCallback,\n type ReactNode,\n} from \"react\";\n\ntype Phase = \"idle\" | \"closing\" | \"closed\" | \"opening\";\n\ninterface SplashContextValue {\n phase: Phase;\n navigateWithSplash: (url: string) => void;\n openSplash: () => void;\n}\n\nconst SplashContext = createContext<SplashContextValue>({\n phase: \"idle\",\n navigateWithSplash: () => {},\n openSplash: () => {},\n});\n\nexport function useSplash() {\n return useContext(SplashContext);\n}\n\nexport function SplashProvider({\n children,\n navigate,\n}: {\n children: ReactNode;\n navigate: (url: string) => void;\n}) {\n const [phase, setPhase] = useState<Phase>(\"idle\");\n\n const navigateWithSplash = useCallback(\n (url: string) => {\n if (phase !== \"idle\") return;\n setPhase(\"closing\");\n\n setTimeout(() => {\n setPhase(\"closed\");\n navigate(url);\n }, 700);\n },\n [phase, navigate]\n );\n\n const openSplash = useCallback(() => {\n if (phase !== \"closed\") return;\n requestAnimationFrame(() => {\n setPhase(\"opening\");\n setTimeout(() => setPhase(\"idle\"), 900);\n });\n }, [phase]);\n\n return (\n <SplashContext.Provider value={{ phase, navigateWithSplash, openSplash }}>\n {children}\n </SplashContext.Provider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport type { ContentEditorProps } from \"./content/ContentEditor.js\";\nimport type { ContentListProps } from \"./content/ContentList.js\";\n\nexport interface GEComponentOverrides {\n DashboardNavbar?: ComponentType<any>;\n DashboardLayout?: ComponentType<{ children: ReactNode }>;\n EditorToolbar?: ComponentType<{ editor: any }>;\n ContentEditor?: ComponentType<ContentEditorProps>;\n ContentList?: ComponentType<ContentListProps>;\n MediaGrid?: ComponentType<any>;\n UserTable?: ComponentType<any>;\n LoginPage?: ComponentType<any>;\n StatCard?: ComponentType<any>;\n}\n\nconst RegistryContext = createContext<GEComponentOverrides>({});\n\nexport function ComponentRegistryProvider({\n overrides,\n children,\n}: {\n overrides: GEComponentOverrides;\n children: ReactNode;\n}) {\n return (\n <RegistryContext.Provider value={overrides}>\n {children}\n </RegistryContext.Provider>\n );\n}\n\nexport function useRegisteredComponent<K extends keyof GEComponentOverrides>(\n name: K,\n fallback: NonNullable<GEComponentOverrides[K]>\n): NonNullable<GEComponentOverrides[K]> {\n const registry = useContext(RegistryContext);\n return (registry[name] as NonNullable<GEComponentOverrides[K]>) ?? fallback;\n}\n\nexport function useComponentRegistry(): GEComponentOverrides {\n return useContext(RegistryContext);\n}\n"],"mappings":"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","names":["createContext","useContext","jsx","createContext","useContext","jsx","createContext","useContext","jsx"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
useGavaActions,
|
|
4
4
|
useGavaConfig,
|
|
5
5
|
useSplash
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PHT76VW6.js";
|
|
7
7
|
|
|
8
8
|
// src/components/editor/ArticleEditor.tsx
|
|
9
9
|
import { useState as useState6, useEffect as useEffect4, useCallback as useCallback4, useRef as useRef3 } from "react";
|
|
@@ -2858,17 +2858,138 @@ function ContentList({
|
|
|
2858
2858
|
] });
|
|
2859
2859
|
}
|
|
2860
2860
|
|
|
2861
|
+
// src/components/categories/CategoryManager.tsx
|
|
2862
|
+
import { useState as useState14, useEffect as useEffect7, useCallback as useCallback10 } from "react";
|
|
2863
|
+
import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2864
|
+
function CategoryManager({
|
|
2865
|
+
getCategories,
|
|
2866
|
+
createCategory,
|
|
2867
|
+
updateCategory,
|
|
2868
|
+
deleteCategory
|
|
2869
|
+
}) {
|
|
2870
|
+
const [categories, setCategories] = useState14([]);
|
|
2871
|
+
const [newName, setNewName] = useState14("");
|
|
2872
|
+
const [editingId, setEditingId] = useState14(null);
|
|
2873
|
+
const [editName, setEditName] = useState14("");
|
|
2874
|
+
const load = useCallback10(async () => {
|
|
2875
|
+
const cats = await getCategories();
|
|
2876
|
+
setCategories(cats);
|
|
2877
|
+
}, [getCategories]);
|
|
2878
|
+
useEffect7(() => {
|
|
2879
|
+
load();
|
|
2880
|
+
}, [load]);
|
|
2881
|
+
const handleCreate = async () => {
|
|
2882
|
+
if (!newName.trim()) return;
|
|
2883
|
+
await createCategory({ name: newName.trim() });
|
|
2884
|
+
setNewName("");
|
|
2885
|
+
load();
|
|
2886
|
+
};
|
|
2887
|
+
const handleUpdate = async (id) => {
|
|
2888
|
+
if (!editName.trim()) return;
|
|
2889
|
+
await updateCategory(id, { name: editName.trim() });
|
|
2890
|
+
setEditingId(null);
|
|
2891
|
+
load();
|
|
2892
|
+
};
|
|
2893
|
+
const handleDelete = async (id, name) => {
|
|
2894
|
+
if (!confirm(`Delete category "${name}"?`)) return;
|
|
2895
|
+
await deleteCategory(id);
|
|
2896
|
+
load();
|
|
2897
|
+
};
|
|
2898
|
+
return /* @__PURE__ */ jsxs22("div", { className: "ge-category-manager", children: [
|
|
2899
|
+
/* @__PURE__ */ jsx24("h2", { children: "Categories" }),
|
|
2900
|
+
/* @__PURE__ */ jsxs22("div", { className: "ge-category-create", style: { display: "flex", gap: "0.5rem", marginBottom: "1rem" }, children: [
|
|
2901
|
+
/* @__PURE__ */ jsx24(
|
|
2902
|
+
"input",
|
|
2903
|
+
{
|
|
2904
|
+
type: "text",
|
|
2905
|
+
value: newName,
|
|
2906
|
+
onChange: (e) => setNewName(e.target.value),
|
|
2907
|
+
placeholder: "New category name",
|
|
2908
|
+
className: "ge-field-input",
|
|
2909
|
+
onKeyDown: (e) => e.key === "Enter" && handleCreate(),
|
|
2910
|
+
style: { flex: 1 }
|
|
2911
|
+
}
|
|
2912
|
+
),
|
|
2913
|
+
/* @__PURE__ */ jsx24("button", { onClick: handleCreate, className: "ge-btn ge-btn-primary", children: "Add" })
|
|
2914
|
+
] }),
|
|
2915
|
+
/* @__PURE__ */ jsx24("ul", { className: "ge-category-list", style: { listStyle: "none", padding: 0 }, children: categories.map((cat) => /* @__PURE__ */ jsx24(
|
|
2916
|
+
"li",
|
|
2917
|
+
{
|
|
2918
|
+
style: {
|
|
2919
|
+
display: "flex",
|
|
2920
|
+
alignItems: "center",
|
|
2921
|
+
gap: "0.5rem",
|
|
2922
|
+
padding: "0.5rem 0",
|
|
2923
|
+
borderBottom: "1px solid var(--ge-card-border, #e5e7eb)"
|
|
2924
|
+
},
|
|
2925
|
+
children: editingId === cat.id ? /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
2926
|
+
/* @__PURE__ */ jsx24(
|
|
2927
|
+
"input",
|
|
2928
|
+
{
|
|
2929
|
+
type: "text",
|
|
2930
|
+
value: editName,
|
|
2931
|
+
onChange: (e) => setEditName(e.target.value),
|
|
2932
|
+
className: "ge-field-input",
|
|
2933
|
+
style: { flex: 1 },
|
|
2934
|
+
onKeyDown: (e) => e.key === "Enter" && handleUpdate(cat.id),
|
|
2935
|
+
autoFocus: true
|
|
2936
|
+
}
|
|
2937
|
+
),
|
|
2938
|
+
/* @__PURE__ */ jsx24(
|
|
2939
|
+
"button",
|
|
2940
|
+
{
|
|
2941
|
+
onClick: () => handleUpdate(cat.id),
|
|
2942
|
+
className: "ge-btn ge-btn-small",
|
|
2943
|
+
children: "Save"
|
|
2944
|
+
}
|
|
2945
|
+
),
|
|
2946
|
+
/* @__PURE__ */ jsx24(
|
|
2947
|
+
"button",
|
|
2948
|
+
{
|
|
2949
|
+
onClick: () => setEditingId(null),
|
|
2950
|
+
className: "ge-btn ge-btn-small",
|
|
2951
|
+
children: "Cancel"
|
|
2952
|
+
}
|
|
2953
|
+
)
|
|
2954
|
+
] }) : /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
2955
|
+
/* @__PURE__ */ jsx24("span", { style: { flex: 1 }, children: cat.name }),
|
|
2956
|
+
/* @__PURE__ */ jsx24(
|
|
2957
|
+
"button",
|
|
2958
|
+
{
|
|
2959
|
+
onClick: () => {
|
|
2960
|
+
setEditingId(cat.id);
|
|
2961
|
+
setEditName(cat.name);
|
|
2962
|
+
},
|
|
2963
|
+
className: "ge-btn ge-btn-small",
|
|
2964
|
+
children: "Edit"
|
|
2965
|
+
}
|
|
2966
|
+
),
|
|
2967
|
+
/* @__PURE__ */ jsx24(
|
|
2968
|
+
"button",
|
|
2969
|
+
{
|
|
2970
|
+
onClick: () => handleDelete(cat.id, cat.name),
|
|
2971
|
+
className: "ge-btn ge-btn-small ge-btn-danger",
|
|
2972
|
+
children: "Delete"
|
|
2973
|
+
}
|
|
2974
|
+
)
|
|
2975
|
+
] })
|
|
2976
|
+
},
|
|
2977
|
+
cat.id
|
|
2978
|
+
)) })
|
|
2979
|
+
] });
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2861
2982
|
// src/components/dashboard/DashboardNavbar.tsx
|
|
2862
2983
|
import Link4 from "next/link";
|
|
2863
2984
|
import { usePathname } from "next/navigation";
|
|
2864
2985
|
import { useSession, signOut } from "next-auth/react";
|
|
2865
2986
|
import { FileText as FileText3, Users, LogOut, BarChart3, ImageIcon as ImageIcon3 } from "lucide-react";
|
|
2866
|
-
import { useState as
|
|
2867
|
-
import { jsx as
|
|
2987
|
+
import { useState as useState15 } from "react";
|
|
2988
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2868
2989
|
function DashboardNavbar() {
|
|
2869
2990
|
const pathname = usePathname();
|
|
2870
2991
|
const { data: session } = useSession();
|
|
2871
|
-
const [mobileOpen, setMobileOpen] =
|
|
2992
|
+
const [mobileOpen, setMobileOpen] = useState15(false);
|
|
2872
2993
|
const { branding, roles, strings, routes } = useGavaConfig();
|
|
2873
2994
|
const role = session?.user?.role;
|
|
2874
2995
|
const navigation = [
|
|
@@ -2884,10 +3005,10 @@ function DashboardNavbar() {
|
|
|
2884
3005
|
...role === roles.adminRole ? [{ name: strings.users, href: routes.users, icon: Users }] : []
|
|
2885
3006
|
];
|
|
2886
3007
|
const isActive = (href) => pathname.startsWith(href);
|
|
2887
|
-
return /* @__PURE__ */
|
|
2888
|
-
/* @__PURE__ */
|
|
2889
|
-
/* @__PURE__ */
|
|
2890
|
-
branding.logo && /* @__PURE__ */
|
|
3008
|
+
return /* @__PURE__ */ jsx25("header", { className: "sticky top-0 z-50 px-4 pb-4", children: /* @__PURE__ */ jsx25("div", { className: "mx-auto max-w-7xl", children: /* @__PURE__ */ jsxs23("nav", { className: "bg-background/95 backdrop-blur-sm border border-t-transparent border-card-border rounded-b-xl", children: [
|
|
3009
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex h-14 items-center justify-between px-6", children: [
|
|
3010
|
+
/* @__PURE__ */ jsxs23(Link4, { href: routes.home, className: "flex items-center gap-3", children: [
|
|
3011
|
+
branding.logo && /* @__PURE__ */ jsx25("span", { className: "relative z-[9999] -my-[100px] py-[100px] bg-white rounded-b-lg px-1.5 pb-1.5", children: /* @__PURE__ */ jsx25(
|
|
2891
3012
|
"img",
|
|
2892
3013
|
{
|
|
2893
3014
|
src: branding.logo,
|
|
@@ -2896,36 +3017,36 @@ function DashboardNavbar() {
|
|
|
2896
3017
|
height: 44
|
|
2897
3018
|
}
|
|
2898
3019
|
) }),
|
|
2899
|
-
/* @__PURE__ */
|
|
3020
|
+
/* @__PURE__ */ jsx25("span", { className: "font-bold text-lg text-foreground", children: branding.name })
|
|
2900
3021
|
] }),
|
|
2901
|
-
/* @__PURE__ */
|
|
3022
|
+
/* @__PURE__ */ jsx25("div", { className: "hidden md:flex md:items-center md:gap-6", children: navigation.map((item) => /* @__PURE__ */ jsxs23(
|
|
2902
3023
|
Link4,
|
|
2903
3024
|
{
|
|
2904
3025
|
href: item.href,
|
|
2905
3026
|
className: `flex items-center gap-2 text-sm font-medium transition-colors ${isActive(item.href) ? "text-accent" : "text-muted hover:text-foreground"}`,
|
|
2906
3027
|
children: [
|
|
2907
|
-
/* @__PURE__ */
|
|
3028
|
+
/* @__PURE__ */ jsx25(item.icon, { className: "w-4 h-4" }),
|
|
2908
3029
|
item.name
|
|
2909
3030
|
]
|
|
2910
3031
|
},
|
|
2911
3032
|
item.name
|
|
2912
3033
|
)) }),
|
|
2913
|
-
/* @__PURE__ */
|
|
2914
|
-
/* @__PURE__ */
|
|
2915
|
-
/* @__PURE__ */
|
|
2916
|
-
/* @__PURE__ */
|
|
3034
|
+
/* @__PURE__ */ jsxs23("div", { className: "hidden md:flex md:items-center md:gap-3", children: [
|
|
3035
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-right", children: [
|
|
3036
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm font-medium text-foreground leading-tight", children: session?.user?.name }),
|
|
3037
|
+
/* @__PURE__ */ jsx25("p", { className: "text-xs text-muted leading-tight", children: roles.labels[role || ""] || role })
|
|
2917
3038
|
] }),
|
|
2918
|
-
/* @__PURE__ */
|
|
3039
|
+
/* @__PURE__ */ jsx25(
|
|
2919
3040
|
"button",
|
|
2920
3041
|
{
|
|
2921
3042
|
onClick: () => signOut({ callbackUrl: routes.login }),
|
|
2922
3043
|
className: "p-2 rounded-full text-muted hover:text-foreground hover:bg-card transition-colors",
|
|
2923
3044
|
title: strings.logout,
|
|
2924
|
-
children: /* @__PURE__ */
|
|
3045
|
+
children: /* @__PURE__ */ jsx25(LogOut, { className: "w-4 h-4" })
|
|
2925
3046
|
}
|
|
2926
3047
|
)
|
|
2927
3048
|
] }),
|
|
2928
|
-
/* @__PURE__ */
|
|
3049
|
+
/* @__PURE__ */ jsxs23(
|
|
2929
3050
|
"button",
|
|
2930
3051
|
{
|
|
2931
3052
|
type: "button",
|
|
@@ -2933,19 +3054,19 @@ function DashboardNavbar() {
|
|
|
2933
3054
|
className: "md:hidden p-2 rounded-full text-foreground flex flex-col justify-center items-center w-10 h-10 gap-1.5",
|
|
2934
3055
|
"aria-label": "Menu",
|
|
2935
3056
|
children: [
|
|
2936
|
-
/* @__PURE__ */
|
|
3057
|
+
/* @__PURE__ */ jsx25(
|
|
2937
3058
|
"span",
|
|
2938
3059
|
{
|
|
2939
3060
|
className: `block h-0.5 w-5 bg-foreground rounded-full transition-all duration-300 ease-in-out ${mobileOpen ? "rotate-45 translate-y-2" : ""}`
|
|
2940
3061
|
}
|
|
2941
3062
|
),
|
|
2942
|
-
/* @__PURE__ */
|
|
3063
|
+
/* @__PURE__ */ jsx25(
|
|
2943
3064
|
"span",
|
|
2944
3065
|
{
|
|
2945
3066
|
className: `block h-0.5 w-5 bg-foreground rounded-full transition-all duration-300 ease-in-out ${mobileOpen ? "opacity-0 scale-0" : ""}`
|
|
2946
3067
|
}
|
|
2947
3068
|
),
|
|
2948
|
-
/* @__PURE__ */
|
|
3069
|
+
/* @__PURE__ */ jsx25(
|
|
2949
3070
|
"span",
|
|
2950
3071
|
{
|
|
2951
3072
|
className: `block h-0.5 w-5 bg-foreground rounded-full transition-all duration-300 ease-in-out ${mobileOpen ? "-rotate-45 -translate-y-2" : ""}`
|
|
@@ -2955,36 +3076,36 @@ function DashboardNavbar() {
|
|
|
2955
3076
|
}
|
|
2956
3077
|
)
|
|
2957
3078
|
] }),
|
|
2958
|
-
/* @__PURE__ */
|
|
3079
|
+
/* @__PURE__ */ jsx25(
|
|
2959
3080
|
"div",
|
|
2960
3081
|
{
|
|
2961
3082
|
className: `md:hidden overflow-hidden transition-all duration-300 ease-in-out ${mobileOpen ? "max-h-80 opacity-100" : "max-h-0 opacity-0"}`,
|
|
2962
|
-
children: /* @__PURE__ */
|
|
2963
|
-
navigation.map((item) => /* @__PURE__ */
|
|
3083
|
+
children: /* @__PURE__ */ jsxs23("div", { className: "py-4 border-t border-card-border mx-6 space-y-1", children: [
|
|
3084
|
+
navigation.map((item) => /* @__PURE__ */ jsxs23(
|
|
2964
3085
|
Link4,
|
|
2965
3086
|
{
|
|
2966
3087
|
href: item.href,
|
|
2967
3088
|
onClick: () => setMobileOpen(false),
|
|
2968
3089
|
className: `flex items-center gap-3 px-3 py-2 rounded-full text-sm font-medium transition-colors ${isActive(item.href) ? "text-accent" : "text-muted hover:text-foreground"}`,
|
|
2969
3090
|
children: [
|
|
2970
|
-
/* @__PURE__ */
|
|
3091
|
+
/* @__PURE__ */ jsx25(item.icon, { className: "w-4 h-4" }),
|
|
2971
3092
|
item.name
|
|
2972
3093
|
]
|
|
2973
3094
|
},
|
|
2974
3095
|
item.name
|
|
2975
3096
|
)),
|
|
2976
|
-
/* @__PURE__ */
|
|
2977
|
-
/* @__PURE__ */
|
|
2978
|
-
/* @__PURE__ */
|
|
2979
|
-
/* @__PURE__ */
|
|
3097
|
+
/* @__PURE__ */ jsxs23("div", { className: "pt-3 mt-2 border-t border-card-border", children: [
|
|
3098
|
+
/* @__PURE__ */ jsxs23("div", { className: "px-3 mb-2", children: [
|
|
3099
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm font-medium text-foreground", children: session?.user?.name }),
|
|
3100
|
+
/* @__PURE__ */ jsx25("p", { className: "text-xs text-muted", children: roles.labels[role || ""] || role })
|
|
2980
3101
|
] }),
|
|
2981
|
-
/* @__PURE__ */
|
|
3102
|
+
/* @__PURE__ */ jsxs23(
|
|
2982
3103
|
"button",
|
|
2983
3104
|
{
|
|
2984
3105
|
onClick: () => signOut({ callbackUrl: routes.login }),
|
|
2985
3106
|
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted hover:text-foreground transition-colors w-full rounded-full hover:bg-card",
|
|
2986
3107
|
children: [
|
|
2987
|
-
/* @__PURE__ */
|
|
3108
|
+
/* @__PURE__ */ jsx25(LogOut, { className: "w-4 h-4" }),
|
|
2988
3109
|
strings.logout
|
|
2989
3110
|
]
|
|
2990
3111
|
}
|
|
@@ -2997,7 +3118,7 @@ function DashboardNavbar() {
|
|
|
2997
3118
|
}
|
|
2998
3119
|
|
|
2999
3120
|
// src/components/dashboard/StatCard.tsx
|
|
3000
|
-
import { jsx as
|
|
3121
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3001
3122
|
var accentStyles = {
|
|
3002
3123
|
blue: {
|
|
3003
3124
|
border: "border-l-blue-500",
|
|
@@ -3027,23 +3148,23 @@ function StatCard({
|
|
|
3027
3148
|
accent = "blue"
|
|
3028
3149
|
}) {
|
|
3029
3150
|
const s = accentStyles[accent];
|
|
3030
|
-
return /* @__PURE__ */
|
|
3151
|
+
return /* @__PURE__ */ jsx26(
|
|
3031
3152
|
"div",
|
|
3032
3153
|
{
|
|
3033
3154
|
className: `bg-card border border-card-border rounded-xl p-5 border-l-[3px] ${s.border} transition-all duration-200 hover:shadow-sm`,
|
|
3034
|
-
children: /* @__PURE__ */
|
|
3035
|
-
/* @__PURE__ */
|
|
3036
|
-
/* @__PURE__ */
|
|
3037
|
-
/* @__PURE__ */
|
|
3155
|
+
children: /* @__PURE__ */ jsxs24("div", { className: "flex items-start justify-between", children: [
|
|
3156
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
3157
|
+
/* @__PURE__ */ jsx26("p", { className: "text-xs font-medium text-muted uppercase tracking-wide mb-2", children: label }),
|
|
3158
|
+
/* @__PURE__ */ jsx26("p", { className: "text-3xl font-bold text-foreground tabular-nums", children: value })
|
|
3038
3159
|
] }),
|
|
3039
|
-
/* @__PURE__ */
|
|
3160
|
+
/* @__PURE__ */ jsx26("div", { className: `p-2 rounded-lg ${s.bg}`, children: /* @__PURE__ */ jsx26(Icon, { className: `w-5 h-5 ${s.text}` }) })
|
|
3040
3161
|
] })
|
|
3041
3162
|
}
|
|
3042
3163
|
);
|
|
3043
3164
|
}
|
|
3044
3165
|
|
|
3045
3166
|
// src/components/splash/SplashScreen.tsx
|
|
3046
|
-
import { jsx as
|
|
3167
|
+
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3047
3168
|
var SPLASH_WORDS = ["Powerful", "Flexible", "Modular", "Secure", "Customizable"];
|
|
3048
3169
|
function pickRandom3() {
|
|
3049
3170
|
const shuffled = [...SPLASH_WORDS].sort(() => Math.random() - 0.5);
|
|
@@ -3055,28 +3176,28 @@ function SplashScreen() {
|
|
|
3055
3176
|
if (phase === "idle") return null;
|
|
3056
3177
|
const topClass = phase === "closing" ? "splash-enter-down" : phase === "opening" ? "splash-exit-up" : "";
|
|
3057
3178
|
const bottomClass = phase === "closing" ? "splash-enter-up" : phase === "opening" ? "splash-exit-down" : "";
|
|
3058
|
-
return /* @__PURE__ */
|
|
3059
|
-
/* @__PURE__ */
|
|
3179
|
+
return /* @__PURE__ */ jsxs25("div", { className: "fixed inset-0 z-[9999] pointer-events-none", children: [
|
|
3180
|
+
/* @__PURE__ */ jsx27(
|
|
3060
3181
|
"div",
|
|
3061
3182
|
{
|
|
3062
3183
|
className: `splash-half splash-half-top absolute inset-x-0 top-0 h-1/2 bg-background overflow-hidden ${topClass}`,
|
|
3063
|
-
children: /* @__PURE__ */
|
|
3184
|
+
children: /* @__PURE__ */ jsx27("div", { className: "absolute inset-0 flex flex-col items-center justify-end pb-2", children: /* @__PURE__ */ jsx27("span", { className: "splash-title", children: "GAVA" }) })
|
|
3064
3185
|
}
|
|
3065
3186
|
),
|
|
3066
|
-
/* @__PURE__ */
|
|
3187
|
+
/* @__PURE__ */ jsx27(
|
|
3067
3188
|
"div",
|
|
3068
3189
|
{
|
|
3069
3190
|
className: `splash-half splash-half-bottom absolute inset-x-0 bottom-0 h-1/2 bg-background overflow-hidden ${bottomClass}`,
|
|
3070
|
-
children: /* @__PURE__ */
|
|
3071
|
-
/* @__PURE__ */
|
|
3072
|
-
/* @__PURE__ */
|
|
3191
|
+
children: /* @__PURE__ */ jsxs25("div", { className: "absolute inset-0 flex flex-col items-center justify-start pt-2", children: [
|
|
3192
|
+
/* @__PURE__ */ jsx27("span", { className: "splash-title", children: "ENGINE" }),
|
|
3193
|
+
/* @__PURE__ */ jsx27("div", { className: "flex items-center gap-3 mt-6", children: words.map((word, i) => /* @__PURE__ */ jsxs25(
|
|
3073
3194
|
"span",
|
|
3074
3195
|
{
|
|
3075
3196
|
className: "splash-word text-xs sm:text-sm font-medium tracking-widest uppercase",
|
|
3076
3197
|
style: { animationDelay: `${0.2 + i * 0.1}s` },
|
|
3077
3198
|
children: [
|
|
3078
3199
|
word,
|
|
3079
|
-
i < 2 && /* @__PURE__ */
|
|
3200
|
+
i < 2 && /* @__PURE__ */ jsx27("span", { className: "ml-3 text-muted-foreground", children: "\xB7" })
|
|
3080
3201
|
]
|
|
3081
3202
|
},
|
|
3082
3203
|
word
|
|
@@ -3088,10 +3209,10 @@ function SplashScreen() {
|
|
|
3088
3209
|
}
|
|
3089
3210
|
|
|
3090
3211
|
// src/components/splash/DashboardSplashTrigger.tsx
|
|
3091
|
-
import { useEffect as
|
|
3212
|
+
import { useEffect as useEffect8 } from "react";
|
|
3092
3213
|
function DashboardSplashTrigger() {
|
|
3093
3214
|
const { openSplash } = useSplash();
|
|
3094
|
-
|
|
3215
|
+
useEffect8(() => {
|
|
3095
3216
|
if (typeof window.requestIdleCallback === "function") {
|
|
3096
3217
|
const id = window.requestIdleCallback(() => openSplash());
|
|
3097
3218
|
return () => window.cancelIdleCallback(id);
|
|
@@ -3131,9 +3252,10 @@ export {
|
|
|
3131
3252
|
JsonRenderer,
|
|
3132
3253
|
ContentEditor,
|
|
3133
3254
|
ContentList,
|
|
3255
|
+
CategoryManager,
|
|
3134
3256
|
DashboardNavbar,
|
|
3135
3257
|
StatCard,
|
|
3136
3258
|
SplashScreen,
|
|
3137
3259
|
DashboardSplashTrigger
|
|
3138
3260
|
};
|
|
3139
|
-
//# sourceMappingURL=chunk-
|
|
3261
|
+
//# sourceMappingURL=chunk-XUWBLDOW.js.map
|