164 lines
5.7 KiB
TypeScript

"use client";
import { useState } from "react";
import Link from "next/link";
import { useParams } from "next/navigation";
import { PageLayout } from "@/components/templates/PageLayout";
import { SubCard } from "@/components/molecules/SubCard/SubCard";
import { simActionsService } from "@/features/subscriptions/services/sim-actions.service";
import { AlertBanner } from "@/components/molecules/AlertBanner";
import { DevicePhoneMobileIcon } from "@heroicons/react/24/outline";
export function SimTopUpContainer() {
const params = useParams();
const subscriptionId = parseInt(params.id as string);
const [gbAmount, setGbAmount] = useState<string>("1");
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const getCurrentAmountMb = () => {
const gb = parseInt(gbAmount, 10);
return isNaN(gb) ? 0 : gb * 1000;
};
const isValidAmount = () => {
const gb = Number(gbAmount);
return Number.isInteger(gb) && gb >= 1 && gb <= 50; // Freebit API limit
};
const calculateCost = () => {
const gb = parseInt(gbAmount, 10);
return isNaN(gb) ? 0 : gb * 500; // 1GB = 500 JPY
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!isValidAmount()) {
setError("Please enter a whole number between 1 GB and 50 GB");
return;
}
setLoading(true);
setMessage(null);
setError(null);
try {
await simActionsService.topUp(subscriptionId, { quotaMb: getCurrentAmountMb() });
setMessage(`Successfully topped up ${gbAmount} GB for ¥${calculateCost().toLocaleString()}`);
} catch (e: unknown) {
setError(e instanceof Error ? e.message : "Failed to submit top-up");
} finally {
setLoading(false);
}
};
return (
<PageLayout
icon={<DevicePhoneMobileIcon />}
title="Top Up Data"
description="Add data to your SIM"
>
<div className="max-w-3xl mx-auto">
<div className="mb-4">
<Link
href={`/subscriptions/${subscriptionId}#sim-management`}
className="text-blue-600 hover:text-blue-700"
>
Back to SIM Management
</Link>
</div>
<SubCard>
<p className="text-sm text-gray-600 mb-6">
Add additional data quota to your SIM service. Enter the amount of data you want to add.
</p>
{message && (
<div className="mb-4">
<AlertBanner variant="success" title="Top-up Submitted">
{message}
</AlertBanner>
</div>
)}
{error && (
<div className="mb-4">
<AlertBanner variant="error" title="Top-up Failed">
{error}
</AlertBanner>
</div>
)}
<form onSubmit={e => void handleSubmit(e)} className="space-y-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Amount (GB)</label>
<div className="relative">
<input
type="number"
value={gbAmount}
onChange={e => setGbAmount(e.target.value)}
placeholder="Enter amount in GB"
min={1}
max={50}
step={1}
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 pr-12"
/>
<div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
<span className="text-gray-500 text-sm">GB</span>
</div>
</div>
<p className="text-xs text-gray-500 mt-1">
Enter the amount of data you want to add (1 - 50 GB, whole numbers)
</p>
</div>
<div className="p-4 bg-blue-50 rounded-lg border border-blue-200">
<div className="flex justify-between items-center">
<div>
<div className="text-sm font-medium text-blue-900">
{gbAmount && !isNaN(parseInt(gbAmount, 10)) ? `${gbAmount} GB` : "0 GB"}
</div>
<div className="text-xs text-blue-700">= {getCurrentAmountMb()} MB</div>
</div>
<div className="text-right">
<div className="text-lg font-bold text-blue-900">
¥{calculateCost().toLocaleString()}
</div>
<div className="text-xs text-blue-700">(1GB = ¥500)</div>
</div>
</div>
</div>
{!isValidAmount() && gbAmount && (
<div className="bg-red-50 border border-red-200 rounded-lg p-3">
<p className="text-sm text-red-700">
Please enter a valid whole number between 1 and 50 GB.
</p>
</div>
)}
<div className="flex gap-3">
<button
type="submit"
disabled={loading}
className="px-4 py-2 rounded-md bg-blue-600 text-white text-sm disabled:opacity-50"
>
{loading ? "Processing…" : "Submit Top Up"}
</button>
<Link
href={`/subscriptions/${subscriptionId}#sim-management`}
className="px-4 py-2 rounded-md border border-gray-300 text-sm text-gray-700 bg-white hover:bg-gray-50"
>
Back
</Link>
</div>
</form>
</SubCard>
</div>
</PageLayout>
);
}
export default SimTopUpContainer;