This commit is contained in:
2025-08-27 12:27:50 -04:00
parent 0663646e40
commit 7e584ba53b
13 changed files with 144 additions and 156 deletions

2
kms/web/dist/665.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,13 @@
import React from 'react';
import { Box, Title, Tabs, Stack, Text } from '@mantine/core';
import { Box, Title, Tabs, Stack, Text, ActionIcon, Group, Select } from '@mantine/core';
import {
IconApps,
IconKey,
IconTestPipe,
IconFileText,
IconDashboard
IconDashboard,
IconStar,
IconStarFilled
} from '@tabler/icons-react';
import Applications from './components/Applications';
import Tokens from './components/Tokens';
@ -25,6 +27,8 @@ const App: React.FC = () => {
};
const [currentRoute, setCurrentRoute] = React.useState(getCurrentRoute());
const [isFavorited, setIsFavorited] = React.useState(false);
const [selectedColor, setSelectedColor] = React.useState('');
// Listen for URL changes (for when the shell navigates)
React.useEffect(() => {
@ -51,6 +55,21 @@ const App: React.FC = () => {
}
};
const toggleFavorite = () => {
setIsFavorited(prev => !prev);
};
const colorOptions = [
{ value: 'red', label: 'Red' },
{ value: 'blue', label: 'Blue' },
{ value: 'green', label: 'Green' },
{ value: 'purple', label: 'Purple' },
{ value: 'orange', label: 'Orange' },
{ value: 'pink', label: 'Pink' },
{ value: 'teal', label: 'Teal' },
];
const renderContent = () => {
switch (currentRoute) {
case 'applications':
@ -67,15 +86,45 @@ const App: React.FC = () => {
};
return (
<Box w="100%">
<Box w="100%" pos="relative">
<Stack gap="lg">
<div>
<Title order={1} size="h2" mb="xs">
<Group justify="space-between" align="flex-start">
<div>
<Group align="center" gap="sm" mb="xs">
<Title order={1} size="h2">
Key Management System
</Title>
<Text c="dimmed" size="sm">
Manage API keys, tokens, and access permissions
</Text>
<ActionIcon
variant="subtle"
size="lg"
onClick={toggleFavorite}
aria-label={isFavorited ? "Remove from favorites" : "Add to favorites"}
>
{isFavorited ? (
<IconStarFilled size={20} color="gold" />
) : (
<IconStar size={20} />
)}
</ActionIcon>
</Group>
</div>
{/* Right-side controls */}
<Group align="flex-start" gap="lg">
<div>
<Select
placeholder="Choose a color"
data={colorOptions}
value={selectedColor}
onChange={(value) => setSelectedColor(value || '')}
size="sm"
w={150}
/>
</div>
</Group>
</Group>
</div>
<Tabs value={currentRoute} onChange={handleTabChange}>

View File

@ -233,9 +233,6 @@ const Applications: React.FC = () => {
<Title order={2} mb="xs">
Applications
</Title>
<Text c="dimmed">
Manage your registered applications and their configurations
</Text>
</div>
<Button
leftSection={<IconPlus size={16} />}

View File

@ -202,9 +202,6 @@ const Audit: React.FC = () => {
<Title order={2} mb="xs">
Audit Log
</Title>
<Text c="dimmed">
View and search system audit events and security logs
</Text>
</div>
<Button
leftSection={<IconRefresh size={16} />}

View File

@ -110,15 +110,6 @@ const Dashboard: React.FC = () => {
return (
<Stack gap="lg">
<div>
<Title order={2} mb="xs">
Dashboard Overview
</Title>
<Text c="dimmed">
Monitor your key management system status and metrics
</Text>
</div>
<SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg">
{statCards.map((stat) => (
<Card key={stat.title} shadow="sm" radius="md" withBorder p="lg">

View File

@ -136,15 +136,6 @@ const TokenTester: React.FC = () => {
return (
<Stack gap="lg">
<div>
<Title order={2} mb="xs">
Token Tester
</Title>
<Text c="dimmed">
Test and verify API tokens against your applications
</Text>
</div>
<Grid>
<Grid.Col span={{ base: 12, md: 6 }}>
<Card shadow="sm" radius="md" withBorder p="lg">

View File

@ -242,9 +242,6 @@ const Tokens: React.FC = () => {
<Title order={2} mb="xs">
API Tokens
</Title>
<Text c="dimmed">
Manage static API tokens for your applications
</Text>
</div>
<Button
leftSection={<IconPlus size={16} />}

2
web/dist/main.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,20 +1,27 @@
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import { AppShell } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import Header from './components/Header';
import Navigation from './components/Navigation';
import HomePage from './pages/HomePage';
import AppLoader from './components/AppLoader';
function App() {
const [collapsed, { toggle: toggleNavbar }] = useDisclosure(false);
return (
<AppShell
header={{ height: 60 }}
navbar={{ width: 300, breakpoint: 'sm' }}
navbar={{
width: 300,
breakpoint: 'sm',
collapsed: { mobile: collapsed, desktop: collapsed }
}}
padding="md"
>
<AppShell.Header>
<Header />
<Header onToggleNavbar={toggleNavbar} />
</AppShell.Header>
<AppShell.Navbar>
<Navigation />

View File

@ -2,24 +2,30 @@ import React from 'react';
import {
Group,
ActionIcon,
Select,
TextInput,
Text,
Avatar,
Flex,
Box,
Burger,
Avatar,
Menu,
} from '@mantine/core';
import { useNavigate } from 'react-router-dom';
import {
IconSearch,
IconBell,
IconHome,
IconStar,
IconSettings,
IconMail,
IconUser,
IconLogout,
} from '@tabler/icons-react';
const Header: React.FC = () => {
interface HeaderProps {
onToggleNavbar: () => void;
}
const Header: React.FC<HeaderProps> = ({ onToggleNavbar }) => {
const navigate = useNavigate();
const [currentTime, setCurrentTime] = React.useState(new Date());
React.useEffect(() => {
@ -64,6 +70,13 @@ const Header: React.FC = () => {
return (
<Box h={60} px="md">
<Flex align="center" h="100%" gap="md">
{/* Burger menu for navbar toggle */}
<Burger
onClick={onToggleNavbar}
size="sm"
aria-label="Toggle navigation"
/>
{/* Logo */}
<Text size="xl" fw={700} c="blue">
Skybridge
@ -71,30 +84,22 @@ const Header: React.FC = () => {
{/* Icon Buttons */}
<Group gap="xs">
<ActionIcon variant="subtle" size="lg">
<ActionIcon
variant="subtle"
size="lg"
aria-label="Home"
onClick={() => navigate('/')}
>
<IconHome size={18} />
</ActionIcon>
<ActionIcon variant="subtle" size="lg" aria-label="Favorites">
<IconStar size={18} />
</ActionIcon>
<ActionIcon variant="subtle" size="lg" aria-label="Notifications">
<IconBell size={18} />
</ActionIcon>
<ActionIcon variant="subtle" size="lg">
<IconMail size={18} />
</ActionIcon>
<ActionIcon variant="subtle" size="lg">
<IconSettings size={18} />
</ActionIcon>
<ActionIcon variant="subtle" size="lg">
<IconUser size={18} />
</ActionIcon>
</Group>
{/* Application Dropdown */}
<Select
placeholder="Select Application"
data={[
{ value: 'demo', label: 'Demo App' },
{ value: 'dashboard', label: 'Dashboard' },
{ value: 'analytics', label: 'Analytics' },
]}
w={200}
/>
{/* Search Box */}
<TextInput
@ -161,6 +166,7 @@ const Header: React.FC = () => {
</Menu.Item>
</Menu.Dropdown>
</Menu>
</Flex>
</Box>
);

View File

@ -1,12 +1,8 @@
import React from 'react';
import { NavLink, Stack, Text, Group } from '@mantine/core';
import { NavLink, Stack, Text } from '@mantine/core';
import { useNavigate, useLocation } from 'react-router-dom';
import {
IconHome,
IconApps,
IconDashboard,
IconChartLine,
IconStar,
IconKey,
} from '@tabler/icons-react';
@ -14,25 +10,8 @@ const Navigation: React.FC = () => {
const navigate = useNavigate();
const location = useLocation();
const navigationItems = [
{
label: 'Home',
icon: IconHome,
path: '/',
},
{
label: 'Favorites',
icon: IconStar,
path: '/favorites',
},
{
label: 'All Applications',
icon: IconApps,
path: '/apps',
},
];
const applications = [
// Define all available applications
const allAvailableApplications = [
{
label: 'Demo App',
icon: IconDashboard,
@ -43,34 +22,26 @@ const Navigation: React.FC = () => {
icon: IconKey,
path: '/app/kms',
},
{
label: 'Analytics',
icon: IconChartLine,
path: '/app/analytics',
},
];
// Define which apps are favorited (you could make this dynamic later)
const favoritePaths = ['/app/demo'];
const favoriteApplications = allAvailableApplications.filter(app =>
favoritePaths.includes(app.path)
);
const nonFavoriteApplications = allAvailableApplications.filter(app =>
!favoritePaths.includes(app.path)
);
return (
<Stack gap="xs" p="md">
<Text size="sm" fw={600} c="dimmed" tt="uppercase" mb="xs">
Navigation
Favorites
</Text>
{navigationItems.map((item) => (
<NavLink
key={item.path}
label={item.label}
leftSection={<item.icon size={16} />}
active={location.pathname === item.path}
onClick={() => navigate(item.path)}
/>
))}
<Text size="sm" fw={600} c="dimmed" tt="uppercase" mt="lg" mb="xs">
Applications
</Text>
{applications.map((app) => (
{favoriteApplications.map((app) => (
<NavLink
key={app.path}
label={app.label}
@ -79,6 +50,24 @@ const Navigation: React.FC = () => {
onClick={() => navigate(app.path)}
/>
))}
{nonFavoriteApplications.length > 0 && (
<>
<Text size="sm" fw={600} c="dimmed" tt="uppercase" mt="lg" mb="xs">
All Applications
</Text>
{nonFavoriteApplications.map((app) => (
<NavLink
key={`all-${app.path}`}
label={app.label}
leftSection={<app.icon size={16} />}
active={location.pathname.startsWith(app.path)}
onClick={() => navigate(app.path)}
/>
))}
</>
)}
</Stack>
);
};

View File

@ -14,11 +14,7 @@ import {
IconStar,
IconStarFilled,
IconDashboard,
IconChartLine,
IconSettings,
IconUsers,
IconFiles,
IconMail,
IconKey,
} from '@tabler/icons-react';
import Breadcrumbs from '../components/Breadcrumbs';
@ -33,56 +29,24 @@ interface App {
const HomePage: React.FC = () => {
const navigate = useNavigate();
const [favoriteApps, setFavoriteApps] = useState<string[]>(['demo', 'analytics']);
const [favoriteApps, setFavoriteApps] = useState<string[]>(['demo']);
const availableApps: App[] = [
{
id: 'demo',
name: 'Demo App',
description: 'Sample application for testing',
description: 'Sample microfrontend application for testing module federation',
icon: IconDashboard,
path: '/app/demo',
category: 'Development',
},
{
id: 'analytics',
name: 'Analytics',
description: 'Data analytics and reporting',
icon: IconChartLine,
path: '/app/analytics',
category: 'Analytics',
},
{
id: 'settings',
name: 'Settings',
description: 'System configuration',
icon: IconSettings,
path: '/app/settings',
category: 'System',
},
{
id: 'users',
name: 'User Management',
description: 'Manage users and permissions',
icon: IconUsers,
path: '/app/users',
category: 'Administration',
},
{
id: 'files',
name: 'File Manager',
description: 'Browse and manage files',
icon: IconFiles,
path: '/app/files',
category: 'Utilities',
},
{
id: 'mail',
name: 'Mail Client',
description: 'Email management',
icon: IconMail,
path: '/app/mail',
category: 'Communication',
id: 'kms',
name: 'Key Management System',
description: 'Manage API keys, tokens, and access permissions for applications',
icon: IconKey,
path: '/app/kms',
category: 'Security',
},
];