138 lines
4.2 KiB
TypeScript
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; |