diff --git a/app/explorer/page.tsx b/app/explorer/page.tsx
new file mode 100644
index 0000000..d56d3e5
--- /dev/null
+++ b/app/explorer/page.tsx
@@ -0,0 +1,10 @@
+'use client';
+
+import { HyperwebExplorer } from '@hyperweb/explorer';
+import { useTheme } from '@/hooks';
+
+export default function ExplorerPage() {
+ const theme = useTheme();
+
+ return ;
+}
diff --git a/app/layout.tsx b/app/layout.tsx
index eb0a6ef..99e2c2d 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,30 +1,28 @@
-import type { Metadata } from 'next'
-import { Inter } from 'next/font/google'
-import './globals.css'
-import { Providers } from './providers'
-import { DashboardLayout } from '@/components/dashboard-layout'
+import type { Metadata } from 'next';
+import { Inter } from 'next/font/google';
+import './globals.css';
+import { Providers } from './providers';
+import { DashboardLayout } from '@/components/dashboard-layout';
+import '@hyperweb/explorer/styles';
+import '@hyperweb/playground/styles';
+import '@hyperweb/playground/wallet-styles';
+import { cn } from '@/lib/utils';
-const inter = Inter({ subsets: ['latin'] })
+const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Kubernetes Dashboard',
description: 'A modern dashboard for managing Kubernetes resources',
-}
+};
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode
-}) {
+export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
-
-
+
+
-
- {children}
-
+ {children}
- )
-}
\ No newline at end of file
+ );
+}
diff --git a/app/playground/page.tsx b/app/playground/page.tsx
new file mode 100644
index 0000000..d0d2d96
--- /dev/null
+++ b/app/playground/page.tsx
@@ -0,0 +1,10 @@
+'use client';
+
+import { HyperwebPlayground } from '@hyperweb/playground';
+import { useTheme } from '@/hooks';
+
+export default function PlaygroundPage() {
+ const theme = useTheme();
+
+ return ;
+}
diff --git a/components/dashboard-layout.tsx b/components/dashboard-layout.tsx
index 033fc28..6a010f0 100644
--- a/components/dashboard-layout.tsx
+++ b/components/dashboard-layout.tsx
@@ -1,12 +1,12 @@
-'use client'
-
-import { useState } from 'react'
-import NextLink from 'next/link'
-import { usePathname } from 'next/navigation'
-import { Button } from '@/components/ui/button'
-import { NamespaceSwitcher } from '@/components/namespace-switcher'
-import { ThemeToggle } from '@/components/ui/theme-toggle'
-import { useKubernetes } from '../k8s/context'
+'use client';
+
+import { useState } from 'react';
+import NextLink from 'next/link';
+import { usePathname } from 'next/navigation';
+import { Button } from '@/components/ui/button';
+import { NamespaceSwitcher } from '@/components/namespace-switcher';
+import { ThemeToggle } from '@/components/ui/theme-toggle';
+import { useKubernetes } from '../k8s/context';
import {
Package,
Server,
@@ -40,154 +40,265 @@ import {
Grid3x3,
ChevronDown,
ChevronRight,
- Heart
-} from 'lucide-react'
+ Heart,
+ Box,
+} from 'lucide-react';
const navigationItems = [
// Top items (no section)
{ id: 'overview', label: 'Overview', icon: Home, href: '/' },
{ id: 'all', label: 'All Resources', icon: Grid3x3, href: '/all' },
{ id: 'templates', label: 'Templates', icon: FileCode2, href: '/templates' },
-
+ { id: 'playground', label: 'Playground', icon: Zap, href: '/playground' },
+ { id: 'explorer', label: 'Explorer', icon: Box, href: '/explorer' },
+
// Workloads
{ id: 'workloads-header', label: 'Workloads', isHeader: true, section: 'workloads' },
- { id: 'deployments', label: 'Deployments', icon: Package, href: '/deployments', section: 'workloads' },
- { id: 'replicasets', label: 'ReplicaSets', icon: Copy, href: '/replicasets', section: 'workloads' },
- { id: 'statefulsets', label: 'StatefulSets', icon: Layers, href: '/statefulsets', section: 'workloads' },
- { id: 'daemonsets', label: 'DaemonSets', icon: Shield, href: '/daemonsets', section: 'workloads' },
+ {
+ id: 'deployments',
+ label: 'Deployments',
+ icon: Package,
+ href: '/deployments',
+ section: 'workloads',
+ },
+ {
+ id: 'replicasets',
+ label: 'ReplicaSets',
+ icon: Copy,
+ href: '/replicasets',
+ section: 'workloads',
+ },
+ {
+ id: 'statefulsets',
+ label: 'StatefulSets',
+ icon: Layers,
+ href: '/statefulsets',
+ section: 'workloads',
+ },
+ {
+ id: 'daemonsets',
+ label: 'DaemonSets',
+ icon: Shield,
+ href: '/daemonsets',
+ section: 'workloads',
+ },
{ id: 'pods', label: 'Pods', icon: Activity, href: '/pods', section: 'workloads' },
{ id: 'jobs', label: 'Jobs', icon: Zap, href: '/jobs', section: 'workloads' },
{ id: 'cronjobs', label: 'CronJobs', icon: Calendar, href: '/cronjobs', section: 'workloads' },
-
+
// Config & Storage
{ id: 'config-header', label: 'Config & Storage', isHeader: true, section: 'config' },
{ id: 'configmaps', label: 'ConfigMaps', icon: Settings, href: '/configmaps', section: 'config' },
{ id: 'secrets', label: 'Secrets', icon: Key, href: '/secrets', section: 'config' },
- { id: 'pvcs', label: 'Persistent Volume Claims', icon: HardDrive, href: '/pvcs', section: 'config' },
+ {
+ id: 'pvcs',
+ label: 'Persistent Volume Claims',
+ icon: HardDrive,
+ href: '/pvcs',
+ section: 'config',
+ },
{ id: 'pvs', label: 'Persistent Volumes', icon: Database, href: '/pvs', section: 'config' },
- { id: 'storageclasses', label: 'Storage Classes', icon: Database, href: '/storageclasses', section: 'config' },
- { id: 'volumeattachments', label: 'Volume Attachments', icon: Paperclip, href: '/volumeattachments', section: 'config' },
-
+ {
+ id: 'storageclasses',
+ label: 'Storage Classes',
+ icon: Database,
+ href: '/storageclasses',
+ section: 'config',
+ },
+ {
+ id: 'volumeattachments',
+ label: 'Volume Attachments',
+ icon: Paperclip,
+ href: '/volumeattachments',
+ section: 'config',
+ },
+
// Network
{ id: 'network-header', label: 'Network', isHeader: true, section: 'network' },
{ id: 'services', label: 'Services', icon: Server, href: '/services', section: 'network' },
{ id: 'ingresses', label: 'Ingresses', icon: Globe, href: '/ingresses', section: 'network' },
- { id: 'networkpolicies', label: 'Network Policies', icon: Shield, href: '/networkpolicies', section: 'network' },
+ {
+ id: 'networkpolicies',
+ label: 'Network Policies',
+ icon: Shield,
+ href: '/networkpolicies',
+ section: 'network',
+ },
{ id: 'endpoints', label: 'Endpoints', icon: Network, href: '/endpoints', section: 'network' },
- { id: 'endpointslices', label: 'Endpoint Slices', icon: Network, href: '/endpointslices', section: 'network' },
-
+ {
+ id: 'endpointslices',
+ label: 'Endpoint Slices',
+ icon: Network,
+ href: '/endpointslices',
+ section: 'network',
+ },
+
// Access Control
{ id: 'rbac-header', label: 'Access Control', isHeader: true, section: 'rbac' },
- { id: 'serviceaccounts', label: 'Service Accounts', icon: Bot, href: '/serviceaccounts', section: 'rbac' },
+ {
+ id: 'serviceaccounts',
+ label: 'Service Accounts',
+ icon: Bot,
+ href: '/serviceaccounts',
+ section: 'rbac',
+ },
{ id: 'roles', label: 'Roles', icon: UserCheck, href: '/roles', section: 'rbac' },
- { id: 'rolebindings', label: 'Role Bindings', icon: Users, href: '/rolebindings', section: 'rbac' },
-
+ {
+ id: 'rolebindings',
+ label: 'Role Bindings',
+ icon: Users,
+ href: '/rolebindings',
+ section: 'rbac',
+ },
+
// Cluster
{ id: 'cluster-header', label: 'Cluster', isHeader: true, section: 'cluster' },
- { id: 'resourcequotas', label: 'Resource Quotas', icon: Gauge, href: '/resourcequotas', section: 'cluster' },
- { id: 'hpas', label: 'Horizontal Pod Autoscalers', icon: BarChart, href: '/hpas', section: 'cluster' },
- { id: 'pdbs', label: 'Pod Disruption Budgets', icon: ShieldCheck, href: '/pdbs', section: 'cluster' },
- { id: 'priorityclasses', label: 'Priority Classes', icon: Star, href: '/priorityclasses', section: 'cluster' },
- { id: 'runtimeclasses', label: 'Runtime Classes', icon: Cpu, href: '/runtimeclasses', section: 'cluster' },
+ {
+ id: 'resourcequotas',
+ label: 'Resource Quotas',
+ icon: Gauge,
+ href: '/resourcequotas',
+ section: 'cluster',
+ },
+ {
+ id: 'hpas',
+ label: 'Horizontal Pod Autoscalers',
+ icon: BarChart,
+ href: '/hpas',
+ section: 'cluster',
+ },
+ {
+ id: 'pdbs',
+ label: 'Pod Disruption Budgets',
+ icon: ShieldCheck,
+ href: '/pdbs',
+ section: 'cluster',
+ },
+ {
+ id: 'priorityclasses',
+ label: 'Priority Classes',
+ icon: Star,
+ href: '/priorityclasses',
+ section: 'cluster',
+ },
+ {
+ id: 'runtimeclasses',
+ label: 'Runtime Classes',
+ icon: Cpu,
+ href: '/runtimeclasses',
+ section: 'cluster',
+ },
{ id: 'events', label: 'Events', icon: Clock, href: '/events', section: 'cluster' },
-]
+];
interface DashboardLayoutProps {
- children: React.ReactNode
+ children: React.ReactNode;
}
export function DashboardLayout({ children }: DashboardLayoutProps) {
- const [sidebarOpen, setSidebarOpen] = useState(true)
- const [expandedSections, setExpandedSections] = useState>(new Set(['workloads', 'config', 'network', 'rbac', 'cluster']))
- const pathname = usePathname()
- const { config } = useKubernetes()
-
+ const [sidebarOpen, setSidebarOpen] = useState(true);
+ const [expandedSections, setExpandedSections] = useState>(
+ new Set(['workloads', 'config', 'network', 'rbac', 'cluster'])
+ );
+ const pathname = usePathname();
+ const { config } = useKubernetes();
+
// Find active section based on pathname
- const activeSection = navigationItems.find(item => !item.isHeader && item.href === pathname)?.label || 'Overview'
-
+ const activeSection =
+ navigationItems.find((item) => !item.isHeader && item.href === pathname)?.label || 'Overview';
+
// Toggle section expansion
const toggleSection = (section: string) => {
- const newExpanded = new Set(expandedSections)
+ const newExpanded = new Set(expandedSections);
if (newExpanded.has(section)) {
- newExpanded.delete(section)
+ newExpanded.delete(section);
} else {
- newExpanded.add(section)
+ newExpanded.add(section);
}
- setExpandedSections(newExpanded)
- }
+ setExpandedSections(newExpanded);
+ };
return (
-
+
{/* Sidebar */}
-
-
+
+
-