diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 193fae22..3e2940aa 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -218,11 +218,21 @@ }, "walletSelector": { "chooseWallet": "Choose a wallet", + "description": "Connect your Stellar wallet to complete this payment.", + "connecting": "Connecting...", "walletConnectWaiting": "Waiting for wallet...", "noProjectId": "(no project ID)", "notInstalled": "(not installed)", + "tapToConnect": "Click to connect", "scanTitle": "Scan with your compatible wallet app", - "pairingFailed": "WalletConnect pairing failed" + "scanDescription": "Scan with Freighter mobile or any WalletConnect-compatible wallet", + "pairingFailed": "WalletConnect pairing failed", + "userRejected": "Connection request was canceled. Please approve it in your wallet to continue.", + "walletConnectUnavailable": "WalletConnect is unavailable right now. Try Freighter or enable a valid WalletConnect project ID.", + "extensionNotFound": "We couldn't find that wallet on this device. Install the extension and try again.", + "noAccountFound": "Your wallet connected, but no Stellar account was returned. Open a Stellar account in the wallet and retry.", + "walletConnectFailed": "We couldn't finish the WalletConnect handshake. Please try again.", + "connectionFailed": "We couldn't connect to that wallet right now. Please try again." }, "checkout": { "paymentRequest": "Payment Request", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 6be329bd..c4b12a5e 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -218,11 +218,21 @@ }, "walletSelector": { "chooseWallet": "Elige una billetera", + "description": "Conecta tu billetera Stellar para completar este pago.", + "connecting": "Conectando...", "walletConnectWaiting": "Esperando la billetera...", "noProjectId": "(sin project ID)", "notInstalled": "(no instalada)", + "tapToConnect": "Haz clic para conectar", "scanTitle": "Escanea con tu app de billetera Stellar", - "pairingFailed": "La vinculacion de WalletConnect fallo" + "scanDescription": "Escanea con Freighter móvil o cualquier billetera compatible con WalletConnect", + "pairingFailed": "La vinculacion de WalletConnect fallo", + "userRejected": "La solicitud de conexión fue cancelada. Apruébala en tu billetera para continuar.", + "walletConnectUnavailable": "WalletConnect no está disponible en este momento. Prueba con Freighter o habilita un WalletConnect project ID válido.", + "extensionNotFound": "No pudimos encontrar esa billetera en este dispositivo. Instala la extensión e inténtalo de nuevo.", + "noAccountFound": "La billetera se conectó, pero no devolvió ninguna cuenta Stellar. Abre una cuenta Stellar en la billetera y vuelve a intentarlo.", + "walletConnectFailed": "No pudimos completar la conexión con WalletConnect. Inténtalo de nuevo.", + "connectionFailed": "No pudimos conectar esa billetera en este momento. Inténtalo de nuevo." }, "checkout": { "paymentRequest": "Solicitud de pago", diff --git a/frontend/messages/pt.json b/frontend/messages/pt.json index b4c62eb6..9fb7811e 100644 --- a/frontend/messages/pt.json +++ b/frontend/messages/pt.json @@ -218,11 +218,21 @@ }, "walletSelector": { "chooseWallet": "Escolha uma carteira", + "description": "Conecte sua carteira Stellar para concluir este pagamento.", + "connecting": "Conectando...", "walletConnectWaiting": "Aguardando a carteira...", "noProjectId": "(sem project ID)", "notInstalled": "(nao instalada)", + "tapToConnect": "Clique para conectar", "scanTitle": "Escaneie com seu app de carteira Stellar", - "pairingFailed": "Falha no pareamento do WalletConnect" + "scanDescription": "Escaneie com o Freighter mobile ou qualquer carteira compatível com WalletConnect", + "pairingFailed": "Falha no pareamento do WalletConnect", + "userRejected": "A solicitação de conexão foi cancelada. Aprove-a na carteira para continuar.", + "walletConnectUnavailable": "O WalletConnect não está disponível agora. Tente usar o Freighter ou habilite um WalletConnect project ID válido.", + "extensionNotFound": "Não encontramos essa carteira neste dispositivo. Instale a extensão e tente novamente.", + "noAccountFound": "A carteira conectou, mas não retornou nenhuma conta Stellar. Abra uma conta Stellar na carteira e tente novamente.", + "walletConnectFailed": "Não conseguimos concluir a conexão com o WalletConnect. Tente novamente.", + "connectionFailed": "Não conseguimos conectar essa carteira agora. Tente novamente." }, "checkout": { "paymentRequest": "Solicitacao de pagamento", diff --git a/frontend/next.config.js b/frontend/next.config.js index 37fae9ca..19044089 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -5,15 +5,24 @@ const createNextIntlPlugin = require("next-intl/plugin"); const withSentryConfig = (config) => config; const withNextIntl = createNextIntlPlugin("./src/i18n/request.ts"); -const withPWA = require("@ducanh2912/next-pwa").default({ - dest: "public", - disable: process.env.NODE_ENV === "development", - register: true, - skipWaiting: true, - fallbacks: { - offline: "/offline", - }, -}); +let withPWA = (config) => config; + +try { + withPWA = require("@ducanh2912/next-pwa").default({ + dest: "public", + disable: process.env.NODE_ENV === "development", + register: true, + skipWaiting: true, + fallbacks: { + offline: "/offline", + }, + }); +} catch (error) { + console.warn( + "next-pwa is unavailable; continuing without PWA support.", + error?.message ?? error, + ); +} const nextConfig = { reactStrictMode: true, diff --git a/frontend/src/app/pay/[id]/page.tsx b/frontend/src/app/pay/[id]/page.tsx index 23634b2a..23f41bc4 100644 --- a/frontend/src/app/pay/[id]/page.tsx +++ b/frontend/src/app/pay/[id]/page.tsx @@ -475,6 +475,14 @@ export default function PaymentPage() { {/* CTA */} {!isSettled && !isFailed && (
+ {t("completePayment")} +
++ {payment.description ?? t("paymentRequest")} +
+{t("connectedVia", { provider: activeProvider.name ?? "" })}
diff --git a/frontend/src/components/AnalyticsCards.tsx b/frontend/src/components/AnalyticsCards.tsx index 35695eb0..05aaf13e 100644 --- a/frontend/src/components/AnalyticsCards.tsx +++ b/frontend/src/components/AnalyticsCards.tsx @@ -84,7 +84,7 @@ export default function AnalyticsCards() { if (loading || !hydrated) { return ( -+
{formatAmount(totalVolume, locale, hideCents)}
@@ -107,9 +107,9 @@ export default function AnalyticsCards() {
+
{successRate.toFixed(1)}%
@@ -119,9 +119,9 @@ export default function AnalyticsCards() {
+
{activeIntents}
diff --git a/frontend/src/components/ApiUsageChart.tsx b/frontend/src/components/ApiUsageChart.tsx
index 22f1be49..e9864d02 100644
--- a/frontend/src/components/ApiUsageChart.tsx
+++ b/frontend/src/components/ApiUsageChart.tsx
@@ -1,6 +1,7 @@
"use client";
import { useEffect, useState } from "react";
+import { useLocale } from "next-intl";
import {
BarChart,
Bar,
@@ -10,6 +11,7 @@ import {
Tooltip,
ResponsiveContainer,
} from "recharts";
+import { localeToLanguageTag } from "@/i18n/config";
import { useMerchantApiKey } from "@/lib/merchant-store";
const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:4000";
@@ -21,9 +23,24 @@ interface DailyUsage {
export default function ApiUsageChart() {
const apiKey = useMerchantApiKey();
+ const locale = localeToLanguageTag(useLocale());
const [data, setData] = useState No API usage data available No payments yet Create your first payment link to start accepting transactions. {t("emptyTitle")} {t("emptyDescription")}
- {sortedPayments.length} of {totalCount} payments{hasActiveFilters ? " (filtered)" : ""}
+ {t("showingResults", { shown: sortedPayments.length, total: totalCount })} {hasActiveFilters ? t("filteredSuffix") : ""}
API Usage - Last 7 Days
@@ -105,8 +133,17 @@ export default function ApiUsageChart() {
+
-
@@ -319,23 +321,23 @@ export default function RecentPayments({ showSkeleton = false }: { showSkeleton?
onClick={() => { setSelectedPayment(payment.id); setIsSheetOpen(true); }}
className={`group cursor-pointer transition-colors hover:bg-[#F9F9F9] ${flashedIds.has(payment.id) ? "bg-emerald-50" : ""}`}
>
-
-
-
- Description
-
- Actions
+
+
+
+ Description
+
+ Actions
-
+
+
{payment.amount}
{payment.asset}
-
+
- {payment.recipient.slice(0,8)}…{payment.recipient.slice(-6)}
+
{payment.description || —}
-
+
{new Date(payment.created_at).toLocaleDateString(locale, { month: "short", day: "numeric", year: "numeric" })}
-
+
@@ -347,15 +349,15 @@ export default function RecentPayments({ showSkeleton = false }: { showSkeleton?
{/* Pagination */}
{totalCount > 0 && (
-