navigation
This commit is contained in:
@@ -9,6 +9,14 @@ import { initializeApiClients } from "./api/client";
|
||||
import { AppConfig } from "./types/config";
|
||||
import { Box, Typography, Paper, CircularProgress } from "@mui/material";
|
||||
import AppTheme from "../src/shared-theme/AppTheme";
|
||||
import {
|
||||
BrowserRouter,
|
||||
Routes,
|
||||
Route,
|
||||
useNavigate,
|
||||
useParams,
|
||||
Navigate,
|
||||
} from "react-router-dom";
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
@@ -17,26 +25,38 @@ export const ConfigContext = React.createContext<AppConfig | null>(null);
|
||||
|
||||
function Dashboard() {
|
||||
const config = React.useContext(ConfigContext);
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
Welcome to the Admin Panel
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
<Typography variant="body1" sx={{ color: 'text.secondary' }}>
|
||||
Select a resource from the sidebar to manage data.
|
||||
</Typography>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(240px, 1fr))",
|
||||
gap: 3,
|
||||
mt: 4,
|
||||
}}
|
||||
>
|
||||
{config?.resources.map((res) => (
|
||||
<Paper key={res.name} sx={{ p: 3, textAlign: "center" }}>
|
||||
<Typography variant="h6">{res.pluralLabel}</Typography>
|
||||
<Paper
|
||||
key={res.name}
|
||||
sx={{
|
||||
p: 3,
|
||||
textAlign: "center",
|
||||
cursor: 'pointer',
|
||||
transition: 'transform 0.2s',
|
||||
'&:hover': { transform: 'translateY(-4px)', boxShadow: 4 }
|
||||
}}
|
||||
onClick={() => navigate(`/${res.name}`)}
|
||||
>
|
||||
<Typography variant="h6" color="primary">{res.pluralLabel}</Typography>
|
||||
<Typography variant="body2" color="text.secondary">Manage {res.pluralLabel.toLowerCase()}</Typography>
|
||||
</Paper>
|
||||
))}
|
||||
</Box>
|
||||
@@ -47,15 +67,7 @@ function Dashboard() {
|
||||
function AdminApp() {
|
||||
const { currentUser, login, logout, loading, error } = useAuth();
|
||||
const config = React.useContext(ConfigContext);
|
||||
const [selectedResourceName, setSelectedResourceName] = React.useState<
|
||||
string | null
|
||||
>(null);
|
||||
const [selectedItemId, setSelectedItemId] = React.useState<string | null>(null);
|
||||
|
||||
const handleNavigateToResource = (resourceName: string, id: string) => {
|
||||
setSelectedResourceName(resourceName);
|
||||
setSelectedItemId(id);
|
||||
};
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (!currentUser) {
|
||||
return (
|
||||
@@ -72,34 +84,34 @@ function AdminApp() {
|
||||
);
|
||||
}
|
||||
|
||||
const selectedResource = config?.resources.find(
|
||||
(r) => r.name === selectedResourceName
|
||||
);
|
||||
|
||||
return (
|
||||
<AdminLayout
|
||||
username={currentUser.username}
|
||||
onLogout={logout}
|
||||
selectedResourceName={selectedResourceName}
|
||||
onSelectResource={(name) => {
|
||||
setSelectedResourceName(name);
|
||||
setSelectedItemId(null);
|
||||
}}
|
||||
onSelectResource={(name) => navigate(`/${name}`)}
|
||||
resources={config?.resources || []}
|
||||
>
|
||||
{selectedResource ? (
|
||||
<ResourceView
|
||||
key={`${selectedResource.name}-${selectedItemId}`}
|
||||
config={selectedResource}
|
||||
onNavigateToResource={handleNavigateToResource}
|
||||
/>
|
||||
) : (
|
||||
<Dashboard />
|
||||
)}
|
||||
<Routes>
|
||||
<Route path="/" element={<Dashboard />} />
|
||||
<Route path="/:resourceName" element={<ResourceRouteWrapper />} />
|
||||
<Route path="/:resourceName/:id" element={<ResourceRouteWrapper />} />
|
||||
<Route path="/:resourceName/create" element={<ResourceRouteWrapper />} />
|
||||
<Route path="/:resourceName/edit/:id" element={<ResourceRouteWrapper />} />
|
||||
</Routes>
|
||||
</AdminLayout>
|
||||
);
|
||||
}
|
||||
|
||||
function ResourceRouteWrapper() {
|
||||
const { resourceName } = useParams();
|
||||
const config = React.useContext(ConfigContext);
|
||||
const selectedResource = config?.resources.find((r) => r.name === resourceName);
|
||||
|
||||
if (!selectedResource) return <Typography>Resource not found</Typography>;
|
||||
|
||||
return <ResourceView config={selectedResource} />;
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const [config, setConfig] = React.useState<AppConfig | null>(null);
|
||||
|
||||
@@ -133,7 +145,9 @@ export default function App() {
|
||||
<ConfigContext.Provider value={config}>
|
||||
<AuthProvider authBaseUrl={config.authBaseUrl}>
|
||||
<UploadProvider>
|
||||
<AdminApp />
|
||||
<BrowserRouter>
|
||||
<AdminApp />
|
||||
</BrowserRouter>
|
||||
</UploadProvider>
|
||||
</AuthProvider>
|
||||
</ConfigContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user