"use client"; import Link from "next/link"; import { useParams, useRouter } from "next/navigation"; import { useEffect, useState, type ReactNode } from "react"; import { simActionsService, type CancellationPreview } from "@/features/subscriptions/services/sim-actions.service"; type Step = 1 | 2 | 3; function Notice({ title, children }: { title: string; children: ReactNode }) { return (
{title}
{children}
); } function InfoRow({ label, value }: { label: string; value: string }) { return (
{label}
{value}
); } export function SimCancelContainer() { const params = useParams(); const router = useRouter(); const subscriptionId = params.id as string; const [step, setStep] = useState(1); const [loading, setLoading] = useState(false); const [preview, setPreview] = useState(null); const [error, setError] = useState(null); const [message, setMessage] = useState(null); const [acceptTerms, setAcceptTerms] = useState(false); const [confirmMonthEnd, setConfirmMonthEnd] = useState(false); const [selectedMonth, setSelectedMonth] = useState(""); const [alternativeEmail, setAlternativeEmail] = useState(""); const [alternativeEmail2, setAlternativeEmail2] = useState(""); const [comments, setComments] = useState(""); const [loadingPreview, setLoadingPreview] = useState(true); useEffect(() => { const fetchPreview = async () => { try { const data = await simActionsService.getCancellationPreview(subscriptionId); setPreview(data); } catch (e: unknown) { setError(e instanceof Error ? e.message : "Failed to load cancellation information"); } finally { setLoadingPreview(false); } }; void fetchPreview(); }, [subscriptionId]); const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const emailProvided = alternativeEmail.trim().length > 0 || alternativeEmail2.trim().length > 0; const emailValid = !emailProvided || (emailPattern.test(alternativeEmail.trim()) && emailPattern.test(alternativeEmail2.trim())); const emailsMatch = !emailProvided || alternativeEmail.trim() === alternativeEmail2.trim(); const canProceedStep2 = !!preview && !!selectedMonth; const canProceedStep3 = acceptTerms && confirmMonthEnd && emailValid && emailsMatch; const selectedMonthInfo = preview?.availableMonths.find(m => m.value === selectedMonth); const submit = async () => { setLoading(true); setError(null); setMessage(null); if (!selectedMonth) { setError("Please select a cancellation month before submitting."); setLoading(false); return; } try { await simActionsService.cancelFull(subscriptionId, { cancellationMonth: selectedMonth, confirmRead: acceptTerms, confirmCancel: confirmMonthEnd, alternativeEmail: alternativeEmail.trim() || undefined, comments: comments.trim() || undefined, }); setMessage("Cancellation request submitted. You will receive a confirmation email."); setTimeout(() => router.push(`/subscriptions/${subscriptionId}#sim-management`), 2000); } catch (e: unknown) { setError(e instanceof Error ? e.message : "Failed to submit cancellation"); } finally { setLoading(false); } }; if (loadingPreview) { return (
); } return (
← Back to SIM Management
{[1, 2, 3].map(s => (
))}
Step {step} of 3
{error && (
{error}
)} {message && (
{message}
)}

Cancel SIM

Cancel your SIM subscription. Please read all the information carefully before proceeding.

{/* Minimum Contract Warning */} {preview?.isWithinMinimumTerm && (
Minimum Contract Term Warning
Your subscription is still within the minimum contract period (ends {preview.minimumContractEndDate}). Early cancellation may result in additional charges for the remaining months.
)} {step === 1 && (
{/* SIM Info */}
{/* Month Selection */}

Your subscription will be cancelled at the end of the selected month.

)} {step === 2 && (
Online cancellations must be made from this website by the 25th of the desired cancellation month. Once a request of a cancellation of the SONIXNET SIM is accepted from this online form, a confirmation email containing details of the SIM plan will be sent to the registered email address. The SIM card is a rental piece of hardware and must be returned to Assist Solutions upon cancellation. The cancellation request through this website retains to your SIM subscriptions only. To cancel any other services with Assist Solutions (home internet etc.) please contact Assist Solutions at info@asolutions.co.jp The SONIXNET SIM has a minimum contract term agreement of three months (sign-up month is not included in the minimum term of three months; ie. sign-up in January = minimum term is February, March, April). If the minimum contract term is not fulfilled, the monthly fees of the remaining months will be charged upon cancellation. Cancellation of option services only (Voice Mail, Call Waiting) while keeping the base plan active is not possible from this online form. Please contact Assist Solutions Customer Support (info@asolutions.co.jp) for more information. Upon cancelling the base plan, all additional options associated with the requested SIM plan will be cancelled. Upon cancellation the SIM phone number will be lost. In order to keep the phone number active to be used with a different cellular provider, a request for an MNP transfer (administrative fee ¥1,000+tax) is necessary. The MNP cannot be requested from this online form. Please contact Assist Solutions Customer Support (info@asolutions.co.jp) for more information.
setAcceptTerms(e.target.checked)} className="h-4 w-4 text-blue-600 border-gray-300 rounded mt-0.5" />
setConfirmMonthEnd(e.target.checked)} disabled={!selectedMonth} className="h-4 w-4 text-blue-600 border-gray-300 rounded mt-0.5" />
)} {step === 3 && (
{/* Voice SIM Notice */}
For Voice-enabled SIM subscriptions:
Calling charges are post payment. Your bill for the final month's calling charges will be charged on your credit card on file during the first week of the second month after the cancellation.
If you would like to make the payment with a different credit card, please contact Assist Solutions at info@asolutions.co.jp
{/* Registered Email */}
Your registered email address is:{" "} {preview?.customerEmail || "—"}
You will receive a cancellation confirmation email. If you would like to receive this email on a different address, please enter the address below.
{/* Alternative Email */}
setAlternativeEmail(e.target.value)} placeholder="you@example.com" />
setAlternativeEmail2(e.target.value)} placeholder="you@example.com" />
{emailProvided && !emailValid && (
Please enter a valid email address in both fields.
)} {emailProvided && emailValid && !emailsMatch && (
Email addresses do not match.
)} {/* Comments */}