Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ import { Settings } from "./pages/admin/Settings";
import IntegrationsMarketplace from "./pages/admin/IntegrationsMarketplace";
import Shipments from "./pages/admin/Shipments";
import StepsTemplatesView from "./pages/admin/StepsTemplatesView";
import AnalyticsDashboard from "./pages/admin/Analytics";
import OEEAnalytics from "./pages/admin/analytics/OEEAnalytics";
import ReliabilityAnalytics from "./pages/admin/analytics/ReliabilityAnalytics";
import QRMAnalytics from "./pages/admin/analytics/QRMAnalytics";
import QRMDashboard from "./pages/admin/analytics/QRMDashboard";
import ApiDocs from "./pages/ApiDocs";
import Pricing from "./pages/Pricing";
import { MyPlan } from "./pages/MyPlan";
Expand Down Expand Up @@ -449,6 +454,62 @@ function AppRoutes() {
}
/>

{/* Analytics Routes */}
<Route
path="/admin/analytics"
element={
<ProtectedRoute adminOnly>
<Layout>
<AnalyticsDashboard />
</Layout>
</ProtectedRoute>
}
/>

<Route
path="/admin/analytics/oee"
element={
<ProtectedRoute adminOnly>
<Layout>
<OEEAnalytics />
</Layout>
</ProtectedRoute>
}
/>

<Route
path="/admin/analytics/reliability"
element={
<ProtectedRoute adminOnly>
<Layout>
<ReliabilityAnalytics />
</Layout>
</ProtectedRoute>
}
/>

<Route
path="/admin/analytics/qrm"
element={
<ProtectedRoute adminOnly>
<Layout>
<QRMAnalytics />
</Layout>
</ProtectedRoute>
}
/>

<Route
path="/admin/analytics/qrm-dashboard"
element={
<ProtectedRoute adminOnly>
<Layout>
<QRMDashboard />
</Layout>
</ProtectedRoute>
}
/>

<Route
path="/admin/config/steps-templates"
element={
Expand Down
6 changes: 6 additions & 0 deletions src/components/AdminLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ export default function AdminLayout({ children }: AdminLayoutProps) {
icon: CalendarClock,
exact: true,
},
{
path: "/admin/analytics/qrm-dashboard",
label: "QRM Analytics",
icon: Activity,
exact: true,
},
];

// Operator views - Admin can see what operators see
Expand Down
137 changes: 137 additions & 0 deletions src/components/analytics/OEECharts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React from "react";
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
PieChart,
Pie,
Cell,
} from "recharts";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

const OEECharts = () => {
// Mock Data
const oeeData = [
{ name: "Availability", value: 85, fill: "hsl(var(--brand-primary))" },
{ name: "Performance", value: 92, fill: "hsl(var(--brand-accent))" },
{ name: "Quality", value: 98, fill: "hsl(var(--color-success))" },
];

const machineStateData = [
{ name: "Running", value: 65, color: "hsl(var(--color-success))" },
{ name: "Idle", value: 20, color: "hsl(var(--color-warning))" },
{ name: "Down", value: 10, color: "hsl(var(--color-error))" },
{ name: "Maintenance", value: 5, color: "hsl(var(--neutral-400))" },
];

const trendData = [
{ name: "Mon", oee: 82 },
{ name: "Tue", oee: 84 },
{ name: "Wed", oee: 88 },
{ name: "Thu", oee: 85 },
{ name: "Fri", oee: 90 },
{ name: "Sat", oee: 87 },
{ name: "Sun", oee: 89 },
];

return (
<div className="grid gap-6 md:grid-cols-2">
{/* OEE Breakdown */}
<Card className="glass-card">
<CardHeader>
<CardTitle>OEE Breakdown</CardTitle>
</CardHeader>
<CardContent>
<div className="h-[300px] w-full">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={oeeData} layout="vertical" margin={{ left: 20 }}>
<CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border-subtle))" horizontal={false} />
<XAxis type="number" domain={[0, 100]} stroke="hsl(var(--muted-foreground))" />
<YAxis dataKey="name" type="category" stroke="hsl(var(--muted-foreground))" width={100} />
<Tooltip
contentStyle={{
backgroundColor: "hsl(var(--popover))",
borderColor: "hsl(var(--border))",
color: "hsl(var(--popover-foreground))"
}}
cursor={{ fill: "hsl(var(--muted)/0.2)" }}
/>
<Bar dataKey="value" radius={[0, 4, 4, 0]} barSize={32} />
</BarChart>
</ResponsiveContainer>
</div>
</CardContent>
</Card>

{/* Machine States */}
<Card className="glass-card">
<CardHeader>
<CardTitle>Machine States</CardTitle>
</CardHeader>
<CardContent>
<div className="h-[300px] w-full flex items-center justify-center">
<ResponsiveContainer width="100%" height="100%">
<PieChart>
<Pie
data={machineStateData}
cx="50%"
cy="50%"
innerRadius={60}
outerRadius={100}
paddingAngle={5}
dataKey="value"
>
{machineStateData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} stroke="none" />
))}
</Pie>
<Tooltip
contentStyle={{
backgroundColor: "hsl(var(--popover))",
borderColor: "hsl(var(--border))",
color: "hsl(var(--popover-foreground))"
}}
/>
<Legend />
</PieChart>
</ResponsiveContainer>
</div>
</CardContent>
</Card>

{/* OEE Trend */}
<Card className="glass-card md:col-span-2">
<CardHeader>
<CardTitle>OEE Trend (Last 7 Days)</CardTitle>
</CardHeader>
<CardContent>
<div className="h-[300px] w-full">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={trendData}>
<CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border-subtle))" vertical={false} />
<XAxis dataKey="name" stroke="hsl(var(--muted-foreground))" />
<YAxis domain={[0, 100]} stroke="hsl(var(--muted-foreground))" />
<Tooltip
contentStyle={{
backgroundColor: "hsl(var(--popover))",
borderColor: "hsl(var(--border))",
color: "hsl(var(--popover-foreground))"
}}
cursor={{ fill: "hsl(var(--muted)/0.2)" }}
/>
<Bar dataKey="oee" fill="hsl(var(--brand-primary))" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
</div>
</CardContent>
</Card>
</div>
);
};

export { OEECharts };
95 changes: 95 additions & 0 deletions src/components/analytics/QRMCharts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from "react";
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
ComposedChart,
Line,
} from "recharts";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

const QRMCharts = () => {
// Mock Data
const leadTimeData = [
{ product: "Prod A", mct: 12, touchTime: 4 },
{ product: "Prod B", mct: 18, touchTime: 6 },
{ product: "Prod C", mct: 8, touchTime: 3 },
{ product: "Prod D", mct: 24, touchTime: 8 },
];

const authBacklogData = [
{ day: "Mon", pending: 5, approved: 12 },
{ day: "Tue", pending: 8, approved: 10 },
{ day: "Wed", pending: 4, approved: 15 },
{ day: "Thu", pending: 6, approved: 14 },
{ day: "Fri", pending: 3, approved: 18 },
];

return (
<div className="grid gap-6 md:grid-cols-2">
{/* MCT Analysis */}
<Card className="glass-card">
<CardHeader>
<CardTitle>MCT vs Touch Time (Hours)</CardTitle>
</CardHeader>
<CardContent>
<div className="h-[300px] w-full">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={leadTimeData} layout="vertical" margin={{ left: 20 }}>
<CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border-subtle))" horizontal={false} />
<XAxis type="number" stroke="hsl(var(--muted-foreground))" />
<YAxis dataKey="product" type="category" stroke="hsl(var(--muted-foreground))" width={60} />
<Tooltip
contentStyle={{
backgroundColor: "hsl(var(--popover))",
borderColor: "hsl(var(--border))",
color: "hsl(var(--popover-foreground))"
}}
cursor={{ fill: "hsl(var(--muted)/0.2)" }}
/>
<Legend />
<Bar dataKey="mct" name="MCT (Total Lead Time)" fill="hsl(var(--brand-primary))" radius={[0, 4, 4, 0]} barSize={20} />
<Bar dataKey="touchTime" name="Touch Time (Value Add)" fill="hsl(var(--color-success))" radius={[0, 4, 4, 0]} barSize={20} />
</BarChart>
</ResponsiveContainer>
</div>
</CardContent>
</Card>

{/* Authorization Backlog */}
<Card className="glass-card">
<CardHeader>
<CardTitle>Authorization Backlog Trend</CardTitle>
</CardHeader>
<CardContent>
<div className="h-[300px] w-full">
<ResponsiveContainer width="100%" height="100%">
<ComposedChart data={authBacklogData}>
<CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border-subtle))" vertical={false} />
<XAxis dataKey="day" stroke="hsl(var(--muted-foreground))" />
<YAxis stroke="hsl(var(--muted-foreground))" />
<Tooltip
contentStyle={{
backgroundColor: "hsl(var(--popover))",
borderColor: "hsl(var(--border))",
color: "hsl(var(--popover-foreground))"
}}
/>
<Legend />
<Bar dataKey="pending" name="Pending Auth" fill="hsl(var(--color-warning))" barSize={30} radius={[4, 4, 0, 0]} />
<Line type="monotone" dataKey="approved" name="Approved" stroke="hsl(var(--color-success))" strokeWidth={2} />
</ComposedChart>
</ResponsiveContainer>
</div>
</CardContent>
</Card>
</div>
);
};

export { QRMCharts };
Loading
Loading