Files
skybridge/user/web/src/App.tsx
2025-08-31 22:35:23 -04:00

138 lines
4.2 KiB
TypeScript

import React, { useState } from 'react';
import { Box, Title, Tabs, Stack, ActionIcon, Group, Select, MantineProvider } from '@mantine/core';
import { Notifications } from '@mantine/notifications';
import { ModalsProvider } from '@mantine/modals';
import {
IconUsers,
IconUserPlus,
IconStar,
IconStarFilled
} from '@tabler/icons-react';
import UserManagement from './components/UserManagement';
const App: React.FC = () => {
// Determine current route based on pathname
const getCurrentRoute = () => {
const path = window.location.pathname;
if (path.includes('/create')) return 'create';
return 'users';
};
const [currentRoute, setCurrentRoute] = useState(getCurrentRoute());
const [isFavorited, setIsFavorited] = useState(false);
const [selectedColor, setSelectedColor] = useState('');
// Listen for URL changes (for when the shell navigates)
React.useEffect(() => {
const handlePopState = () => {
setCurrentRoute(getCurrentRoute());
};
window.addEventListener('popstate', handlePopState);
return () => window.removeEventListener('popstate', handlePopState);
}, []);
const handleTabChange = (value: string | null) => {
if (value) {
// Use history.pushState to update URL and notify shell router
const basePath = '/app/user';
const newPath = value === 'users' ? basePath : `${basePath}/${value}`;
// Update the URL and internal state
window.history.pushState(null, '', newPath);
setCurrentRoute(value);
// Dispatch a custom event so shell can respond if needed
window.dispatchEvent(new PopStateEvent('popstate', { state: null }));
}
};
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 'users':
case 'create':
default:
return <UserManagement />;
}
};
return (
<MantineProvider>
<ModalsProvider>
<Notifications />
<Box w="100%" pos="relative">
<Stack gap="lg">
<div>
<Group justify="space-between" align="flex-start">
<div>
<Group align="center" gap="sm" mb="xs">
<Title order={1} size="h2">
User Management
</Title>
<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}>
<Tabs.List>
<Tabs.Tab
value="users"
leftSection={<IconUsers size={16} />}
>
Users
</Tabs.Tab>
</Tabs.List>
<Box pt="md">
{renderContent()}
</Box>
</Tabs>
</Stack>
</Box>
</ModalsProvider>
</MantineProvider>
);
};
export default App;