feat(ai): move the assistant to its own "Odin" sidebar page
Promote the AI chat from a dashboard widget to a dedicated page: - new sidebar item "Odin" under the Přehled section, gated on ai.use, → /odin - new /odin route + Odin page (reuses the assistant component, with a light ai.use guard) - remove the widget from the dashboard - rebrand the assistant header "Asistent" → "Odin" and give the thread more height now that it owns the page Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import { LoadingState } from "./ui";
|
||||
import Login from "./pages/Login";
|
||||
import Dashboard from "./pages/Dashboard";
|
||||
|
||||
const Odin = lazy(() => import("./pages/Odin"));
|
||||
const Users = lazy(() => import("./pages/Users"));
|
||||
const Attendance = lazy(() => import("./pages/Attendance"));
|
||||
const AttendanceHistory = lazy(() => import("./pages/AttendanceHistory"));
|
||||
@@ -82,6 +83,7 @@ export default function AdminApp() {
|
||||
)}
|
||||
<Route element={<AppShell />}>
|
||||
<Route index element={<Dashboard />} />
|
||||
<Route path="odin" element={<Odin />} />
|
||||
<Route path="users" element={<Users />} />
|
||||
<Route path="attendance" element={<Attendance />} />
|
||||
<Route
|
||||
|
||||
@@ -361,7 +361,7 @@ export default function DashAssistant() {
|
||||
AI
|
||||
</Box>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 600 }}>
|
||||
Asistent
|
||||
Odin
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1.5 }}>
|
||||
@@ -393,8 +393,8 @@ export default function DashAssistant() {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
minHeight: 120,
|
||||
maxHeight: 360,
|
||||
minHeight: 200,
|
||||
maxHeight: 480,
|
||||
overflowY: "auto",
|
||||
mb: 1.5,
|
||||
p: 1,
|
||||
|
||||
@@ -22,7 +22,6 @@ import DashSessions from "../components/dashboard/DashSessions";
|
||||
import DashTodayPlan, {
|
||||
type TodayPlan,
|
||||
} from "../components/dashboard/DashTodayPlan";
|
||||
import DashAssistant from "../components/dashboard/DashAssistant";
|
||||
|
||||
const API_BASE = "/api/admin";
|
||||
|
||||
@@ -237,9 +236,6 @@ export default function Dashboard() {
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{/* AI Assistant widget */}
|
||||
{hasPermission("ai.use") && <DashAssistant />}
|
||||
|
||||
{/* 2FA Required Banner */}
|
||||
{user?.require2FA && !user?.totpEnabled && (
|
||||
<Card
|
||||
|
||||
27
src/admin/pages/Odin.tsx
Normal file
27
src/admin/pages/Odin.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { PageEnter } from "../ui";
|
||||
import { useAuth } from "../context/AuthContext";
|
||||
import DashAssistant from "../components/dashboard/DashAssistant";
|
||||
|
||||
export default function Odin() {
|
||||
const { hasPermission } = useAuth();
|
||||
|
||||
if (!hasPermission("ai.use")) {
|
||||
return (
|
||||
<PageEnter>
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
Nemáte oprávnění pro AI asistenta.
|
||||
</Typography>
|
||||
</PageEnter>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<PageEnter>
|
||||
<Box sx={{ maxWidth: 920, mx: "auto" }}>
|
||||
<DashAssistant />
|
||||
</Box>
|
||||
</PageEnter>
|
||||
);
|
||||
}
|
||||
@@ -38,6 +38,22 @@ export const menuSections: MenuSection[] = [
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/odin",
|
||||
label: "Odin",
|
||||
permission: "ai.use",
|
||||
end: true,
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user