"use client";
import React from "react";
import { formatPlanShort } from "@/lib/utils";
import {
DevicePhoneMobileIcon,
WifiIcon,
SignalIcon,
ClockIcon,
CheckCircleIcon,
ExclamationTriangleIcon,
XCircleIcon,
} from "@heroicons/react/24/outline";
export interface SimDetails {
account: string;
msisdn: string;
iccid?: string;
imsi?: string;
eid?: string;
planCode: string;
status: "active" | "suspended" | "cancelled" | "pending";
simType: "physical" | "esim";
size: "standard" | "nano" | "micro" | "esim";
hasVoice: boolean;
hasSms: boolean;
remainingQuotaKb: number;
remainingQuotaMb: number;
startDate?: string;
ipv4?: string;
ipv6?: string;
voiceMailEnabled?: boolean;
callWaitingEnabled?: boolean;
internationalRoamingEnabled?: boolean;
networkType?: string;
pendingOperations?: Array<{
operation: string;
scheduledDate: string;
}>;
}
interface SimDetailsCardProps {
simDetails: SimDetails;
isLoading?: boolean;
error?: string | null;
embedded?: boolean; // when true, render content without card container
showFeaturesSummary?: boolean; // show the right-side Service Features summary
}
export function SimDetailsCard({
simDetails,
isLoading,
error,
embedded = false,
showFeaturesSummary = true,
}: SimDetailsCardProps) {
const formatPlan = (code?: string) => {
const formatted = formatPlanShort(code);
// Remove "PASI" prefix if present
return formatted?.replace(/^PASI\s*/, "") || formatted;
};
const getStatusIcon = (status: string) => {
switch (status) {
case "active":
return ;
case "suspended":
return ;
case "cancelled":
return ;
case "pending":
return ;
default:
return ;
}
};
const getStatusColor = (status: string) => {
switch (status) {
case "active":
return "bg-green-100 text-green-800";
case "suspended":
return "bg-yellow-100 text-yellow-800";
case "cancelled":
return "bg-red-100 text-red-800";
case "pending":
return "bg-blue-100 text-blue-800";
default:
return "bg-gray-100 text-gray-800";
}
};
const formatDate = (dateString: string) => {
try {
const date = new Date(dateString);
return date.toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
});
} catch {
return dateString;
}
};
const formatQuota = (quotaMb: number) => {
if (quotaMb >= 1000) {
return `${(quotaMb / 1000).toFixed(1)} GB`;
}
return `${quotaMb.toFixed(0)} MB`;
};
if (isLoading) {
const Skeleton = (
);
return Skeleton;
}
if (error) {
return (
Error Loading SIM Details
{error}
);
}
// Modern eSIM details view with usage visualization
if (simDetails.simType === "esim") {
const remainingGB = simDetails.remainingQuotaMb / 1000;
const totalGB = 1048.6; // Mock total - should come from API
const usedGB = totalGB - remainingGB;
const usagePercentage = (usedGB / totalGB) * 100;
// Usage Sparkline Component
const UsageSparkline = ({ data }: { data: Array<{ date: string; usedMB: number }> }) => {
const maxValue = Math.max(...data.map(d => d.usedMB), 1);
const width = 80;
const height = 16;
const points = data.map((d, i) => {
const x = (i / (data.length - 1)) * width;
const y = height - (d.usedMB / maxValue) * height;
return `${x},${y}`;
}).join(' ');
return (
);
};
// Usage Donut Component
const UsageDonut = ({ size = 120 }: { size?: number }) => {
const radius = (size - 16) / 2;
const circumference = 2 * Math.PI * radius;
const strokeDashoffset = circumference - (usagePercentage / 100) * circumference;
return (
{remainingGB.toFixed(1)}
GB remaining
{usagePercentage.toFixed(1)}% used
);
};
return (
{/* Compact Header Bar */}
{simDetails.status.charAt(0).toUpperCase() + simDetails.status.slice(1)}
{formatPlan(simDetails.planCode)}
{simDetails.msisdn}
{/* Usage Visualization */}
Recent Usage History
{[
{ date: "Sep 29", usage: "0 MB" },
{ date: "Sep 28", usage: "0 MB" },
{ date: "Sep 27", usage: "0 MB" },
].map((entry, index) => (
{entry.date}
{entry.usage}
))}
);
}
// Default view for physical SIM cards
return (
{/* Header */}
Physical SIM Details
{formatPlan(simDetails.planCode)} • {`${simDetails.size} SIM`}
{getStatusIcon(simDetails.status)}
{simDetails.status.charAt(0).toUpperCase() + simDetails.status.slice(1)}
{/* Content */}
{/* SIM Information */}
SIM Information
{simDetails.msisdn}
{simDetails.simType === "physical" && (
)}
{simDetails.eid && (
{simDetails.eid}
)}
{simDetails.imsi && (
)}
{simDetails.startDate && (
{formatDate(simDetails.startDate)}
)}
{/* Service Features */}
{showFeaturesSummary && (
Service Features
{formatQuota(simDetails.remainingQuotaMb)}
Voice {simDetails.hasVoice ? "Enabled" : "Disabled"}
SMS {simDetails.hasSms ? "Enabled" : "Disabled"}
{(simDetails.ipv4 || simDetails.ipv6) && (
{simDetails.ipv4 && (
IPv4: {simDetails.ipv4}
)}
{simDetails.ipv6 && (
IPv6: {simDetails.ipv6}
)}
)}
)}
{/* Pending Operations */}
{simDetails.pendingOperations && simDetails.pendingOperations.length > 0 && (
Pending Operations
{simDetails.pendingOperations.map((operation, index) => (
{operation.operation} scheduled for {formatDate(operation.scheduledDate)}
))}
)}
);
}