@@ -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" ;
4550import { Link , useLocation } from "react-router-dom" ;
4651import { 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