"use client"; import { Badge } from "@workspace/ui/components/badge"; import { Button } from "@workspace/ui/components/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@workspace/ui/components/card"; import { Loader2 } from "lucide-react"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { getRecalculationStatus, recalculateGroup, } from "@workspace/ui/services/admin/group"; export default function GroupRecalculate() { const { t } = useTranslation("group"); const [recalculating, setRecalculating] = useState(null); const [loadingStatus, setLoadingStatus] = useState(false); const [status, setStatus] = useState<{ state: string; progress: number; total: number; } | null>(null); const loadStatus = async () => { setLoadingStatus(true); try { const { data } = await getRecalculationStatus(); if (data.data) { setStatus(data.data); } } catch (error) { console.error("Failed to load recalculation status:", error); } finally { setLoadingStatus(false); } }; useEffect(() => { loadStatus(); // Poll status every 2 seconds when recalculating const interval = setInterval(() => { if (status?.state === "running") { loadStatus(); } }, 2000); return () => clearInterval(interval); }, [status?.state]); const handleRecalculate = async (mode: "average" | "subscribe" | "traffic") => { setRecalculating(mode); try { await recalculateGroup({ mode }); toast.success(t("recalculationStarted", "Recalculation started")); loadStatus(); } catch (error) { console.error("Failed to start recalculation:", error); toast.error(t("recalculationFailed", "Failed to start recalculation")); } finally { setRecalculating(null); } }; const getStateLabel = (state: string) => { switch (state) { case "running": return t("running", "Running"); case "completed": return t("completed", "Completed"); case "failed": return t("failed", "Failed"); default: return t("idle", "Idle"); } }; const getStateVariant = (state: string) => { switch (state) { case "running": return "default"; case "completed": return "secondary"; case "failed": return "destructive"; default: return "outline"; } }; return (
{t("groupRecalculation", "Group Recalculation")} {t( "groupRecalculationDescription", "Manually trigger a full recalculation of all user groups based on current configuration" )} {/* Current Status */}
{t("currentStatus", "Current Status")} {loadingStatus ? ( ) : status ? ( {getStateLabel(status.state)} ) : null}
{status?.state === "running" && (
{t("progress", "Progress")} {status.progress} / {status.total || 0}
0 ? (status.progress / status.total) * 100 : 0}%`, }} />
)} {status?.state === "completed" && (
{t("recalculationCompleted", "Recalculation completed successfully")}
)} {status?.state === "failed" && (
{t("recalculationFailed", "Recalculation failed. Please try again.")}
)}
{/* Recalculate Buttons */}
{/* Average Mode Recalculate */}
{t("averageMode", "Average Mode")}
{/* Subscribe Mode Recalculate */}
{t("subscribeMode", "Subscribe Mode")}
{/* Traffic Mode Recalculate */}
{t("trafficMode", "Traffic Mode")}
{/* Warning */}
{t("warning", "Warning")}:{" "} {t( "recalculationWarning", "Recalculation will reassign all users to new groups based on current configuration. This operation cannot be undone." )}
); }