"use client"; import { useEffect, useState } from "react"; import { useParams, useSearchParams } from "next/navigation"; import Link from "next/link"; import { ServerIcon, CalendarIcon, DocumentTextIcon, XCircleIcon, } from "@heroicons/react/24/outline"; import { useSubscription } from "@/features/subscriptions/hooks"; import { InvoicesList } from "@/features/billing/components/InvoiceList/InvoiceList"; import { Formatting } from "@customer-portal/domain/toolkit"; import { PageLayout } from "@/components/templates/PageLayout"; import { StatusPill } from "@/components/atoms/status-pill"; import { SubscriptionDetailStatsSkeleton, InvoiceListSkeleton, } from "@/components/atoms/loading-skeleton"; import { formatIsoDate } from "@/shared/utils"; const { formatCurrency: sharedFormatCurrency } = Formatting; import { SimManagementSection } from "@/features/subscriptions/components/sim"; import { getBillingCycleLabel, getSubscriptionStatusVariant, } from "@/features/subscriptions/utils/status-presenters"; import { cn } from "@/shared/utils"; export function SubscriptionDetailContainer() { const params = useParams(); const searchParams = useSearchParams(); const [activeTab, setActiveTab] = useState<"overview" | "sim">("overview"); const subscriptionId = parseInt(params.id as string); const { data: subscription, error } = useSubscription(subscriptionId); // Simple loading check: show skeleton until we have data or an error const showLoading = !subscription && !error; useEffect(() => { const updateTab = () => { const hash = typeof window !== "undefined" ? window.location.hash : ""; const service = (searchParams.get("service") || "").toLowerCase(); const isSimContext = hash.includes("sim-management") || service === "sim"; setActiveTab(isSimContext ? "sim" : "overview"); }; updateTab(); if (typeof window !== "undefined") { window.addEventListener("hashchange", updateTab); return () => window.removeEventListener("hashchange", updateTab); } return; }, [searchParams]); const formatDate = (dateString: string | undefined) => formatIsoDate(dateString); const formatCurrency = (amount: number) => sharedFormatCurrency(amount || 0); // Show error message (only when we have an error, not during loading) const pageError = error ? process.env.NODE_ENV === "development" && error instanceof Error ? error.message : "Unable to load subscription details. Please try again." : null; const productNameLower = subscription?.productName?.toLowerCase() ?? ""; const isSimService = productNameLower.includes("sim"); // Match: "Internet", "SonixNet via NTT Optical Fiber", or any NTT-based fiber service const isInternetService = productNameLower.includes("internet") || productNameLower.includes("sonixnet") || (productNameLower.includes("ntt") && productNameLower.includes("fiber")); const canCancel = subscription?.status === "Active"; // Header action: cancel button (for Internet services) const headerActions = isInternetService && canCancel ? ( Cancel Service ) : undefined; // Render skeleton matching loading.tsx structure when loading if (showLoading) { return ( } title="Subscription" description="Loading subscription details..." breadcrumbs={[ { label: "Subscriptions", href: "/account/subscriptions" }, { label: "Subscription" }, ]} >
); } return ( } title={subscription?.productName ?? "Subscription"} actions={headerActions} breadcrumbs={[ { label: "Subscriptions", href: "/account/subscriptions" }, { label: subscription?.productName ?? "Subscription" }, ]} error={pageError} > {subscription ? (
{/* Subscription Stats */}

Service Status

Billing Amount

{formatCurrency(subscription.amount)}

{getBillingCycleLabel(subscription.cycle)}

Next Due Date

{formatDate(subscription.nextDue)}

Registration Date

{formatDate(subscription.registrationDate)}

{/* Tab Navigation for SIM Services */} {isSimService && (
Overview & Billing SIM Management
)} {/* SIM Management Section */} {activeTab === "sim" && isSimService && ( )} {/* Billing History Section */} {activeTab === "overview" && (

Billing History

)}
) : null}
); } export default SubscriptionDetailContainer;