diff --git a/frontends/nextjs/src/components/managers/PageRoutesManager.tsx b/frontends/nextjs/src/components/managers/PageRoutesManager.tsx index e6ed6411f..e11958f24 100644 --- a/frontends/nextjs/src/components/managers/PageRoutesManager.tsx +++ b/frontends/nextjs/src/components/managers/PageRoutesManager.tsx @@ -1,29 +1,39 @@ -import { useState, useEffect } from 'react' -import { Button } from '@/components/ui' -import { Input } from '@/components/ui' -import { Label } from '@/components/ui' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui' -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui' -import { Badge } from '@/components/ui' -import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui' -import { Plus, Pencil, Trash, Eye, LockKey } from '@phosphor-icons/react' +import { useEffect, useState } from 'react' +import { + Button, + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/ui' +import { Plus } from '@phosphor-icons/react' import { Database } from '@/lib/database' +import type { PageConfig } from '@/lib/level-types' import { toast } from 'sonner' -import type { PageConfig, UserRole, AppLevel } from '@/lib/level-types' -import { Switch } from '@/components/ui' +import { RoutesTable } from './page-routes/RoutesTable' +import { Preview } from './page-routes/Preview' +import { RouteEditor, RouteFormData } from './page-routes/RouteEditor' + +const defaultFormData: RouteFormData = { + path: '/', + title: '', + level: 1, + requiresAuth: false, + componentTree: [], +} export function PageRoutesManager() { const [pages, setPages] = useState([]) const [isDialogOpen, setIsDialogOpen] = useState(false) const [editingPage, setEditingPage] = useState(null) - const [formData, setFormData] = useState>({ - path: '/', - title: '', - level: 1, - requiresAuth: false, - componentTree: [], - }) + const [formData, setFormData] = useState({ ...defaultFormData }) useEffect(() => { loadPages() @@ -40,13 +50,7 @@ export function PageRoutesManager() { setFormData(page) } else { setEditingPage(null) - setFormData({ - path: '/', - title: '', - level: 1, - requiresAuth: false, - componentTree: [], - }) + setFormData({ ...defaultFormData }) } setIsDialogOpen(true) } @@ -54,13 +58,7 @@ export function PageRoutesManager() { const handleCloseDialog = () => { setIsDialogOpen(false) setEditingPage(null) - setFormData({ - path: '/', - title: '', - level: 1, - requiresAuth: false, - componentTree: [], - }) + setFormData({ ...defaultFormData }) } const handleSavePage = async () => { @@ -98,18 +96,6 @@ export function PageRoutesManager() { } } - const getLevelBadgeColor = (level: AppLevel) => { - switch (level) { - case 1: return 'bg-blue-500' - case 2: return 'bg-green-500' - case 3: return 'bg-orange-500' - case 4: return 'bg-sky-500' - case 5: return 'bg-purple-500' - case 6: return 'bg-rose-500' - default: return 'bg-gray-500' - } - } - return (
@@ -124,94 +110,23 @@ export function PageRoutesManager() { New Page Route - + {editingPage ? 'Edit Page Route' : 'Create New Page Route'} Configure the route path, access level, and authentication requirements - -
-
-
- - setFormData({ ...formData, path: e.target.value })} - /> -
-
- - setFormData({ ...formData, title: e.target.value })} - /> -
-
- -
-
- - -
- -
- - -
-
- -
- setFormData({ ...formData, requiresAuth: checked })} - /> - -
+
+ +
- - - - -
@@ -222,67 +137,11 @@ export function PageRoutesManager() { All page routes in your application - {pages.length === 0 ? ( -
-

No pages configured yet. Create your first page route!

-
- ) : ( - - - - Path - Title - Level - Auth - Required Role - Actions - - - - {pages.map((page) => ( - - {page.path} - {page.title} - - - Level {page.level} - - - - {page.requiresAuth ? ( - - ) : ( - - )} - - - - {page.requiredRole || 'public'} - - - -
- - -
-
-
- ))} -
-
- )} +
diff --git a/frontends/nextjs/src/components/managers/page-routes/Preview.tsx b/frontends/nextjs/src/components/managers/page-routes/Preview.tsx new file mode 100644 index 000000000..2bfd2e207 --- /dev/null +++ b/frontends/nextjs/src/components/managers/page-routes/Preview.tsx @@ -0,0 +1,37 @@ +import { Badge, Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui' +import { Eye, LockKey } from '@phosphor-icons/react' +import type { PageConfig } from '@/lib/level-types' + +interface PreviewProps { + formData: Partial +} + +export function Preview({ formData }: PreviewProps) { + return ( + + + Route Preview + Quick glance at the route details + + +
+

Path

+

{formData.path || '/your-path'}

+
+
+

Title

+

{formData.title || 'Untitled Page'}

+
+
+ Level {formData.level || 1} + {formData.requiredRole || 'public'} + {formData.requiresAuth ? ( + + ) : ( + + )} +
+
+
+ ) +} diff --git a/frontends/nextjs/src/components/managers/page-routes/RouteEditor.tsx b/frontends/nextjs/src/components/managers/page-routes/RouteEditor.tsx new file mode 100644 index 000000000..e772c97ff --- /dev/null +++ b/frontends/nextjs/src/components/managers/page-routes/RouteEditor.tsx @@ -0,0 +1,107 @@ +import { + Button, + Input, + Label, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, + Switch, +} from '@/components/ui' +import type { PageConfig, UserRole, AppLevel } from '@/lib/level-types' + +export type RouteFormData = Partial + +interface RouteEditorProps { + formData: RouteFormData + onChange: (value: RouteFormData) => void + onSave: () => void + onCancel: () => void + isEdit: boolean +} + +export function RouteEditor({ formData, onChange, onSave, onCancel, isEdit }: RouteEditorProps) { + return ( +
+
+
+ + onChange({ ...formData, path: e.target.value })} + /> +
+
+ + onChange({ ...formData, title: e.target.value })} + /> +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+ onChange({ ...formData, requiresAuth: checked })} + /> + +
+ +
+ + +
+
+ ) +} diff --git a/frontends/nextjs/src/components/managers/page-routes/RoutesTable.tsx b/frontends/nextjs/src/components/managers/page-routes/RoutesTable.tsx new file mode 100644 index 000000000..be7f98038 --- /dev/null +++ b/frontends/nextjs/src/components/managers/page-routes/RoutesTable.tsx @@ -0,0 +1,98 @@ +import { + Badge, + Button, + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui' +import { Eye, LockKey, Pencil, Trash } from '@phosphor-icons/react' +import type { PageConfig, AppLevel } from '@/lib/level-types' + +interface RoutesTableProps { + pages: PageConfig[] + onEdit: (page: PageConfig) => void + onDelete: (pageId: string) => void +} + +const getLevelBadgeColor = (level: AppLevel) => { + switch (level) { + case 1: return 'bg-blue-500' + case 2: return 'bg-green-500' + case 3: return 'bg-orange-500' + case 4: return 'bg-sky-500' + case 5: return 'bg-purple-500' + case 6: return 'bg-rose-500' + default: return 'bg-gray-500' + } +} + +export function RoutesTable({ pages, onEdit, onDelete }: RoutesTableProps) { + if (pages.length === 0) { + return ( +
+

No pages configured yet. Create your first page route!

+
+ ) + } + + return ( + + + + Path + Title + Level + Auth + Required Role + Actions + + + + {pages.map((page) => ( + + {page.path} + {page.title} + + + Level {page.level} + + + + {page.requiresAuth ? ( + + ) : ( + + )} + + + + {page.requiredRole || 'public'} + + + +
+ + +
+
+
+ ))} +
+
+ ) +}