"use client"; import { useState, useEffect } from "react"; import { useTranslations } from "next-intl"; import { getDefaultPricing, formatCost } from "@/shared/constants/pricing"; export default function PricingModal({ isOpen, onClose, onSave }) { const t = useTranslations("pricingModal"); const [pricingData, setPricingData] = useState({}); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); useEffect(() => { if (isOpen) { loadPricing(); } }, [isOpen]); const loadPricing = async () => { setLoading(true); try { const response = await fetch("/api/pricing"); if (response.ok) { const data = await response.json(); setPricingData(data); } else { // Fallback to defaults const defaults = getDefaultPricing(); setPricingData(defaults); } } catch (error) { console.error("Failed to load pricing:", error); const defaults = getDefaultPricing(); setPricingData(defaults); } finally { setLoading(false); } }; const handlePricingChange = (provider, model, field, value) => { const numValue = parseFloat(value); if (isNaN(numValue) || numValue < 0) return; setPricingData((prev) => { const newData = { ...prev }; if (!newData[provider]) newData[provider] = {}; if (!newData[provider][model]) newData[provider][model] = {}; newData[provider][model][field] = numValue; return newData; }); }; const handleSave = async () => { setSaving(true); try { const response = await fetch("/api/pricing", { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(pricingData), }); if (response.ok) { onSave?.(); onClose(); } else { const error = await response.json(); alert(`${t("errorSaveFailed")}: ${error.error}`); } } catch (error) { console.error("Failed to save pricing:", error); alert(t("errorSaveFailed")); } finally { setSaving(false); } }; const handleReset = async () => { if (!confirm(t("resetConfirm"))) return; try { const response = await fetch("/api/pricing", { method: "DELETE" }); if (response.ok) { const defaults = getDefaultPricing(); setPricingData(defaults); } } catch (error) { console.error("Failed to reset pricing:", error); alert(t("errorResetFailed")); } }; if (!isOpen) return null; // Get all unique providers and models for display const allProviders = Object.keys(pricingData).sort(); const pricingFields = ["input", "output", "cached", "reasoning", "cache_creation"]; return (
{/* Header */}

{t("title")}

{/* Content */}
{loading ? (
{t("loading")}
) : (
{/* Instructions */}

{t("pricingRatesFormat")}

{t.rich("ratesDescription", { strong: (c) => {c}, })}

{/* Pricing Tables */} {allProviders.map((provider) => { const models = Object.keys(pricingData[provider]).sort(); return (
{provider.toUpperCase()}
{models.map((model) => ( {pricingFields.map((field) => ( ))} ))}
{t("model")} {t("input")} {t("output")} {t("cached")} {t("reasoning")} {t("cacheCreation")}
{model} handlePricingChange(provider, model, field, e.target.value) } className="w-20 px-2 py-1 text-right bg-bg-base border border-border rounded focus:outline-none focus:border-primary" />
); })} {allProviders.length === 0 && (
{t("noPricingData")}
)}
)}
{/* Footer */}
); }