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:
BOHA
2026-06-08 18:38:35 +02:00
parent 049ee492c0
commit e4ec08a5ef
5 changed files with 48 additions and 7 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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
View 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>
);
}

View File

@@ -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>
),
},
],
},
{