"use client"; import { useState, useTransition, useEffect, useRef } from "react"; import { Send, Loader2, CheckCircle2, AlertCircle } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Badge } from "@/components/ui/badge"; interface SendToTelegramButtonProps { packageId: string; packageName: string; /** variant for inline row actions vs larger button */ variant?: "icon" | "default"; } type SendStatus = "idle" | "sending" | "polling" | "sent" | "failed"; export function SendToTelegramButton({ packageId, packageName, variant = "default", }: SendToTelegramButtonProps) { const [open, setOpen] = useState(false); const [status, setStatus] = useState("idle"); const [error, setError] = useState(null); const [isPending, startTransition] = useTransition(); const pollRef = useRef | null>(null); // Clean up polling on unmount useEffect(() => { return () => { if (pollRef.current) clearInterval(pollRef.current); }; }, []); function handleSend() { startTransition(async () => { setStatus("sending"); setError(null); try { const res = await fetch("/api/telegram/bot/send", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ packageId }), }); const data = await res.json(); if (!res.ok) { setStatus("failed"); setError(data.error ?? "Failed to queue send"); return; } // Start polling for status setStatus("polling"); const requestId = data.requestId; pollRef.current = setInterval(async () => { try { const statusRes = await fetch(`/api/telegram/bot/send/${requestId}`); const statusData = await statusRes.json(); if (statusData.status === "SENT") { setStatus("sent"); toast.success(`"${packageName}" sent to Telegram`); if (pollRef.current) clearInterval(pollRef.current); } else if (statusData.status === "FAILED") { setStatus("failed"); setError(statusData.error ?? "Send failed"); if (pollRef.current) clearInterval(pollRef.current); } // PENDING / SENDING — keep polling } catch { // Network error — keep trying } }, 2000); // Stop polling after 60 seconds setTimeout(() => { if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; } setStatus((s: SendStatus) => { if (s === "polling") return "sent"; // Assume queued successfully return s; }); }, 60000); } catch { setStatus("failed"); setError("Network error"); } }); } function handleClose() { if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; } setOpen(false); // Reset after animation setTimeout(() => { setStatus("idle"); setError(null); }, 200); } const trigger = variant === "icon" ? ( ) : ( ); return ( (o ? setOpen(true) : handleClose())}> {trigger} Send to Telegram Send “{packageName}” to your linked Telegram account.
{status === "idle" && (

The bot will forward the archive files from the destination channel to your linked Telegram account.

)} {(status === "sending" || status === "polling") && (

{status === "sending" ? "Queuing…" : "Sending…"}

The bot is forwarding the files to your Telegram.

)} {status === "sent" && (

Sent!

Check your Telegram messages.

)} {status === "failed" && (

Failed

{error}

)}
{status === "idle" && ( <> )} {(status === "sent" || status === "failed") && ( )}
); }