Skip to content

Commit 94d63ab

Browse files
Merge pull request #200 from SheetMetalConnect/claude/add-analytics-menu-section-01S4dwVZKyiwRbfEMNykQwYw
Create analytics menu section with unified pages
2 parents 1766222 + ab7fe14 commit 94d63ab

File tree

11 files changed

+929
-483
lines changed

11 files changed

+929
-483
lines changed

src/App.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import OEEAnalytics from "./pages/admin/analytics/OEEAnalytics";
4545
import ReliabilityAnalytics from "./pages/admin/analytics/ReliabilityAnalytics";
4646
import QRMAnalytics from "./pages/admin/analytics/QRMAnalytics";
4747
import QRMDashboard from "./pages/admin/analytics/QRMDashboard";
48+
import JobsAnalytics from "./pages/admin/analytics/JobsAnalytics";
49+
import QualityAnalytics from "./pages/admin/analytics/QualityAnalytics";
4850
import ApiDocs from "./pages/ApiDocs";
4951
import Pricing from "./pages/Pricing";
5052
import { MyPlan } from "./pages/MyPlan";
@@ -522,6 +524,28 @@ function AppRoutes() {
522524
}
523525
/>
524526

527+
<Route
528+
path="/admin/analytics/jobs"
529+
element={
530+
<ProtectedRoute adminOnly>
531+
<Layout>
532+
<JobsAnalytics />
533+
</Layout>
534+
</ProtectedRoute>
535+
}
536+
/>
537+
538+
<Route
539+
path="/admin/analytics/quality"
540+
element={
541+
<ProtectedRoute adminOnly>
542+
<Layout>
543+
<QualityAnalytics />
544+
</Layout>
545+
</ProtectedRoute>
546+
}
547+
/>
548+
525549
<Route
526550
path="/admin/config/steps-templates"
527551
element={

src/components/AdminLayout.tsx

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ import {
4141
Info,
4242
Factory,
4343
CalendarClock,
44+
BarChart3,
45+
Radio,
46+
Gauge,
47+
Target,
48+
TrendingUp,
4449
} from "lucide-react";
4550
import { Link, useLocation } from "react-router-dom";
4651
import { useState } from "react";
@@ -63,6 +68,7 @@ export default function AdminLayout({ children }: AdminLayoutProps) {
6368
const [collapsed, setCollapsed] = useState(false);
6469
const [mobileOpen, setMobileOpen] = useState(false);
6570
const [operatorViewsOpen, setOperatorViewsOpen] = useState(false);
71+
const [analyticsOpen, setAnalyticsOpen] = useState(false);
6672
const [configOpen, setConfigOpen] = useState(false);
6773
const [integrationsOpen, setIntegrationsOpen] = useState(false);
6874
const [accountOpen, setAccountOpen] = useState(false);
@@ -122,12 +128,40 @@ export default function AdminLayout({ children }: AdminLayoutProps) {
122128
icon: CalendarClock,
123129
exact: true,
124130
},
131+
];
132+
133+
// Analytics - Production insights and metrics
134+
const analyticsNavItems = [
125135
{
126136
path: "/admin/analytics/qrm-dashboard",
127-
label: "QRM Analytics",
137+
label: t("navigation.qrmDashboard"),
128138
icon: Activity,
129139
exact: true,
130140
},
141+
{
142+
path: "/admin/analytics/jobs",
143+
label: t("navigation.jobsAnalytics"),
144+
icon: Briefcase,
145+
exact: true,
146+
},
147+
{
148+
path: "/admin/analytics/quality",
149+
label: t("navigation.qualityAnalytics"),
150+
icon: Target,
151+
exact: true,
152+
},
153+
{
154+
path: "/admin/analytics/oee",
155+
label: t("navigation.oeeAnalytics"),
156+
icon: Gauge,
157+
exact: true,
158+
},
159+
{
160+
path: "/admin/analytics/reliability",
161+
label: t("navigation.reliabilityAnalytics"),
162+
icon: TrendingUp,
163+
exact: true,
164+
},
131165
];
132166

133167
// Operator views - Admin can see what operators see
@@ -230,6 +264,12 @@ export default function AdminLayout({ children }: AdminLayoutProps) {
230264
icon: Webhook,
231265
exact: true,
232266
},
267+
{
268+
path: "/admin/config/mqtt-publishers",
269+
label: t("navigation.mqttPublishers"),
270+
icon: Radio,
271+
exact: true,
272+
},
233273
{
234274
path: "/admin/data-import",
235275
label: t("navigation.dataImport"),
@@ -389,6 +429,53 @@ export default function AdminLayout({ children }: AdminLayoutProps) {
389429

390430
{!collapsed && <Separator className="my-2" />}
391431

432+
{/* Analytics Section - Collapsible */}
433+
{!collapsed && (
434+
<Collapsible open={analyticsOpen} onOpenChange={setAnalyticsOpen} className="space-y-0.5">
435+
<CollapsibleTrigger asChild>
436+
<Button
437+
variant="ghost"
438+
size="sm"
439+
className="w-full justify-start gap-2 font-medium text-muted-foreground h-7 text-xs"
440+
>
441+
<BarChart3 className="h-3.5 w-3.5" />
442+
<span className="flex-1 text-left">{t("navigation.analytics")}</span>
443+
<ChevronDown
444+
className={cn(
445+
"h-3 w-3 transition-transform",
446+
analyticsOpen && "rotate-180"
447+
)}
448+
/>
449+
</Button>
450+
</CollapsibleTrigger>
451+
<CollapsibleContent className="space-y-0.5 pl-3">
452+
{analyticsNavItems.map((item) => {
453+
const isItemActive = item.exact
454+
? isActive(item.path)
455+
: location.pathname.startsWith(item.path);
456+
457+
return (
458+
<Link key={item.path} to={item.path} onClick={() => setMobileOpen(false)}>
459+
<Button
460+
variant="ghost"
461+
className={cn(
462+
"w-full justify-start gap-2 nav-item-hover h-7 text-xs",
463+
isItemActive && "nav-item-active"
464+
)}
465+
size="sm"
466+
>
467+
<item.icon className="h-3.5 w-3.5 shrink-0" />
468+
<span>{item.label}</span>
469+
</Button>
470+
</Link>
471+
);
472+
})}
473+
</CollapsibleContent>
474+
</Collapsible>
475+
)}
476+
477+
{!collapsed && <Separator className="my-2" />}
478+
392479
{/* Configuration Section - Collapsible */}
393480
{!collapsed && (
394481
<Collapsible open={configOpen} onOpenChange={setConfigOpen} className="space-y-0.5">

0 commit comments

Comments
 (0)