diff --git a/apps/web-dashboard/src/app/settings/page.tsx b/apps/web-dashboard/src/app/settings/page.tsx
new file mode 100644
index 0000000..0a6d3fd
--- /dev/null
+++ b/apps/web-dashboard/src/app/settings/page.tsx
@@ -0,0 +1,75 @@
+import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
+import { Button } from "@/components/ui/button";
+import { Settings } from "lucide-react";
+
+export default function SettingsPage() {
+ return (
+
+
+
+
+
Settings
+
Platform configuration and preferences.
+
+
+
+
+
+ );
+}
diff --git a/apps/web-dashboard/src/app/subscribers/page.tsx b/apps/web-dashboard/src/app/subscribers/page.tsx
new file mode 100644
index 0000000..63ba8a2
--- /dev/null
+++ b/apps/web-dashboard/src/app/subscribers/page.tsx
@@ -0,0 +1,94 @@
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import { UserPlus, Search, Download } from "lucide-react";
+
+const subscribers = [
+ { id: 1, name: "Alice Martin", msisdn: "+33612345678", imsi: "208930000000001", email: "alice@example.com", status: "active" as const, balance: 45.0, plan: "Premium 5G" },
+ { id: 2, name: "Bob Dupont", msisdn: "+33698765432", imsi: "208930000000002", email: "bob@example.com", status: "active" as const, balance: 12.5, plan: "Basic LTE" },
+ { id: 3, name: "Claire Moreau", msisdn: "+33678901234", imsi: "208930000000003", email: "claire@example.com", status: "provisioning" as const, balance: 0.0, plan: "Premium 5G" },
+ { id: 4, name: "David Leroy", msisdn: "+33667890123", imsi: "208930000000004", email: "david@example.com", status: "suspended" as const, balance: -2.3, plan: "Standard" },
+ { id: 5, name: "Emma Petit", msisdn: "+33656789012", imsi: "208930000000005", email: "emma@example.com", status: "active" as const, balance: 78.9, plan: "Premium 5G" },
+ { id: 6, name: "François Blanc", msisdn: "+33645678901", imsi: "208930000000006", email: "francois@example.com", status: "active" as const, balance: 25.0, plan: "Standard" },
+ { id: 7, name: "Gabrielle Roux", msisdn: "+33634567890", imsi: "208930000000007", email: "gabrielle@example.com", status: "terminated" as const, balance: 0.0, plan: "Basic LTE" },
+ { id: 8, name: "Henri Faure", msisdn: "+33623456789", imsi: "208930000000008", email: "henri@example.com", status: "active" as const, balance: 156.2, plan: "Enterprise" },
+];
+
+const statusVariant = (s: string) =>
+ s === "active" ? "success" : s === "suspended" ? "warning" : s === "terminated" ? "destructive" : "secondary";
+
+export default function SubscribersPage() {
+ return (
+
+
+
+
Subscribers
+
Manage subscriber accounts and profiles.
+
+
+
+
+
+
+
+
+
+ All Subscribers
+
+
+
+
+
+
+
+ | Name |
+ MSISDN |
+ IMSI |
+ Plan |
+ Balance |
+ Status |
+ Actions |
+
+
+
+ {subscribers.map((sub) => (
+
+
+
+ {sub.name}
+ {sub.email}
+
+ |
+ {sub.msisdn} |
+ {sub.imsi} |
+ {sub.plan} |
+
+
+ €{sub.balance.toFixed(2)}
+
+ |
+
+ {sub.status}
+ |
+
+
+ |
+
+ ))}
+
+
+
+
+
+
+ );
+}
diff --git a/apps/web-dashboard/src/app/usage/page.tsx b/apps/web-dashboard/src/app/usage/page.tsx
new file mode 100644
index 0000000..3b52bd0
--- /dev/null
+++ b/apps/web-dashboard/src/app/usage/page.tsx
@@ -0,0 +1,78 @@
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { StatCard } from "@/components/stat-card";
+import { Activity, HardDrive, Phone, MessageSquare } from "lucide-react";
+
+const usageEvents = [
+ { id: 1, imsi: "208930000000001", type: "DATA", volume: "1.2 GB", cost: "€2.40", time: "2 min ago" },
+ { id: 2, imsi: "208930000000002", type: "VOICE", volume: "15 min", cost: "€0.75", time: "5 min ago" },
+ { id: 3, imsi: "208930000000005", type: "SMS", volume: "3 msgs", cost: "€0.30", time: "12 min ago" },
+ { id: 4, imsi: "208930000000001", type: "DATA", volume: "450 MB", cost: "€0.90", time: "18 min ago" },
+ { id: 5, imsi: "208930000000008", type: "DATA", volume: "2.8 GB", cost: "€5.60", time: "25 min ago" },
+ { id: 6, imsi: "208930000000006", type: "VOICE", volume: "42 min", cost: "€2.10", time: "30 min ago" },
+ { id: 7, imsi: "208930000000002", type: "DATA", volume: "780 MB", cost: "€1.56", time: "45 min ago" },
+ { id: 8, imsi: "208930000000005", type: "SMS", volume: "1 msg", cost: "€0.10", time: "1 hr ago" },
+];
+
+const typeIcon = (t: string) => {
+ if (t === "DATA") return HardDrive;
+ if (t === "VOICE") return Phone;
+ return MessageSquare;
+};
+
+export default function UsagePage() {
+ return (
+
+
+
Usage & Billing
+
Monitor real-time usage and billing metrics.
+
+
+
+
+
+
+
+
+
+
+
+ Recent Usage Events
+
+
+
+
+
+
+ | Type |
+ IMSI |
+ Volume |
+ Cost |
+ Time |
+
+
+
+ {usageEvents.map((evt) => {
+ const Icon = typeIcon(evt.type);
+ return (
+
+ |
+
+
+ {evt.type}
+
+ |
+ {evt.imsi} |
+ {evt.volume} |
+ {evt.cost} |
+ {evt.time} |
+
+ );
+ })}
+
+
+
+
+
+
+ );
+}
diff --git a/apps/web-dashboard/src/components/sidebar.tsx b/apps/web-dashboard/src/components/sidebar.tsx
new file mode 100644
index 0000000..892de9c
--- /dev/null
+++ b/apps/web-dashboard/src/components/sidebar.tsx
@@ -0,0 +1,62 @@
+"use client";
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import {
+ Users,
+ LayoutDashboard,
+ Activity,
+ CreditCard,
+ Shield,
+ Settings,
+ Radio,
+ HeartPulse,
+} from "lucide-react";
+import { cn } from "@/lib/utils";
+
+const navItems = [
+ { href: "/", label: "Dashboard", icon: LayoutDashboard },
+ { href: "/subscribers", label: "Subscribers", icon: Users },
+ { href: "/usage", label: "Usage & Billing", icon: Activity },
+ { href: "/payments", label: "Payments", icon: CreditCard },
+ { href: "/esim", label: "eSIM Profiles", icon: Radio },
+ { href: "/health", label: "System Health", icon: HeartPulse },
+ { href: "/chaos", label: "Chaos Engineering", icon: Shield },
+ { href: "/settings", label: "Settings", icon: Settings },
+];
+
+export function Sidebar() {
+ const pathname = usePathname();
+
+ return (
+
+ );
+}
diff --git a/apps/web-dashboard/src/components/stat-card.tsx b/apps/web-dashboard/src/components/stat-card.tsx
new file mode 100644
index 0000000..5e60301
--- /dev/null
+++ b/apps/web-dashboard/src/components/stat-card.tsx
@@ -0,0 +1,36 @@
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { type LucideIcon } from "lucide-react";
+import { cn } from "@/lib/utils";
+
+interface StatCardProps {
+ title: string;
+ value: string | number;
+ description?: string;
+ icon: LucideIcon;
+ trend?: { value: number; positive: boolean };
+ className?: string;
+}
+
+export function StatCard({ title, value, description, icon: Icon, trend, className }: StatCardProps) {
+ return (
+
+
+ {title}
+
+
+
+ {value}
+ {(description || trend) && (
+
+ {trend && (
+
+ {trend.positive ? "+" : ""}{trend.value}%{" "}
+
+ )}
+ {description}
+
+ )}
+
+
+ );
+}