-
This commit is contained in:
2
kms/web/dist/665.js
vendored
2
kms/web/dist/665.js
vendored
File diff suppressed because one or more lines are too long
2
kms/web/dist/main.js
vendored
2
kms/web/dist/main.js
vendored
File diff suppressed because one or more lines are too long
@ -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}>
|
||||
|
||||
@ -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} />}
|
||||
|
||||
@ -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} />}
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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
2
web/dist/main.js
vendored
File diff suppressed because one or more lines are too long
@ -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 />
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user