"use client"; import { CSSProperties, useState } from "react"; import { useParams, useRouter } from "next/navigation"; import { Permission } from "../../auth-context"; import { tradesApi } from "../../api"; import { Header } from "../../components/Header"; import { SatsDisplay } from "../../components/SatsDisplay"; import { StatusBadge } from "../../components/StatusBadge"; import { useRequireAuth } from "../../hooks/useRequireAuth"; import { useAsyncData } from "../../hooks/useAsyncData"; import { formatDateTime } from "../../utils/date"; import { formatEur } from "../../utils/exchange"; import { layoutStyles, typographyStyles, bannerStyles, buttonStyles, tradeCardStyles, } from "../../styles/shared"; import { useTranslation } from "../../hooks/useTranslation"; import { useLanguage } from "../../hooks/useLanguage"; export default function TradeDetailPage() { const router = useRouter(); const params = useParams(); const publicId = params?.id as string | undefined; const [cancelError, setCancelError] = useState(null); const t = useTranslation("trades"); const tExchange = useTranslation("exchange"); const { locale } = useLanguage(); // Map locale codes to Intl locale strings const intlLocale = locale === "es" ? "es-ES" : locale === "ca" ? "ca-ES" : "en-US"; const { user, isLoading, isAuthorized } = useRequireAuth({ requiredPermission: Permission.VIEW_OWN_EXCHANGES, fallbackRedirect: "/", }); const { data: trade, isLoading: isLoadingTrade, error, } = useAsyncData( () => { if (!publicId) throw new Error("Trade ID is required"); return tradesApi.getTrade(publicId); }, { enabled: !!user && isAuthorized && !!publicId, onError: () => { // Error message is set by useAsyncData }, } ); if (isLoading || isLoadingTrade) { return (
{t("details.loading")}
); } if (!isAuthorized) { return null; } if (error || (!isLoadingTrade && !trade)) { return (

{t("details.title")}

{error &&
{error || t("details.error")}
}
); } if (!trade) { return null; } const isBuy = trade.direction === "buy"; return (

{t("details.title")}

{t("details.tradeInformation")}

{t("details.status")} {""}
{t("details.time")} {formatDateTime(trade.slot_start, intlLocale)}
{t("details.direction")} {isBuy ? t("details.buyBtc") : t("details.sellBtc")}
{t("details.paymentMethod")} {isBuy ? `${t("details.receiveVia")} ${trade.bitcoin_transfer_method === "onchain" ? tExchange("transferMethod.onchain") : tExchange("transferMethod.lightning")}` : `${t("details.sendVia")} ${trade.bitcoin_transfer_method === "onchain" ? tExchange("transferMethod.onchain") : tExchange("transferMethod.lightning")}`}

{t("details.amounts")}

{t("details.eurAmount")} {formatEur(trade.eur_amount)}
{t("details.bitcoinAmount")}

{t("details.pricing")}

{t("details.marketPrice")} € {trade.market_price_eur.toLocaleString(intlLocale, { maximumFractionDigits: 0, })} /BTC
{t("details.agreedPrice")} € {trade.agreed_price_eur.toLocaleString(intlLocale, { maximumFractionDigits: 0, })} /BTC
{t("details.premium")} {trade.premium_percentage}%

{t("details.timestamps")}

{t("details.created")} {formatDateTime(trade.created_at, intlLocale)}
{trade.cancelled_at && (
{t("details.cancelled")} {formatDateTime(trade.cancelled_at, intlLocale)}
)} {trade.completed_at && (
{t("details.completed")} {formatDateTime(trade.completed_at, intlLocale)}
)}
{cancelError &&
{cancelError}
} {trade.status === "booked" && (
)}
); } const styles: Record = { content: { flex: 1, padding: "2rem", maxWidth: "800px", margin: "0 auto", width: "100%", }, header: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "2rem", }, tradeDetailCard: { background: "rgba(255, 255, 255, 0.03)", border: "1px solid rgba(255, 255, 255, 0.08)", borderRadius: "12px", padding: "2rem", }, detailSection: { marginBottom: "2rem", }, sectionTitle: { fontFamily: "'DM Sans', system-ui, sans-serif", fontSize: "1.1rem", fontWeight: 600, color: "#fff", marginBottom: "1rem", }, detailGrid: { display: "flex", flexDirection: "column", gap: "1rem", }, detailRow: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "0.75rem 0", borderBottom: "1px solid rgba(255, 255, 255, 0.05)", }, detailLabel: { fontFamily: "'DM Sans', system-ui, sans-serif", fontSize: "0.9rem", color: "rgba(255, 255, 255, 0.6)", }, detailValue: { fontFamily: "'DM Sans', system-ui, sans-serif", fontSize: "0.9rem", color: "#fff", fontWeight: 500, }, actionSection: { marginTop: "2rem", paddingTop: "2rem", borderTop: "1px solid rgba(255, 255, 255, 0.1)", }, };