Spaces:
Paused
Paused
File size: 2,917 Bytes
5a81b95 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 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,
};
}
|