Kraft102's picture
fix: sql.js Docker/Alpine compatibility layer for PatternMemory and FailureMemory
5a81b95
import { useState, useEffect, useCallback } from 'react';
import { DashboardWidget } from '@/pages/Dashboard';
const PAGES_STORAGE_KEY = 'cyber-custom-pages';
export type PageType = 'dashboard' | 'static' | 'report';
export interface PageBlock {
id: string;
type: 'heading' | 'text' | 'image' | 'divider' | 'metric' | 'chart' | 'table';
content: any;
}
export interface CustomPage {
id: string;
slug: string;
title: string;
description?: string;
type: PageType;
icon?: string;
widgets?: DashboardWidget[];
blocks?: PageBlock[];
createdAt: number;
updatedAt: number;
}
const generateSlug = (title: string): string => {
return title
.toLowerCase()
.replace(/[æ]/g, 'ae')
.replace(/[ø]/g, 'oe')
.replace(/[å]/g, 'aa')
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '');
};
export function useCustomPages() {
const [pages, setPages] = useState<CustomPage[]>([]);
useEffect(() => {
const saved = localStorage.getItem(PAGES_STORAGE_KEY);
if (saved) {
try {
setPages(JSON.parse(saved));
} catch (e) {
console.error('Failed to load pages:', e);
}
}
}, []);
const savePages = useCallback((newPages: CustomPage[]) => {
localStorage.setItem(PAGES_STORAGE_KEY, JSON.stringify(newPages));
setPages(newPages);
}, []);
const createPage = useCallback((
title: string,
type: PageType,
description?: string,
icon?: string
): CustomPage => {
const baseSlug = generateSlug(title);
let slug = baseSlug;
let counter = 1;
// Ensure unique slug
while (pages.some(p => p.slug === slug)) {
slug = `${baseSlug}-${counter}`;
counter++;
}
const newPage: CustomPage = {
id: `page-${Date.now()}`,
slug,
title,
description,
type,
icon,
widgets: type === 'dashboard' ? [] : undefined,
blocks: type !== 'dashboard' ? [] : undefined,
createdAt: Date.now(),
updatedAt: Date.now(),
};
savePages([...pages, newPage]);
return newPage;
}, [pages, savePages]);
const updatePage = useCallback((pageId: string, updates: Partial<CustomPage>) => {
const updatedPages = pages.map(p => {
if (p.id === pageId) {
return { ...p, ...updates, updatedAt: Date.now() };
}
return p;
});
savePages(updatedPages);
}, [pages, savePages]);
const deletePage = useCallback((pageId: string) => {
savePages(pages.filter(p => p.id !== pageId));
}, [pages, savePages]);
const getPageBySlug = useCallback((slug: string): CustomPage | undefined => {
return pages.find(p => p.slug === slug);
}, [pages]);
const getPageById = useCallback((id: string): CustomPage | undefined => {
return pages.find(p => p.id === id);
}, [pages]);
return {
pages,
createPage,
updatePage,
deletePage,
getPageBySlug,
getPageById,
};
}