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,
  };
}