2025-09-04 18:34:28 +09:00
|
|
|
"use client";
|
|
|
|
|
|
2025-09-09 15:45:03 +09:00
|
|
|
import React from "react";
|
2025-09-10 16:33:24 +09:00
|
|
|
import { formatPlanShort } from "@/lib/plan";
|
2025-09-09 15:45:03 +09:00
|
|
|
import {
|
|
|
|
|
DevicePhoneMobileIcon,
|
|
|
|
|
WifiIcon,
|
2025-09-04 18:34:28 +09:00
|
|
|
SignalIcon,
|
|
|
|
|
ClockIcon,
|
|
|
|
|
CheckCircleIcon,
|
|
|
|
|
ExclamationTriangleIcon,
|
2025-09-09 15:45:03 +09:00
|
|
|
XCircleIcon,
|
|
|
|
|
} from "@heroicons/react/24/outline";
|
2025-09-04 18:34:28 +09:00
|
|
|
|
|
|
|
|
export interface SimDetails {
|
|
|
|
|
account: string;
|
|
|
|
|
msisdn: string;
|
2025-09-05 12:30:57 +09:00
|
|
|
iccid?: string;
|
|
|
|
|
imsi?: string;
|
2025-09-04 18:34:28 +09:00
|
|
|
eid?: string;
|
|
|
|
|
planCode: string;
|
2025-09-09 15:45:03 +09:00
|
|
|
status: "active" | "suspended" | "cancelled" | "pending";
|
|
|
|
|
simType: "physical" | "esim";
|
|
|
|
|
size: "standard" | "nano" | "micro" | "esim";
|
2025-09-04 18:34:28 +09:00
|
|
|
hasVoice: boolean;
|
|
|
|
|
hasSms: boolean;
|
|
|
|
|
remainingQuotaKb: number;
|
|
|
|
|
remainingQuotaMb: number;
|
2025-09-05 12:30:57 +09:00
|
|
|
startDate?: string;
|
2025-09-04 18:34:28 +09:00
|
|
|
ipv4?: string;
|
|
|
|
|
ipv6?: string;
|
2025-09-05 12:30:57 +09:00
|
|
|
voiceMailEnabled?: boolean;
|
|
|
|
|
callWaitingEnabled?: boolean;
|
|
|
|
|
internationalRoamingEnabled?: boolean;
|
|
|
|
|
networkType?: string;
|
2025-09-04 18:34:28 +09:00
|
|
|
pendingOperations?: Array<{
|
|
|
|
|
operation: string;
|
|
|
|
|
scheduledDate: string;
|
|
|
|
|
}>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface SimDetailsCardProps {
|
|
|
|
|
simDetails: SimDetails;
|
|
|
|
|
isLoading?: boolean;
|
|
|
|
|
error?: string | null;
|
2025-09-05 15:39:43 +09:00
|
|
|
embedded?: boolean; // when true, render content without card container
|
|
|
|
|
showFeaturesSummary?: boolean; // show the right-side Service Features summary
|
2025-09-04 18:34:28 +09:00
|
|
|
}
|
|
|
|
|
|
2025-09-09 15:45:03 +09:00
|
|
|
export function SimDetailsCard({
|
|
|
|
|
simDetails,
|
|
|
|
|
isLoading,
|
|
|
|
|
error,
|
|
|
|
|
embedded = false,
|
|
|
|
|
showFeaturesSummary = true,
|
|
|
|
|
}: SimDetailsCardProps) {
|
2025-09-10 16:33:24 +09:00
|
|
|
const formatPlan = (code?: string) => formatPlanShort(code);
|
2025-09-04 18:34:28 +09:00
|
|
|
const getStatusIcon = (status: string) => {
|
|
|
|
|
switch (status) {
|
2025-09-09 15:45:03 +09:00
|
|
|
case "active":
|
2025-09-04 18:34:28 +09:00
|
|
|
return <CheckCircleIcon className="h-6 w-6 text-green-500" />;
|
2025-09-09 15:45:03 +09:00
|
|
|
case "suspended":
|
2025-09-04 18:34:28 +09:00
|
|
|
return <ExclamationTriangleIcon className="h-6 w-6 text-yellow-500" />;
|
2025-09-09 15:45:03 +09:00
|
|
|
case "cancelled":
|
2025-09-04 18:34:28 +09:00
|
|
|
return <XCircleIcon className="h-6 w-6 text-red-500" />;
|
2025-09-09 15:45:03 +09:00
|
|
|
case "pending":
|
2025-09-04 18:34:28 +09:00
|
|
|
return <ClockIcon className="h-6 w-6 text-blue-500" />;
|
|
|
|
|
default:
|
|
|
|
|
return <DevicePhoneMobileIcon className="h-6 w-6 text-gray-500" />;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getStatusColor = (status: string) => {
|
|
|
|
|
switch (status) {
|
2025-09-09 15:45:03 +09:00
|
|
|
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";
|
2025-09-04 18:34:28 +09:00
|
|
|
default:
|
2025-09-09 15:45:03 +09:00
|
|
|
return "bg-gray-100 text-gray-800";
|
2025-09-04 18:34:28 +09:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const formatDate = (dateString: string) => {
|
|
|
|
|
try {
|
|
|
|
|
const date = new Date(dateString);
|
2025-09-09 15:45:03 +09:00
|
|
|
return date.toLocaleDateString("en-US", {
|
|
|
|
|
year: "numeric",
|
|
|
|
|
month: "short",
|
|
|
|
|
day: "numeric",
|
2025-09-04 18:34:28 +09:00
|
|
|
});
|
|
|
|
|
} catch {
|
|
|
|
|
return dateString;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const formatQuota = (quotaMb: number) => {
|
2025-09-06 17:02:20 +09:00
|
|
|
if (quotaMb >= 1000) {
|
|
|
|
|
return `${(quotaMb / 1000).toFixed(1)} GB`;
|
2025-09-04 18:34:28 +09:00
|
|
|
}
|
|
|
|
|
return `${quotaMb.toFixed(0)} MB`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (isLoading) {
|
2025-09-05 15:39:43 +09:00
|
|
|
const Skeleton = (
|
2025-09-09 15:45:03 +09:00
|
|
|
<div
|
|
|
|
|
className={`${embedded ? "" : "bg-white shadow-lg rounded-xl border border-gray-100 hover:shadow-xl transition-shadow duration-300 "}p-6 lg:p-8`}
|
|
|
|
|
>
|
2025-09-04 18:34:28 +09:00
|
|
|
<div className="animate-pulse">
|
|
|
|
|
<div className="flex items-center space-x-4">
|
2025-09-05 15:39:43 +09:00
|
|
|
<div className="rounded-full bg-gradient-to-br from-blue-200 to-blue-300 h-14 w-14"></div>
|
|
|
|
|
<div className="flex-1 space-y-3">
|
|
|
|
|
<div className="h-5 bg-gradient-to-r from-gray-200 to-gray-300 rounded-lg w-3/4"></div>
|
|
|
|
|
<div className="h-4 bg-gradient-to-r from-gray-200 to-gray-300 rounded-lg w-1/2"></div>
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-09-05 15:39:43 +09:00
|
|
|
<div className="mt-8 space-y-4">
|
|
|
|
|
<div className="h-4 bg-gradient-to-r from-gray-200 to-gray-300 rounded-lg"></div>
|
|
|
|
|
<div className="h-4 bg-gradient-to-r from-gray-200 to-gray-300 rounded-lg w-5/6"></div>
|
|
|
|
|
<div className="h-4 bg-gradient-to-r from-gray-200 to-gray-300 rounded-lg w-4/6"></div>
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2025-09-05 15:39:43 +09:00
|
|
|
return Skeleton;
|
2025-09-04 18:34:28 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
return (
|
2025-09-09 15:45:03 +09:00
|
|
|
<div
|
|
|
|
|
className={`${embedded ? "" : "bg-white shadow-lg rounded-xl border border-red-100 "}p-6 lg:p-8`}
|
|
|
|
|
>
|
2025-09-04 18:34:28 +09:00
|
|
|
<div className="text-center">
|
2025-09-05 15:39:43 +09:00
|
|
|
<div className="bg-red-50 rounded-full p-3 w-16 h-16 mx-auto mb-4">
|
|
|
|
|
<ExclamationTriangleIcon className="h-10 w-10 text-red-500 mx-auto" />
|
|
|
|
|
</div>
|
|
|
|
|
<h3 className="text-lg font-semibold text-gray-900 mb-2">Error Loading SIM Details</h3>
|
|
|
|
|
<p className="text-red-600 text-sm">{error}</p>
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-05 12:30:57 +09:00
|
|
|
// Specialized, minimal eSIM details view
|
2025-09-09 15:45:03 +09:00
|
|
|
if (simDetails.simType === "esim") {
|
2025-09-05 12:30:57 +09:00
|
|
|
return (
|
2025-09-09 15:45:03 +09:00
|
|
|
<div
|
|
|
|
|
className={`${embedded ? "" : "bg-white shadow-lg rounded-xl border border-gray-100 hover:shadow-xl transition-shadow duration-300"}`}
|
|
|
|
|
>
|
2025-09-05 15:39:43 +09:00
|
|
|
{/* Header */}
|
2025-09-09 15:45:03 +09:00
|
|
|
<div className={`${embedded ? "" : "px-6 lg:px-8 py-5 border-b border-gray-200"}`}>
|
2025-09-05 15:39:43 +09:00
|
|
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between space-y-3 sm:space-y-0">
|
2025-09-05 12:30:57 +09:00
|
|
|
<div className="flex items-center">
|
2025-09-05 15:39:43 +09:00
|
|
|
<div className="bg-blue-50 rounded-xl p-2 mr-4">
|
|
|
|
|
<WifiIcon className="h-8 w-8 text-blue-600" />
|
|
|
|
|
</div>
|
2025-09-05 12:30:57 +09:00
|
|
|
<div>
|
2025-09-05 15:39:43 +09:00
|
|
|
<h3 className="text-xl font-semibold text-gray-900">eSIM Details</h3>
|
2025-09-09 15:45:03 +09:00
|
|
|
<p className="text-sm text-gray-600 font-medium">
|
|
|
|
|
Current Plan: {formatPlan(simDetails.planCode)}
|
|
|
|
|
</p>
|
2025-09-05 12:30:57 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-09-09 15:45:03 +09:00
|
|
|
<span
|
|
|
|
|
className={`inline-flex px-4 py-2 text-sm font-semibold rounded-full ${getStatusColor(simDetails.status)} self-start sm:self-auto`}
|
|
|
|
|
>
|
2025-09-05 12:30:57 +09:00
|
|
|
{simDetails.status.charAt(0).toUpperCase() + simDetails.status.slice(1)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-09-09 15:45:03 +09:00
|
|
|
<div className={`${embedded ? "" : "px-6 lg:px-8 py-6"}`}>
|
2025-09-05 15:39:43 +09:00
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
<div>
|
|
|
|
|
<h4 className="text-sm font-semibold text-gray-700 uppercase tracking-wider mb-4 flex items-center">
|
|
|
|
|
<DevicePhoneMobileIcon className="h-4 w-4 mr-2 text-blue-500" />
|
|
|
|
|
SIM Information
|
|
|
|
|
</h4>
|
|
|
|
|
<div className="bg-gray-50 rounded-lg p-4">
|
|
|
|
|
<div>
|
2025-09-09 15:45:03 +09:00
|
|
|
<label className="text-xs font-medium text-gray-500 uppercase tracking-wide">
|
|
|
|
|
Phone Number
|
|
|
|
|
</label>
|
2025-09-05 15:39:43 +09:00
|
|
|
<p className="text-lg font-semibold text-gray-900 mt-1">{simDetails.msisdn}</p>
|
|
|
|
|
</div>
|
2025-09-05 12:30:57 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-09-05 15:39:43 +09:00
|
|
|
<div>
|
2025-09-09 15:45:03 +09:00
|
|
|
<label className="text-xs font-medium text-gray-500 uppercase tracking-wide">
|
|
|
|
|
Data Remaining
|
|
|
|
|
</label>
|
|
|
|
|
<p className="text-2xl font-bold text-green-600 mt-1">
|
|
|
|
|
{formatQuota(simDetails.remainingQuotaMb)}
|
|
|
|
|
</p>
|
2025-09-05 12:30:57 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-09-05 15:39:43 +09:00
|
|
|
{showFeaturesSummary && (
|
|
|
|
|
<div>
|
|
|
|
|
<h4 className="text-sm font-semibold text-gray-700 uppercase tracking-wider mb-4 flex items-center">
|
|
|
|
|
<CheckCircleIcon className="h-4 w-4 mr-2 text-green-500" />
|
|
|
|
|
Service Features
|
|
|
|
|
</h4>
|
|
|
|
|
<div className="space-y-3">
|
|
|
|
|
<div className="flex justify-between items-center py-2 px-3 bg-gray-50 rounded-lg">
|
|
|
|
|
<span className="text-sm text-gray-700">Voice Mail (¥300/month)</span>
|
2025-09-09 15:45:03 +09:00
|
|
|
<span
|
|
|
|
|
className={`text-sm font-semibold px-2 py-1 rounded-full ${simDetails.voiceMailEnabled ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-600"}`}
|
|
|
|
|
>
|
|
|
|
|
{simDetails.voiceMailEnabled ? "Enabled" : "Disabled"}
|
2025-09-05 15:39:43 +09:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex justify-between items-center py-2 px-3 bg-gray-50 rounded-lg">
|
|
|
|
|
<span className="text-sm text-gray-700">Call Waiting (¥300/month)</span>
|
2025-09-09 15:45:03 +09:00
|
|
|
<span
|
|
|
|
|
className={`text-sm font-semibold px-2 py-1 rounded-full ${simDetails.callWaitingEnabled ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-600"}`}
|
|
|
|
|
>
|
|
|
|
|
{simDetails.callWaitingEnabled ? "Enabled" : "Disabled"}
|
2025-09-05 15:39:43 +09:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex justify-between items-center py-2 px-3 bg-gray-50 rounded-lg">
|
|
|
|
|
<span className="text-sm text-gray-700">International Roaming</span>
|
2025-09-09 15:45:03 +09:00
|
|
|
<span
|
|
|
|
|
className={`text-sm font-semibold px-2 py-1 rounded-full ${simDetails.internationalRoamingEnabled ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-600"}`}
|
|
|
|
|
>
|
|
|
|
|
{simDetails.internationalRoamingEnabled ? "Enabled" : "Disabled"}
|
2025-09-05 15:39:43 +09:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex justify-between items-center py-2 px-3 bg-blue-50 rounded-lg">
|
|
|
|
|
<span className="text-sm text-gray-700">4G/5G</span>
|
|
|
|
|
<span className="text-sm font-semibold px-2 py-1 rounded-full bg-blue-100 text-blue-800">
|
2025-09-09 15:45:03 +09:00
|
|
|
{simDetails.networkType || "5G"}
|
2025-09-05 15:39:43 +09:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2025-09-05 12:30:57 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-04 18:34:28 +09:00
|
|
|
return (
|
2025-09-09 15:45:03 +09:00
|
|
|
<div className={`${embedded ? "" : "bg-white shadow rounded-lg"}`}>
|
2025-09-04 18:34:28 +09:00
|
|
|
{/* Header */}
|
2025-09-09 15:45:03 +09:00
|
|
|
<div className={`${embedded ? "" : "px-6 py-4 border-b border-gray-200"}`}>
|
2025-09-04 18:34:28 +09:00
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div className="flex items-center">
|
|
|
|
|
<div className="text-2xl mr-3">
|
2025-09-05 15:39:43 +09:00
|
|
|
<DevicePhoneMobileIcon className="h-8 w-8 text-blue-600" />
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
<div>
|
2025-09-05 15:39:43 +09:00
|
|
|
<h3 className="text-lg font-medium text-gray-900">Physical SIM Details</h3>
|
2025-09-10 16:33:24 +09:00
|
|
|
<p className="text-sm text-gray-500">
|
|
|
|
|
{formatPlan(simDetails.planCode)} • {`${simDetails.size} SIM`}
|
|
|
|
|
</p>
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex items-center space-x-3">
|
|
|
|
|
{getStatusIcon(simDetails.status)}
|
2025-09-09 15:45:03 +09:00
|
|
|
<span
|
|
|
|
|
className={`inline-flex px-3 py-1 text-sm font-semibold rounded-full ${getStatusColor(simDetails.status)}`}
|
|
|
|
|
>
|
2025-09-04 18:34:28 +09:00
|
|
|
{simDetails.status.charAt(0).toUpperCase() + simDetails.status.slice(1)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Content */}
|
2025-09-09 15:45:03 +09:00
|
|
|
<div className={`${embedded ? "" : "px-6 py-4"}`}>
|
2025-09-04 18:34:28 +09:00
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
|
|
|
{/* SIM Information */}
|
|
|
|
|
<div>
|
|
|
|
|
<h4 className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-3">
|
|
|
|
|
SIM Information
|
|
|
|
|
</h4>
|
|
|
|
|
<div className="space-y-3">
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-gray-500">Phone Number</label>
|
|
|
|
|
<p className="text-sm font-medium text-gray-900">{simDetails.msisdn}</p>
|
|
|
|
|
</div>
|
2025-09-09 15:45:03 +09:00
|
|
|
|
|
|
|
|
{simDetails.simType === "physical" && (
|
2025-09-04 18:34:28 +09:00
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-gray-500">ICCID</label>
|
|
|
|
|
<p className="text-sm font-mono text-gray-900 break-all">{simDetails.iccid}</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{simDetails.eid && (
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-gray-500">EID (eSIM)</label>
|
|
|
|
|
<p className="text-sm font-mono text-gray-900 break-all">{simDetails.eid}</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-09-05 12:30:57 +09:00
|
|
|
{simDetails.imsi && (
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-gray-500">IMSI</label>
|
|
|
|
|
<p className="text-sm font-mono text-gray-900">{simDetails.imsi}</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2025-09-04 18:34:28 +09:00
|
|
|
|
2025-09-05 12:30:57 +09:00
|
|
|
{simDetails.startDate && (
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-gray-500">Service Start Date</label>
|
|
|
|
|
<p className="text-sm text-gray-900">{formatDate(simDetails.startDate)}</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Service Features */}
|
2025-09-05 15:39:43 +09:00
|
|
|
{showFeaturesSummary && (
|
|
|
|
|
<div>
|
|
|
|
|
<h4 className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-3">
|
|
|
|
|
Service Features
|
|
|
|
|
</h4>
|
|
|
|
|
<div className="space-y-3">
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-gray-500">Data Remaining</label>
|
2025-09-09 15:45:03 +09:00
|
|
|
<p className="text-lg font-semibold text-green-600">
|
|
|
|
|
{formatQuota(simDetails.remainingQuotaMb)}
|
|
|
|
|
</p>
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
|
2025-09-05 15:39:43 +09:00
|
|
|
<div className="flex items-center space-x-4">
|
|
|
|
|
<div className="flex items-center">
|
2025-09-09 15:45:03 +09:00
|
|
|
<SignalIcon
|
|
|
|
|
className={`h-4 w-4 mr-1 ${simDetails.hasVoice ? "text-green-500" : "text-gray-400"}`}
|
|
|
|
|
/>
|
|
|
|
|
<span
|
|
|
|
|
className={`text-sm ${simDetails.hasVoice ? "text-green-600" : "text-gray-500"}`}
|
|
|
|
|
>
|
|
|
|
|
Voice {simDetails.hasVoice ? "Enabled" : "Disabled"}
|
2025-09-05 15:39:43 +09:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex items-center">
|
2025-09-09 15:45:03 +09:00
|
|
|
<DevicePhoneMobileIcon
|
|
|
|
|
className={`h-4 w-4 mr-1 ${simDetails.hasSms ? "text-green-500" : "text-gray-400"}`}
|
|
|
|
|
/>
|
|
|
|
|
<span
|
|
|
|
|
className={`text-sm ${simDetails.hasSms ? "text-green-600" : "text-gray-500"}`}
|
|
|
|
|
>
|
|
|
|
|
SMS {simDetails.hasSms ? "Enabled" : "Disabled"}
|
2025-09-05 15:39:43 +09:00
|
|
|
</span>
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-09-05 15:39:43 +09:00
|
|
|
|
|
|
|
|
{(simDetails.ipv4 || simDetails.ipv6) && (
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-gray-500">IP Address</label>
|
|
|
|
|
<div className="space-y-1">
|
|
|
|
|
{simDetails.ipv4 && (
|
|
|
|
|
<p className="text-sm font-mono text-gray-900">IPv4: {simDetails.ipv4}</p>
|
|
|
|
|
)}
|
|
|
|
|
{simDetails.ipv6 && (
|
|
|
|
|
<p className="text-sm font-mono text-gray-900">IPv6: {simDetails.ipv6}</p>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
2025-09-05 15:39:43 +09:00
|
|
|
)}
|
2025-09-04 18:34:28 +09:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Pending Operations */}
|
|
|
|
|
{simDetails.pendingOperations && simDetails.pendingOperations.length > 0 && (
|
|
|
|
|
<div className="mt-6 pt-6 border-t border-gray-200">
|
|
|
|
|
<h4 className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-3">
|
|
|
|
|
Pending Operations
|
|
|
|
|
</h4>
|
|
|
|
|
<div className="bg-blue-50 rounded-lg p-4">
|
|
|
|
|
{simDetails.pendingOperations.map((operation, index) => (
|
|
|
|
|
<div key={index} className="flex items-center text-sm">
|
|
|
|
|
<ClockIcon className="h-4 w-4 text-blue-500 mr-2" />
|
|
|
|
|
<span className="text-blue-800">
|
|
|
|
|
{operation.operation} scheduled for {formatDate(operation.scheduledDate)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|