@djangocfg/ext-payments 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.cjs +3 -2
- package/dist/config.js +3 -2
- package/dist/hooks.cjs +559 -543
- package/dist/hooks.js +558 -543
- package/dist/index.cjs +559 -543
- package/dist/index.d.cts +0 -97
- package/dist/index.d.ts +0 -97
- package/dist/index.js +558 -543
- package/package.json +9 -8
- package/src/api/generated/ext_payments/CLAUDE.md +76 -0
- package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +1 -8
- package/src/api/generated/ext_payments/_utils/fetchers/index.ts +1 -8
- package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +1 -8
- package/src/api/generated/ext_payments/_utils/hooks/index.ts +1 -8
- package/src/api/generated/ext_payments/_utils/schemas/index.ts +1 -8
- package/src/api/generated/ext_payments/api-instance.ts +1 -8
- package/src/api/generated/ext_payments/enums.ts +1 -8
- package/src/api/generated/ext_payments/errors.ts +1 -8
- package/src/api/generated/ext_payments/ext_payments__payments/index.ts +1 -8
- package/src/api/generated/ext_payments/ext_payments__payments/models.ts +1 -8
- package/src/api/generated/ext_payments/http.ts +1 -8
- package/src/api/generated/ext_payments/index.ts +1 -8
- package/src/api/generated/ext_payments/logger.ts +1 -8
- package/src/api/generated/ext_payments/retry.ts +1 -8
- package/src/api/generated/ext_payments/storage.ts +1 -8
- package/src/api/generated/ext_payments/validation-events.ts +1 -8
- package/src/api/index.ts +2 -1
- package/src/config.ts +1 -0
- package/src/contexts/BalancesContext.tsx +2 -1
- package/src/contexts/CurrenciesContext.tsx +2 -1
- package/src/contexts/OverviewContext.tsx +5 -5
- package/src/contexts/PaymentsContext.tsx +6 -5
- package/src/contexts/PaymentsExtensionProvider.tsx +3 -2
- package/src/contexts/RootPaymentsContext.tsx +2 -1
- package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +5 -7
- package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +10 -27
- package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +15 -18
- package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +6 -13
- package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +8 -11
- package/src/layouts/PaymentsLayout/views/overview/index.tsx +1 -0
- package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +43 -42
- package/src/layouts/PaymentsLayout/views/payments/index.tsx +1 -0
- package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +71 -84
- package/src/layouts/PaymentsLayout/views/transactions/index.tsx +1 -0
package/dist/index.cjs
CHANGED
|
@@ -4,19 +4,21 @@ var consola = require('consola');
|
|
|
4
4
|
var pRetry = require('p-retry');
|
|
5
5
|
var zod = require('zod');
|
|
6
6
|
var api = require('@djangocfg/ext-base/api');
|
|
7
|
+
var lucideReact = require('lucide-react');
|
|
8
|
+
var uiNextjs = require('@djangocfg/ui-nextjs');
|
|
7
9
|
var react = require('react');
|
|
8
10
|
var useSWR = require('swr');
|
|
9
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
-
var uiNextjs = require('@djangocfg/ui-nextjs');
|
|
11
|
-
var lucideReact = require('lucide-react');
|
|
12
12
|
var reactHookForm = require('react-hook-form');
|
|
13
13
|
var zod$1 = require('@hookform/resolvers/zod');
|
|
14
|
+
var moment = require('moment');
|
|
14
15
|
var extBase = require('@djangocfg/ext-base');
|
|
15
16
|
|
|
16
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
18
|
|
|
18
19
|
var pRetry__default = /*#__PURE__*/_interopDefault(pRetry);
|
|
19
20
|
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
|
|
21
|
+
var moment__default = /*#__PURE__*/_interopDefault(moment);
|
|
20
22
|
|
|
21
23
|
var __defProp = Object.defineProperty;
|
|
22
24
|
var __export = (target, all) => {
|
|
@@ -1590,6 +1592,11 @@ function useRootPaymentsContext() {
|
|
|
1590
1592
|
}
|
|
1591
1593
|
return context;
|
|
1592
1594
|
}
|
|
1595
|
+
var isDevelopment = process.env.NODE_ENV === "development";
|
|
1596
|
+
var logger = consola.createConsola({
|
|
1597
|
+
level: isDevelopment ? 4 : 1
|
|
1598
|
+
}).withTag("ext-payments");
|
|
1599
|
+
var paymentsLogger = logger;
|
|
1593
1600
|
|
|
1594
1601
|
// src/layouts/PaymentsLayout/events.ts
|
|
1595
1602
|
var PAYMENT_EVENTS = {
|
|
@@ -1610,156 +1617,526 @@ var openPaymentDetailsDialog = (id) => {
|
|
|
1610
1617
|
var closePaymentsDialog = () => {
|
|
1611
1618
|
window.dispatchEvent(new Event(PAYMENT_EVENTS.CLOSE_DIALOG));
|
|
1612
1619
|
};
|
|
1613
|
-
var
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
const
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1620
|
+
var PaymentCreateSchema = zod.z.object({
|
|
1621
|
+
amount_usd: zod.z.number().min(0.01, "Amount must be at least $0.01"),
|
|
1622
|
+
currency_code: zod.z.string().min(1, "Please select a currency")
|
|
1623
|
+
});
|
|
1624
|
+
var CreatePaymentDialog = () => {
|
|
1625
|
+
const [open, setOpen] = react.useState(false);
|
|
1626
|
+
const [isSubmitting, setIsSubmitting] = react.useState(false);
|
|
1627
|
+
const { createPayment } = usePaymentsContext();
|
|
1628
|
+
const { currencies, isLoadingCurrencies } = useRootPaymentsContext();
|
|
1629
|
+
const form = reactHookForm.useForm({
|
|
1630
|
+
resolver: zod$1.zodResolver(PaymentCreateSchema),
|
|
1631
|
+
defaultValues: {
|
|
1632
|
+
amount_usd: 10,
|
|
1633
|
+
currency_code: "USDT"
|
|
1634
|
+
}
|
|
1635
|
+
});
|
|
1636
|
+
const currenciesList = react.useMemo(() => {
|
|
1637
|
+
const data = currencies?.currencies || currencies?.results || currencies || [];
|
|
1638
|
+
return Array.isArray(data) ? data : [];
|
|
1639
|
+
}, [currencies]);
|
|
1640
|
+
const currencyOptions = react.useMemo(() => {
|
|
1641
|
+
return currenciesList.filter((curr) => curr.is_enabled !== false).map((curr) => ({
|
|
1642
|
+
code: curr.code || curr.currency_code || curr.symbol,
|
|
1643
|
+
name: curr.name || curr.code || curr.currency_code,
|
|
1644
|
+
usd_rate: curr.usd_rate || curr.rate || 1,
|
|
1645
|
+
network: curr.network || null
|
|
1646
|
+
}));
|
|
1647
|
+
}, [currenciesList]);
|
|
1648
|
+
const calculateCryptoAmount = react.useMemo(() => {
|
|
1649
|
+
const amountUsd = form.watch("amount_usd");
|
|
1650
|
+
const currencyCode = form.watch("currency_code");
|
|
1651
|
+
const currency = currencyOptions.find((c) => c.code === currencyCode);
|
|
1652
|
+
if (!currency || !currency.usd_rate || !amountUsd) {
|
|
1653
|
+
return null;
|
|
1654
|
+
}
|
|
1655
|
+
const cryptoAmount = amountUsd / currency.usd_rate;
|
|
1656
|
+
return {
|
|
1657
|
+
amount: cryptoAmount,
|
|
1658
|
+
currency: currency.code,
|
|
1659
|
+
rate: currency.usd_rate,
|
|
1660
|
+
network: currency.network
|
|
1661
|
+
};
|
|
1662
|
+
}, [form.watch("amount_usd"), form.watch("currency_code"), currencyOptions]);
|
|
1663
|
+
react.useEffect(() => {
|
|
1664
|
+
const handleOpen = () => setOpen(true);
|
|
1665
|
+
const handleClose2 = () => setOpen(false);
|
|
1666
|
+
window.addEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
|
|
1667
|
+
window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1668
|
+
return () => {
|
|
1669
|
+
window.removeEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
|
|
1670
|
+
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1671
|
+
};
|
|
1672
|
+
}, []);
|
|
1673
|
+
const handleClose = () => {
|
|
1674
|
+
setOpen(false);
|
|
1675
|
+
form.reset();
|
|
1626
1676
|
};
|
|
1627
|
-
|
|
1628
|
-
if (
|
|
1677
|
+
react.useEffect(() => {
|
|
1678
|
+
if (currencyOptions.length > 0 && !form.getValues("currency_code")) {
|
|
1679
|
+
form.setValue("currency_code", currencyOptions[0].code);
|
|
1680
|
+
}
|
|
1681
|
+
}, [currencyOptions, form]);
|
|
1682
|
+
const handleSubmit = async (data) => {
|
|
1629
1683
|
try {
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1684
|
+
setIsSubmitting(true);
|
|
1685
|
+
const result = await createPayment();
|
|
1686
|
+
handleClose();
|
|
1687
|
+
closePaymentsDialog();
|
|
1688
|
+
const paymentData = result;
|
|
1689
|
+
const paymentId = paymentData?.payment?.id || paymentData?.id;
|
|
1690
|
+
if (paymentId) {
|
|
1691
|
+
openPaymentDetailsDialog(String(paymentId));
|
|
1692
|
+
}
|
|
1693
|
+
} catch (error) {
|
|
1694
|
+
paymentsLogger.error("Failed to create payment:", error);
|
|
1695
|
+
} finally {
|
|
1696
|
+
setIsSubmitting(false);
|
|
1637
1697
|
}
|
|
1638
1698
|
};
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1699
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-md", children: [
|
|
1700
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
1701
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Create Payment" }),
|
|
1702
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Create a new payment to add funds to your account." })
|
|
1703
|
+
] }),
|
|
1704
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-4", children: [
|
|
1705
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1706
|
+
uiNextjs.FormField,
|
|
1707
|
+
{
|
|
1708
|
+
control: form.control,
|
|
1709
|
+
name: "amount_usd",
|
|
1710
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
|
|
1711
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Amount (USD)" }),
|
|
1712
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1713
|
+
uiNextjs.Input,
|
|
1714
|
+
{
|
|
1715
|
+
type: "number",
|
|
1716
|
+
step: "0.01",
|
|
1717
|
+
min: "0.01",
|
|
1718
|
+
placeholder: "10.00",
|
|
1719
|
+
...field,
|
|
1720
|
+
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
1721
|
+
}
|
|
1722
|
+
) }),
|
|
1723
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormDescription, { children: "The amount you want to pay in USD." }),
|
|
1724
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
|
|
1725
|
+
] })
|
|
1726
|
+
}
|
|
1727
|
+
),
|
|
1728
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1729
|
+
uiNextjs.FormField,
|
|
1730
|
+
{
|
|
1731
|
+
control: form.control,
|
|
1732
|
+
name: "currency_code",
|
|
1733
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
|
|
1734
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Currency" }),
|
|
1735
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1736
|
+
uiNextjs.Select,
|
|
1737
|
+
{
|
|
1738
|
+
onValueChange: field.onChange,
|
|
1739
|
+
defaultValue: field.value,
|
|
1740
|
+
disabled: isLoadingCurrencies,
|
|
1741
|
+
children: [
|
|
1742
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectValue, { placeholder: "Select currency..." }) }) }),
|
|
1743
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectContent, { children: currencyOptions.map((curr) => /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: curr.code, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1744
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: curr.code, size: 16 }),
|
|
1745
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: curr.code }),
|
|
1746
|
+
curr.network && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
1747
|
+
"(",
|
|
1748
|
+
curr.network,
|
|
1749
|
+
")"
|
|
1750
|
+
] })
|
|
1751
|
+
] }) }, curr.code)) })
|
|
1752
|
+
]
|
|
1753
|
+
}
|
|
1754
|
+
),
|
|
1755
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormDescription, { children: "The cryptocurrency to use for payment." }),
|
|
1756
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
|
|
1757
|
+
] })
|
|
1758
|
+
}
|
|
1759
|
+
),
|
|
1760
|
+
calculateCryptoAmount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm bg-muted p-4 space-y-3", children: [
|
|
1761
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1762
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "You will send" }),
|
|
1763
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1764
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: calculateCryptoAmount.currency, size: 16 }),
|
|
1765
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-semibold", children: [
|
|
1766
|
+
calculateCryptoAmount.amount.toFixed(8),
|
|
1767
|
+
" ",
|
|
1768
|
+
calculateCryptoAmount.currency
|
|
1769
|
+
] })
|
|
1770
|
+
] })
|
|
1645
1771
|
] }),
|
|
1646
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
}
|
|
1654
|
-
const balanceData = balance?.balance || balance;
|
|
1655
|
-
const amountUsd = balanceData?.amount_usd ?? 0;
|
|
1656
|
-
const totalDeposited = balanceData?.total_deposited ?? 0;
|
|
1657
|
-
const totalWithdrawn = balanceData?.total_withdrawn ?? 0;
|
|
1658
|
-
const lastTransactionAt = balanceData?.last_transaction_at;
|
|
1659
|
-
const isEmpty = amountUsd === 0 && totalDeposited === 0;
|
|
1660
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
|
|
1661
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
|
|
1662
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1663
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-5 w-5" }),
|
|
1664
|
-
"Account Balance"
|
|
1665
|
-
] }),
|
|
1666
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1667
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { variant: "ghost", size: "sm", onClick: refreshBalance, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4" }) }),
|
|
1668
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { size: "sm", onClick: () => openCreatePaymentDialog(), children: [
|
|
1669
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
1670
|
-
"Add Funds"
|
|
1671
|
-
] })
|
|
1672
|
-
] })
|
|
1673
|
-
] }) }),
|
|
1674
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "space-y-4", children: [
|
|
1675
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1676
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-4xl font-bold", children: formatCurrency(amountUsd) }),
|
|
1677
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mt-1", children: [
|
|
1678
|
-
"Available balance \u2022 Last updated ",
|
|
1679
|
-
formatDate(lastTransactionAt)
|
|
1680
|
-
] })
|
|
1681
|
-
] }),
|
|
1682
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4 pt-4 border-t", children: [
|
|
1683
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1684
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Total Deposited" }),
|
|
1685
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-semibold text-green-600", children: formatCurrency(totalDeposited) })
|
|
1772
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1773
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "You will receive" }),
|
|
1774
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-lg font-bold", children: [
|
|
1775
|
+
"$",
|
|
1776
|
+
form.watch("amount_usd")?.toFixed(2),
|
|
1777
|
+
" USD"
|
|
1778
|
+
] })
|
|
1686
1779
|
] }),
|
|
1687
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1688
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
1689
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1690
|
-
|
|
1780
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
1781
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Rate" }),
|
|
1782
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
1783
|
+
"1 ",
|
|
1784
|
+
calculateCryptoAmount.currency,
|
|
1785
|
+
" = $",
|
|
1786
|
+
calculateCryptoAmount.rate?.toFixed(2)
|
|
1787
|
+
] })
|
|
1788
|
+
] }),
|
|
1789
|
+
calculateCryptoAmount.network && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1790
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
|
|
1791
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: calculateCryptoAmount.network })
|
|
1792
|
+
] }) })
|
|
1691
1793
|
] }),
|
|
1692
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1693
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.
|
|
1694
|
-
|
|
1794
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogFooter, { children: [
|
|
1795
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { type: "button", variant: "outline", onClick: handleClose, disabled: isSubmitting, children: "Cancel" }),
|
|
1796
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { type: "submit", disabled: isSubmitting || currencyOptions.length === 0, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1797
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
1798
|
+
"Creating..."
|
|
1799
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1800
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
1801
|
+
"Create Payment"
|
|
1802
|
+
] }) })
|
|
1803
|
+
] })
|
|
1804
|
+
] }) })
|
|
1805
|
+
] }) });
|
|
1806
|
+
};
|
|
1807
|
+
var PaymentDetailsDialog = () => {
|
|
1808
|
+
const [open, setOpen] = react.useState(false);
|
|
1809
|
+
const [paymentId, setPaymentId] = react.useState(null);
|
|
1810
|
+
const [timeLeft, setTimeLeft] = react.useState("");
|
|
1811
|
+
const shouldFetch = open && !!paymentId;
|
|
1812
|
+
const { data: payment, isLoading, error, mutate } = usePaymentsPaymentsRetrieve(
|
|
1813
|
+
shouldFetch ? paymentId : "",
|
|
1814
|
+
apiPayments
|
|
1815
|
+
);
|
|
1816
|
+
react.useEffect(() => {
|
|
1817
|
+
const handleOpen = (event) => {
|
|
1818
|
+
const customEvent = event;
|
|
1819
|
+
setPaymentId(customEvent.detail.id);
|
|
1820
|
+
setOpen(true);
|
|
1821
|
+
};
|
|
1822
|
+
const handleClose2 = () => {
|
|
1823
|
+
setOpen(false);
|
|
1824
|
+
setPaymentId(null);
|
|
1825
|
+
};
|
|
1826
|
+
window.addEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
1827
|
+
window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1828
|
+
return () => {
|
|
1829
|
+
window.removeEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
1830
|
+
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
1831
|
+
};
|
|
1832
|
+
}, []);
|
|
1833
|
+
const handleClose = () => {
|
|
1834
|
+
setOpen(false);
|
|
1835
|
+
setPaymentId(null);
|
|
1836
|
+
};
|
|
1837
|
+
react.useEffect(() => {
|
|
1838
|
+
if (!payment?.expires_at) return;
|
|
1839
|
+
const updateTimeLeft = () => {
|
|
1840
|
+
const now = moment__default.default();
|
|
1841
|
+
const expires = moment__default.default.utc(payment.expires_at);
|
|
1842
|
+
const diff = expires.diff(now);
|
|
1843
|
+
if (diff <= 0) {
|
|
1844
|
+
setTimeLeft("Expired");
|
|
1845
|
+
return;
|
|
1846
|
+
}
|
|
1847
|
+
const duration = moment__default.default.duration(diff);
|
|
1848
|
+
const hours = Math.floor(duration.asHours());
|
|
1849
|
+
const minutes = duration.minutes();
|
|
1850
|
+
const seconds = duration.seconds();
|
|
1851
|
+
setTimeLeft(`${hours}h ${minutes}m ${seconds}s`);
|
|
1852
|
+
};
|
|
1853
|
+
updateTimeLeft();
|
|
1854
|
+
const interval = setInterval(updateTimeLeft, 1e3);
|
|
1855
|
+
return () => clearInterval(interval);
|
|
1856
|
+
}, [payment?.expires_at]);
|
|
1857
|
+
const getStatusInfo = () => {
|
|
1858
|
+
switch (payment?.status?.toLowerCase()) {
|
|
1859
|
+
case "pending":
|
|
1860
|
+
return { icon: lucideReact.Clock, color: "text-yellow-500", bg: "bg-yellow-500/10" };
|
|
1861
|
+
case "completed":
|
|
1862
|
+
case "success":
|
|
1863
|
+
return { icon: lucideReact.CheckCircle2, color: "text-green-500", bg: "bg-green-500/10" };
|
|
1864
|
+
case "failed":
|
|
1865
|
+
case "error":
|
|
1866
|
+
return { icon: lucideReact.XCircle, color: "text-red-500", bg: "bg-red-500/10" };
|
|
1867
|
+
case "expired":
|
|
1868
|
+
return { icon: lucideReact.AlertCircle, color: "text-gray-500", bg: "bg-gray-500/10" };
|
|
1869
|
+
case "confirming":
|
|
1870
|
+
return { icon: lucideReact.RefreshCw, color: "text-blue-500", bg: "bg-blue-500/10" };
|
|
1871
|
+
default:
|
|
1872
|
+
return { icon: lucideReact.Clock, color: "text-gray-500", bg: "bg-gray-500/10" };
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
if (!open) return null;
|
|
1876
|
+
if (isLoading) {
|
|
1877
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
|
|
1878
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
1879
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
|
|
1880
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Loading payment information..." })
|
|
1881
|
+
] }),
|
|
1882
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-8 w-8 animate-spin text-muted-foreground" }) })
|
|
1883
|
+
] }) });
|
|
1884
|
+
}
|
|
1885
|
+
if (shouldFetch && !isLoading && (error || !payment)) {
|
|
1886
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
|
|
1887
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
1888
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
|
|
1889
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Failed to load payment information" })
|
|
1890
|
+
] }),
|
|
1891
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
|
|
1892
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-12 w-12 text-destructive" }),
|
|
1893
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: error ? `Error: ${error}` : "Payment not found" }),
|
|
1894
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { onClick: () => mutate(), children: "Try Again" })
|
|
1895
|
+
] })
|
|
1896
|
+
] }) });
|
|
1897
|
+
}
|
|
1898
|
+
const statusInfo = getStatusInfo();
|
|
1899
|
+
const StatusIcon = statusInfo.icon;
|
|
1900
|
+
const qrCodeUrl = payment.pay_address ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
1901
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
|
|
1902
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
1903
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
|
|
1904
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Send cryptocurrency to complete your payment" })
|
|
1905
|
+
] }),
|
|
1906
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
1907
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-3 p-4 rounded-sm ${statusInfo.bg}`, children: [
|
|
1908
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: `h-5 w-5 ${statusInfo.color}` }),
|
|
1909
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
1910
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold capitalize", children: payment.status }),
|
|
1911
|
+
payment.status === "pending" && timeLeft && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
1912
|
+
"Expires in ",
|
|
1913
|
+
timeLeft
|
|
1914
|
+
] })
|
|
1915
|
+
] })
|
|
1916
|
+
] }),
|
|
1917
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1918
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 bg-muted rounded-sm", children: [
|
|
1919
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Amount to send" }),
|
|
1920
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1921
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: String(payment.currency_code || "BTC"), size: 20 }),
|
|
1922
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-bold text-lg", children: [
|
|
1923
|
+
payment.pay_amount || "0.00000000",
|
|
1924
|
+
" ",
|
|
1925
|
+
payment.currency_code
|
|
1926
|
+
] })
|
|
1927
|
+
] })
|
|
1928
|
+
] }),
|
|
1929
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
1930
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Equivalent to" }),
|
|
1931
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-lg", children: [
|
|
1932
|
+
"$",
|
|
1933
|
+
parseFloat(payment.amount_usd || "0").toFixed(2),
|
|
1934
|
+
" USD"
|
|
1935
|
+
] })
|
|
1936
|
+
] }),
|
|
1937
|
+
payment.internal_payment_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
1938
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Payment Order #" }),
|
|
1939
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", children: payment.internal_payment_id })
|
|
1940
|
+
] }),
|
|
1941
|
+
payment.currency_network && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
1942
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
|
|
1943
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: payment.currency_network })
|
|
1944
|
+
] })
|
|
1945
|
+
] }),
|
|
1946
|
+
qrCodeUrl && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-6 bg-white rounded-sm", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: qrCodeUrl, alt: "Payment QR Code", className: "w-48 h-48" }) }),
|
|
1947
|
+
payment.pay_address && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1948
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
|
|
1949
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1950
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.pay_address }),
|
|
1951
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CopyButton, { value: payment.pay_address, variant: "outline" })
|
|
1952
|
+
] })
|
|
1953
|
+
] }),
|
|
1954
|
+
payment.transaction_hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1955
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
1956
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.transaction_hash })
|
|
1957
|
+
] }),
|
|
1958
|
+
payment.payment_url && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1959
|
+
uiNextjs.Button,
|
|
1960
|
+
{
|
|
1961
|
+
variant: "outline",
|
|
1962
|
+
className: "w-full",
|
|
1963
|
+
onClick: () => window.open(payment.payment_url, "_blank"),
|
|
1964
|
+
children: [
|
|
1965
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
1966
|
+
"Open in Payment Provider"
|
|
1967
|
+
]
|
|
1968
|
+
}
|
|
1969
|
+
),
|
|
1970
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t space-y-2 text-xs text-muted-foreground", children: [
|
|
1971
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
1972
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment ID" }),
|
|
1973
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: payment.id })
|
|
1974
|
+
] }),
|
|
1975
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
1976
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Created" }),
|
|
1977
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: moment__default.default.utc(payment.created_at).local().format("MMM D, YYYY HH:mm") })
|
|
1978
|
+
] }),
|
|
1979
|
+
payment.confirmations_count !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
1980
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Confirmations" }),
|
|
1981
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: payment.confirmations_count })
|
|
1982
|
+
] })
|
|
1983
|
+
] })
|
|
1984
|
+
] }),
|
|
1985
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogFooter, { children: [
|
|
1986
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { variant: "outline", onClick: handleClose, children: "Close" }),
|
|
1987
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { onClick: () => mutate(), variant: "ghost", size: "sm", children: [
|
|
1988
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
1989
|
+
"Refresh"
|
|
1695
1990
|
] })
|
|
1696
1991
|
] })
|
|
1697
|
-
] });
|
|
1992
|
+
] }) });
|
|
1698
1993
|
};
|
|
1699
|
-
var
|
|
1700
|
-
const {
|
|
1994
|
+
var BalanceCard = () => {
|
|
1995
|
+
const {
|
|
1996
|
+
balance,
|
|
1997
|
+
isLoadingBalance,
|
|
1998
|
+
refreshBalance
|
|
1999
|
+
} = useOverviewContext();
|
|
1701
2000
|
const formatCurrency = (amount) => {
|
|
1702
2001
|
if (amount === null || amount === void 0) return "$0.00";
|
|
1703
|
-
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1704
2002
|
return new Intl.NumberFormat("en-US", {
|
|
1705
2003
|
style: "currency",
|
|
1706
2004
|
currency: "USD",
|
|
1707
2005
|
minimumFractionDigits: 2
|
|
1708
|
-
}).format(
|
|
1709
|
-
};
|
|
1710
|
-
const getRelativeTime = (date) => {
|
|
1711
|
-
if (!date) return "N/A";
|
|
1712
|
-
const now = /* @__PURE__ */ new Date();
|
|
1713
|
-
const target = new Date(date);
|
|
1714
|
-
const diffInSeconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
|
|
1715
|
-
if (diffInSeconds < 60) return "Just now";
|
|
1716
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
1717
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
1718
|
-
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2006
|
+
}).format(amount);
|
|
1719
2007
|
};
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
case "confirming":
|
|
1727
|
-
return "secondary";
|
|
1728
|
-
case "failed":
|
|
1729
|
-
case "error":
|
|
1730
|
-
case "expired":
|
|
1731
|
-
return "destructive";
|
|
1732
|
-
default:
|
|
1733
|
-
return "outline";
|
|
2008
|
+
const formatDate = (dateStr) => {
|
|
2009
|
+
if (!dateStr) return "No transactions yet";
|
|
2010
|
+
try {
|
|
2011
|
+
return moment__default.default.utc(dateStr).local().format("MMM D, YYYY");
|
|
2012
|
+
} catch {
|
|
2013
|
+
return "Invalid date";
|
|
1734
2014
|
}
|
|
1735
2015
|
};
|
|
1736
|
-
if (
|
|
2016
|
+
if (isLoadingBalance) {
|
|
1737
2017
|
return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
|
|
1738
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center
|
|
1739
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardContent, { className: "space-y-3", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-3 border rounded-sm", children: [
|
|
1743
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1744
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-4 w-32" }),
|
|
1745
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-3 w-24" })
|
|
2018
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
|
|
2019
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2020
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-5 w-5" }),
|
|
2021
|
+
"Account Balance"
|
|
1746
2022
|
] }),
|
|
1747
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-
|
|
1748
|
-
] }
|
|
2023
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-8 w-20" })
|
|
2024
|
+
] }) }),
|
|
2025
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "space-y-4", children: [
|
|
2026
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-10 w-32" }),
|
|
2027
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-4 w-48" })
|
|
2028
|
+
] })
|
|
1749
2029
|
] });
|
|
1750
2030
|
}
|
|
1751
|
-
const
|
|
2031
|
+
const balanceData = balance?.balance || balance;
|
|
2032
|
+
const amountUsd = balanceData?.amount_usd ?? 0;
|
|
2033
|
+
const totalDeposited = balanceData?.total_deposited ?? 0;
|
|
2034
|
+
const totalWithdrawn = balanceData?.total_withdrawn ?? 0;
|
|
2035
|
+
const lastTransactionAt = balanceData?.last_transaction_at;
|
|
2036
|
+
const isEmpty = amountUsd === 0 && totalDeposited === 0;
|
|
1752
2037
|
return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
|
|
1753
2038
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
|
|
1754
2039
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1755
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
1756
|
-
"
|
|
2040
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { className: "h-5 w-5" }),
|
|
2041
|
+
"Account Balance"
|
|
1757
2042
|
] }),
|
|
1758
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1759
|
-
"
|
|
1760
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1761
|
-
|
|
1762
|
-
|
|
2043
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2044
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { variant: "ghost", size: "sm", onClick: refreshBalance, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4" }) }),
|
|
2045
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { size: "sm", onClick: () => openCreatePaymentDialog(), children: [
|
|
2046
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2047
|
+
"Add Funds"
|
|
2048
|
+
] })
|
|
2049
|
+
] })
|
|
2050
|
+
] }) }),
|
|
2051
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "space-y-4", children: [
|
|
2052
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2053
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-4xl font-bold", children: formatCurrency(amountUsd) }),
|
|
2054
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mt-1", children: [
|
|
2055
|
+
"Available balance \u2022 Last updated ",
|
|
2056
|
+
formatDate(lastTransactionAt)
|
|
2057
|
+
] })
|
|
2058
|
+
] }),
|
|
2059
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4 pt-4 border-t", children: [
|
|
2060
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2061
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Total Deposited" }),
|
|
2062
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-semibold text-green-600", children: formatCurrency(totalDeposited) })
|
|
2063
|
+
] }),
|
|
2064
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2065
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Total Withdrawn" }),
|
|
2066
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-semibold text-red-600", children: formatCurrency(totalWithdrawn) })
|
|
2067
|
+
] })
|
|
2068
|
+
] }),
|
|
2069
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2070
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: !isEmpty ? "default" : "secondary", children: !isEmpty ? "Active" : "New Account" }),
|
|
2071
|
+
isEmpty && /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: "outline", children: "Empty Balance" })
|
|
2072
|
+
] })
|
|
2073
|
+
] })
|
|
2074
|
+
] });
|
|
2075
|
+
};
|
|
2076
|
+
var RecentPayments = () => {
|
|
2077
|
+
const { payments, isLoadingPayments } = useOverviewContext();
|
|
2078
|
+
const formatCurrency = (amount) => {
|
|
2079
|
+
if (amount === null || amount === void 0) return "$0.00";
|
|
2080
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
2081
|
+
return new Intl.NumberFormat("en-US", {
|
|
2082
|
+
style: "currency",
|
|
2083
|
+
currency: "USD",
|
|
2084
|
+
minimumFractionDigits: 2
|
|
2085
|
+
}).format(numAmount);
|
|
2086
|
+
};
|
|
2087
|
+
const getRelativeTime = (date) => {
|
|
2088
|
+
if (!date) return "N/A";
|
|
2089
|
+
const m = moment__default.default.utc(date).local();
|
|
2090
|
+
const now = moment__default.default();
|
|
2091
|
+
const diffInSeconds = now.diff(m, "seconds");
|
|
2092
|
+
if (diffInSeconds < 60) return "Just now";
|
|
2093
|
+
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2094
|
+
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2095
|
+
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2096
|
+
};
|
|
2097
|
+
const getStatusVariant = (status) => {
|
|
2098
|
+
switch (status?.toLowerCase()) {
|
|
2099
|
+
case "completed":
|
|
2100
|
+
case "success":
|
|
2101
|
+
return "default";
|
|
2102
|
+
case "pending":
|
|
2103
|
+
case "confirming":
|
|
2104
|
+
return "secondary";
|
|
2105
|
+
case "failed":
|
|
2106
|
+
case "error":
|
|
2107
|
+
case "expired":
|
|
2108
|
+
return "destructive";
|
|
2109
|
+
default:
|
|
2110
|
+
return "outline";
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
if (isLoadingPayments) {
|
|
2114
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
|
|
2115
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center gap-2", children: [
|
|
2116
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
|
|
2117
|
+
"Recent Payments"
|
|
2118
|
+
] }) }),
|
|
2119
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardContent, { className: "space-y-3", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-3 border rounded-sm", children: [
|
|
2120
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
2121
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-4 w-32" }),
|
|
2122
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-3 w-24" })
|
|
2123
|
+
] }),
|
|
2124
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-6 w-16" })
|
|
2125
|
+
] }, i)) })
|
|
2126
|
+
] });
|
|
2127
|
+
}
|
|
2128
|
+
const recentPaymentsList = payments?.results?.slice(0, 5) || [];
|
|
2129
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
|
|
2130
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
|
|
2131
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2132
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-5 w-5" }),
|
|
2133
|
+
"Recent Payments"
|
|
2134
|
+
] }),
|
|
2135
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { variant: "ghost", size: "sm", children: [
|
|
2136
|
+
"View All",
|
|
2137
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 ml-2" })
|
|
2138
|
+
] })
|
|
2139
|
+
] }) }),
|
|
1763
2140
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardContent, { children: recentPaymentsList.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
1764
2141
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-12 w-12 mx-auto mb-4 opacity-50" }),
|
|
1765
2142
|
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "No recent payments" }),
|
|
@@ -1817,14 +2194,18 @@ var PaymentsList = () => {
|
|
|
1817
2194
|
};
|
|
1818
2195
|
const getRelativeTime = (date) => {
|
|
1819
2196
|
if (!date) return "N/A";
|
|
1820
|
-
const
|
|
1821
|
-
const
|
|
1822
|
-
const diffInSeconds =
|
|
2197
|
+
const m = moment__default.default.utc(date).local();
|
|
2198
|
+
const now = moment__default.default();
|
|
2199
|
+
const diffInSeconds = now.diff(m, "seconds");
|
|
1823
2200
|
if (diffInSeconds < 60) return "Just now";
|
|
1824
2201
|
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
1825
2202
|
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
1826
2203
|
return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
1827
2204
|
};
|
|
2205
|
+
const formatDate = (date) => {
|
|
2206
|
+
if (!date) return "N/A";
|
|
2207
|
+
return moment__default.default.utc(date).local().format("MMM D, YYYY");
|
|
2208
|
+
};
|
|
1828
2209
|
const getStatusVariant = (status) => {
|
|
1829
2210
|
switch (status?.toLowerCase()) {
|
|
1830
2211
|
case "completed":
|
|
@@ -1847,11 +2228,21 @@ var PaymentsList = () => {
|
|
|
1847
2228
|
const handleStatusFilter = (status) => {
|
|
1848
2229
|
setStatusFilter(status);
|
|
1849
2230
|
};
|
|
2231
|
+
const truncateId = (id) => {
|
|
2232
|
+
if (!id) return "N/A";
|
|
2233
|
+
const str = id.toString();
|
|
2234
|
+
return str.length > 8 ? `${str.slice(0, 8)}...` : str;
|
|
2235
|
+
};
|
|
1850
2236
|
const filteredPayments = paymentsList.filter((payment) => {
|
|
1851
2237
|
const matchesSearch = searchTerm ? payment.id?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.status?.toLowerCase().includes(searchTerm.toLowerCase()) || payment.currency_code?.toLowerCase().includes(searchTerm.toLowerCase()) : true;
|
|
1852
2238
|
const matchesStatus = statusFilter !== "all" ? payment.status?.toLowerCase() === statusFilter.toLowerCase() : true;
|
|
1853
2239
|
return matchesSearch && matchesStatus;
|
|
1854
|
-
})
|
|
2240
|
+
}).map((payment) => ({
|
|
2241
|
+
...payment,
|
|
2242
|
+
formattedDate: formatDate(payment.created_at),
|
|
2243
|
+
relativeTime: getRelativeTime(payment.created_at),
|
|
2244
|
+
truncatedId: truncateId(payment.id)
|
|
2245
|
+
}));
|
|
1855
2246
|
return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
|
|
1856
2247
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center justify-between", children: [
|
|
1857
2248
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment History" }),
|
|
@@ -1927,14 +2318,14 @@ var PaymentsList = () => {
|
|
|
1927
2318
|
onClick: () => openPaymentDetailsDialog(String(payment.id)),
|
|
1928
2319
|
children: [
|
|
1929
2320
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1930
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: payment.
|
|
1931
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children:
|
|
2321
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: payment.formattedDate }),
|
|
2322
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: payment.relativeTime })
|
|
1932
2323
|
] }) }),
|
|
1933
2324
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono font-semibold", children: formatCurrency(payment.amount_usd) }),
|
|
1934
2325
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: "outline", children: payment.currency_code || "USD" }) }),
|
|
1935
2326
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: getStatusVariant(payment.status), children: payment.status }) }),
|
|
1936
2327
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "text-sm text-muted-foreground", children: "NowPayments" }),
|
|
1937
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono text-sm text-muted-foreground", children: payment.
|
|
2328
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono text-sm text-muted-foreground", children: payment.truncatedId }),
|
|
1938
2329
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1939
2330
|
uiNextjs.Button,
|
|
1940
2331
|
{
|
|
@@ -1987,22 +2378,16 @@ var TransactionsList = () => {
|
|
|
1987
2378
|
const formatDate = (date) => {
|
|
1988
2379
|
if (!date) return "N/A";
|
|
1989
2380
|
try {
|
|
1990
|
-
return
|
|
1991
|
-
year: "numeric",
|
|
1992
|
-
month: "short",
|
|
1993
|
-
day: "numeric",
|
|
1994
|
-
hour: "2-digit",
|
|
1995
|
-
minute: "2-digit"
|
|
1996
|
-
});
|
|
2381
|
+
return moment__default.default.utc(date).local().format("MMM D, YYYY hh:mm A");
|
|
1997
2382
|
} catch {
|
|
1998
2383
|
return "Invalid date";
|
|
1999
2384
|
}
|
|
2000
2385
|
};
|
|
2001
2386
|
const getRelativeTime = (date) => {
|
|
2002
2387
|
if (!date) return "N/A";
|
|
2003
|
-
const
|
|
2004
|
-
const
|
|
2005
|
-
const diffInSeconds =
|
|
2388
|
+
const m = moment__default.default.utc(date).local();
|
|
2389
|
+
const now = moment__default.default();
|
|
2390
|
+
const diffInSeconds = now.diff(m, "seconds");
|
|
2006
2391
|
if (diffInSeconds < 60) return "Just now";
|
|
2007
2392
|
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2008
2393
|
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
@@ -2032,11 +2417,22 @@ var TransactionsList = () => {
|
|
|
2032
2417
|
setTypeFilter(type);
|
|
2033
2418
|
await refreshTransactions();
|
|
2034
2419
|
};
|
|
2420
|
+
const truncateId = (id) => {
|
|
2421
|
+
if (!id) return "N/A";
|
|
2422
|
+
const str = id.toString();
|
|
2423
|
+
return str.length > 8 ? `${str.slice(0, 8)}...` : str;
|
|
2424
|
+
};
|
|
2035
2425
|
const filteredTransactions = transactionsList.filter((transaction) => {
|
|
2036
2426
|
const matchesSearch = searchTerm ? transaction.id?.toString().toLowerCase().includes(searchTerm.toLowerCase()) || transaction.description?.toLowerCase().includes(searchTerm.toLowerCase()) || transaction.type?.toLowerCase().includes(searchTerm.toLowerCase()) : true;
|
|
2037
2427
|
const matchesType = typeFilter !== "all" ? transaction.type?.toLowerCase() === typeFilter.toLowerCase() : true;
|
|
2038
2428
|
return matchesSearch && matchesType;
|
|
2039
|
-
})
|
|
2429
|
+
}).map((transaction) => ({
|
|
2430
|
+
...transaction,
|
|
2431
|
+
isDeposit: transaction.type?.toLowerCase() === "deposit" || transaction.type?.toLowerCase() === "credit",
|
|
2432
|
+
formattedDate: formatDate(transaction.created_at || transaction.timestamp),
|
|
2433
|
+
relativeTime: getRelativeTime(transaction.created_at || transaction.timestamp),
|
|
2434
|
+
truncatedRef: truncateId(transaction.reference || transaction.payment_id)
|
|
2435
|
+
}));
|
|
2040
2436
|
if (isLoadingTransactions) {
|
|
2041
2437
|
return /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Card, { children: [
|
|
2042
2438
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardTitle, { className: "flex items-center gap-2", children: [
|
|
@@ -2102,26 +2498,23 @@ var TransactionsList = () => {
|
|
|
2102
2498
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Description" }),
|
|
2103
2499
|
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableHead, { children: "Reference" })
|
|
2104
2500
|
] }) }),
|
|
2105
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableBody, { children: filteredTransactions.map((transaction, index) => {
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono text-sm text-muted-foreground", children: transaction.reference || transaction.payment_id ? `${(transaction.reference || transaction.payment_id).toString().slice(0, 8)}...` : "N/A" })
|
|
2123
|
-
] }, transaction.id || index);
|
|
2124
|
-
}) })
|
|
2501
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableBody, { children: filteredTransactions.map((transaction, index) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.TableRow, { children: [
|
|
2502
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2503
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: transaction.formattedDate }),
|
|
2504
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: transaction.relativeTime })
|
|
2505
|
+
] }) }),
|
|
2506
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2507
|
+
getTypeIcon(transaction.type),
|
|
2508
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: getTypeVariant(transaction.type), children: transaction.type || "Unknown" })
|
|
2509
|
+
] }) }),
|
|
2510
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono font-semibold", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: transaction.isDeposit ? "text-green-600" : "text-red-600", children: [
|
|
2511
|
+
transaction.isDeposit ? "+" : "-",
|
|
2512
|
+
formatCurrency(Math.abs(transaction.amount || transaction.amount_usd || 0))
|
|
2513
|
+
] }) }),
|
|
2514
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono", children: formatCurrency(transaction.balance_after || 0) }),
|
|
2515
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "text-sm", children: transaction.description || transaction.note || "No description" }),
|
|
2516
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TableCell, { className: "font-mono text-sm text-muted-foreground", children: transaction.truncatedRef })
|
|
2517
|
+
] }, transaction.id || index)) })
|
|
2125
2518
|
] }) })
|
|
2126
2519
|
] })
|
|
2127
2520
|
] });
|
|
@@ -2129,384 +2522,6 @@ var TransactionsList = () => {
|
|
|
2129
2522
|
var TransactionsView = () => {
|
|
2130
2523
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntime.jsx(TransactionsList, {}) });
|
|
2131
2524
|
};
|
|
2132
|
-
var isDevelopment = process.env.NODE_ENV === "development";
|
|
2133
|
-
var logger = consola.createConsola({
|
|
2134
|
-
level: isDevelopment ? 4 : 1
|
|
2135
|
-
}).withTag("ext-payments");
|
|
2136
|
-
var paymentsLogger = logger;
|
|
2137
|
-
var PaymentCreateSchema = zod.z.object({
|
|
2138
|
-
amount_usd: zod.z.number().min(0.01, "Amount must be at least $0.01"),
|
|
2139
|
-
currency_code: zod.z.string().min(1, "Please select a currency")
|
|
2140
|
-
});
|
|
2141
|
-
var CreatePaymentDialog = () => {
|
|
2142
|
-
const [open, setOpen] = react.useState(false);
|
|
2143
|
-
const [isSubmitting, setIsSubmitting] = react.useState(false);
|
|
2144
|
-
const { createPayment } = usePaymentsContext();
|
|
2145
|
-
const { currencies, isLoadingCurrencies } = useRootPaymentsContext();
|
|
2146
|
-
const form = reactHookForm.useForm({
|
|
2147
|
-
resolver: zod$1.zodResolver(PaymentCreateSchema),
|
|
2148
|
-
defaultValues: {
|
|
2149
|
-
amount_usd: 10,
|
|
2150
|
-
currency_code: "USDT"
|
|
2151
|
-
}
|
|
2152
|
-
});
|
|
2153
|
-
const currenciesList = react.useMemo(() => {
|
|
2154
|
-
const data = currencies?.currencies || currencies?.results || currencies || [];
|
|
2155
|
-
return Array.isArray(data) ? data : [];
|
|
2156
|
-
}, [currencies]);
|
|
2157
|
-
const currencyOptions = react.useMemo(() => {
|
|
2158
|
-
return currenciesList.filter((curr) => curr.is_enabled !== false).map((curr) => ({
|
|
2159
|
-
code: curr.code || curr.currency_code || curr.symbol,
|
|
2160
|
-
name: curr.name || curr.code || curr.currency_code,
|
|
2161
|
-
usd_rate: curr.usd_rate || curr.rate || 1,
|
|
2162
|
-
network: curr.network || null
|
|
2163
|
-
}));
|
|
2164
|
-
}, [currenciesList]);
|
|
2165
|
-
const calculateCryptoAmount = react.useMemo(() => {
|
|
2166
|
-
const amountUsd = form.watch("amount_usd");
|
|
2167
|
-
const currencyCode = form.watch("currency_code");
|
|
2168
|
-
const currency = currencyOptions.find((c) => c.code === currencyCode);
|
|
2169
|
-
if (!currency || !currency.usd_rate || !amountUsd) {
|
|
2170
|
-
return null;
|
|
2171
|
-
}
|
|
2172
|
-
const cryptoAmount = amountUsd / currency.usd_rate;
|
|
2173
|
-
return {
|
|
2174
|
-
amount: cryptoAmount,
|
|
2175
|
-
currency: currency.code,
|
|
2176
|
-
rate: currency.usd_rate,
|
|
2177
|
-
network: currency.network
|
|
2178
|
-
};
|
|
2179
|
-
}, [form.watch("amount_usd"), form.watch("currency_code"), currencyOptions]);
|
|
2180
|
-
react.useEffect(() => {
|
|
2181
|
-
const handleOpen = () => setOpen(true);
|
|
2182
|
-
const handleClose2 = () => setOpen(false);
|
|
2183
|
-
window.addEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
|
|
2184
|
-
window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
2185
|
-
return () => {
|
|
2186
|
-
window.removeEventListener(PAYMENT_EVENTS.OPEN_CREATE_PAYMENT_DIALOG, handleOpen);
|
|
2187
|
-
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
2188
|
-
};
|
|
2189
|
-
}, []);
|
|
2190
|
-
const handleClose = () => {
|
|
2191
|
-
setOpen(false);
|
|
2192
|
-
form.reset();
|
|
2193
|
-
};
|
|
2194
|
-
react.useEffect(() => {
|
|
2195
|
-
if (currencyOptions.length > 0 && !form.getValues("currency_code")) {
|
|
2196
|
-
form.setValue("currency_code", currencyOptions[0].code);
|
|
2197
|
-
}
|
|
2198
|
-
}, [currencyOptions, form]);
|
|
2199
|
-
const handleSubmit = async (data) => {
|
|
2200
|
-
try {
|
|
2201
|
-
setIsSubmitting(true);
|
|
2202
|
-
const result = await createPayment();
|
|
2203
|
-
handleClose();
|
|
2204
|
-
closePaymentsDialog();
|
|
2205
|
-
const paymentData = result;
|
|
2206
|
-
const paymentId = paymentData?.payment?.id || paymentData?.id;
|
|
2207
|
-
if (paymentId) {
|
|
2208
|
-
openPaymentDetailsDialog(String(paymentId));
|
|
2209
|
-
}
|
|
2210
|
-
} catch (error) {
|
|
2211
|
-
paymentsLogger.error("Failed to create payment:", error);
|
|
2212
|
-
} finally {
|
|
2213
|
-
setIsSubmitting(false);
|
|
2214
|
-
}
|
|
2215
|
-
};
|
|
2216
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-md", children: [
|
|
2217
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
2218
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Create Payment" }),
|
|
2219
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Create a new payment to add funds to your account." })
|
|
2220
|
-
] }),
|
|
2221
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(handleSubmit), className: "space-y-4", children: [
|
|
2222
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2223
|
-
uiNextjs.FormField,
|
|
2224
|
-
{
|
|
2225
|
-
control: form.control,
|
|
2226
|
-
name: "amount_usd",
|
|
2227
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
|
|
2228
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Amount (USD)" }),
|
|
2229
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2230
|
-
uiNextjs.Input,
|
|
2231
|
-
{
|
|
2232
|
-
type: "number",
|
|
2233
|
-
step: "0.01",
|
|
2234
|
-
min: "0.01",
|
|
2235
|
-
placeholder: "10.00",
|
|
2236
|
-
...field,
|
|
2237
|
-
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
2238
|
-
}
|
|
2239
|
-
) }),
|
|
2240
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormDescription, { children: "The amount you want to pay in USD." }),
|
|
2241
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
|
|
2242
|
-
] })
|
|
2243
|
-
}
|
|
2244
|
-
),
|
|
2245
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2246
|
-
uiNextjs.FormField,
|
|
2247
|
-
{
|
|
2248
|
-
control: form.control,
|
|
2249
|
-
name: "currency_code",
|
|
2250
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
|
|
2251
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Currency" }),
|
|
2252
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2253
|
-
uiNextjs.Select,
|
|
2254
|
-
{
|
|
2255
|
-
onValueChange: field.onChange,
|
|
2256
|
-
defaultValue: field.value,
|
|
2257
|
-
disabled: isLoadingCurrencies,
|
|
2258
|
-
children: [
|
|
2259
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectValue, { placeholder: "Select currency..." }) }) }),
|
|
2260
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectContent, { children: currencyOptions.map((curr) => /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.SelectItem, { value: curr.code, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2261
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: curr.code, size: 16 }),
|
|
2262
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: curr.code }),
|
|
2263
|
-
curr.network && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
2264
|
-
"(",
|
|
2265
|
-
curr.network,
|
|
2266
|
-
")"
|
|
2267
|
-
] })
|
|
2268
|
-
] }) }, curr.code)) })
|
|
2269
|
-
]
|
|
2270
|
-
}
|
|
2271
|
-
),
|
|
2272
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormDescription, { children: "The cryptocurrency to use for payment." }),
|
|
2273
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
|
|
2274
|
-
] })
|
|
2275
|
-
}
|
|
2276
|
-
),
|
|
2277
|
-
calculateCryptoAmount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm bg-muted p-4 space-y-3", children: [
|
|
2278
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2279
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "You will send" }),
|
|
2280
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2281
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: calculateCryptoAmount.currency, size: 16 }),
|
|
2282
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-semibold", children: [
|
|
2283
|
-
calculateCryptoAmount.amount.toFixed(8),
|
|
2284
|
-
" ",
|
|
2285
|
-
calculateCryptoAmount.currency
|
|
2286
|
-
] })
|
|
2287
|
-
] })
|
|
2288
|
-
] }),
|
|
2289
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2290
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "You will receive" }),
|
|
2291
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-lg font-bold", children: [
|
|
2292
|
-
"$",
|
|
2293
|
-
form.watch("amount_usd")?.toFixed(2),
|
|
2294
|
-
" USD"
|
|
2295
|
-
] })
|
|
2296
|
-
] }),
|
|
2297
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
2298
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Rate" }),
|
|
2299
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
2300
|
-
"1 ",
|
|
2301
|
-
calculateCryptoAmount.currency,
|
|
2302
|
-
" = $",
|
|
2303
|
-
calculateCryptoAmount.rate?.toFixed(2)
|
|
2304
|
-
] })
|
|
2305
|
-
] }),
|
|
2306
|
-
calculateCryptoAmount.network && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2307
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
|
|
2308
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: calculateCryptoAmount.network })
|
|
2309
|
-
] }) })
|
|
2310
|
-
] }),
|
|
2311
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogFooter, { children: [
|
|
2312
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { type: "button", variant: "outline", onClick: handleClose, disabled: isSubmitting, children: "Cancel" }),
|
|
2313
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { type: "submit", disabled: isSubmitting || currencyOptions.length === 0, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2314
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
2315
|
-
"Creating..."
|
|
2316
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2317
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2318
|
-
"Create Payment"
|
|
2319
|
-
] }) })
|
|
2320
|
-
] })
|
|
2321
|
-
] }) })
|
|
2322
|
-
] }) });
|
|
2323
|
-
};
|
|
2324
|
-
var PaymentDetailsDialog = () => {
|
|
2325
|
-
const [open, setOpen] = react.useState(false);
|
|
2326
|
-
const [paymentId, setPaymentId] = react.useState(null);
|
|
2327
|
-
const [timeLeft, setTimeLeft] = react.useState("");
|
|
2328
|
-
const shouldFetch = open && !!paymentId;
|
|
2329
|
-
const { data: payment, isLoading, error, mutate } = usePaymentsPaymentsRetrieve(
|
|
2330
|
-
shouldFetch ? paymentId : "",
|
|
2331
|
-
apiPayments
|
|
2332
|
-
);
|
|
2333
|
-
react.useEffect(() => {
|
|
2334
|
-
const handleOpen = (event) => {
|
|
2335
|
-
const customEvent = event;
|
|
2336
|
-
setPaymentId(customEvent.detail.id);
|
|
2337
|
-
setOpen(true);
|
|
2338
|
-
};
|
|
2339
|
-
const handleClose2 = () => {
|
|
2340
|
-
setOpen(false);
|
|
2341
|
-
setPaymentId(null);
|
|
2342
|
-
};
|
|
2343
|
-
window.addEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
2344
|
-
window.addEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
2345
|
-
return () => {
|
|
2346
|
-
window.removeEventListener(PAYMENT_EVENTS.OPEN_PAYMENT_DETAILS_DIALOG, handleOpen);
|
|
2347
|
-
window.removeEventListener(PAYMENT_EVENTS.CLOSE_DIALOG, handleClose2);
|
|
2348
|
-
};
|
|
2349
|
-
}, []);
|
|
2350
|
-
const handleClose = () => {
|
|
2351
|
-
setOpen(false);
|
|
2352
|
-
setPaymentId(null);
|
|
2353
|
-
};
|
|
2354
|
-
react.useEffect(() => {
|
|
2355
|
-
if (!payment?.expires_at) return;
|
|
2356
|
-
const updateTimeLeft = () => {
|
|
2357
|
-
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
2358
|
-
const expires = new Date(payment.expires_at).getTime();
|
|
2359
|
-
const diff = expires - now;
|
|
2360
|
-
if (diff <= 0) {
|
|
2361
|
-
setTimeLeft("Expired");
|
|
2362
|
-
return;
|
|
2363
|
-
}
|
|
2364
|
-
const hours = Math.floor(diff / (1e3 * 60 * 60));
|
|
2365
|
-
const minutes = Math.floor(diff % (1e3 * 60 * 60) / (1e3 * 60));
|
|
2366
|
-
const seconds = Math.floor(diff % (1e3 * 60) / 1e3);
|
|
2367
|
-
setTimeLeft(`${hours}h ${minutes}m ${seconds}s`);
|
|
2368
|
-
};
|
|
2369
|
-
updateTimeLeft();
|
|
2370
|
-
const interval = setInterval(updateTimeLeft, 1e3);
|
|
2371
|
-
return () => clearInterval(interval);
|
|
2372
|
-
}, [payment?.expires_at]);
|
|
2373
|
-
const getStatusInfo = () => {
|
|
2374
|
-
switch (payment?.status?.toLowerCase()) {
|
|
2375
|
-
case "pending":
|
|
2376
|
-
return { icon: lucideReact.Clock, color: "text-yellow-500", bg: "bg-yellow-500/10" };
|
|
2377
|
-
case "completed":
|
|
2378
|
-
case "success":
|
|
2379
|
-
return { icon: lucideReact.CheckCircle2, color: "text-green-500", bg: "bg-green-500/10" };
|
|
2380
|
-
case "failed":
|
|
2381
|
-
case "error":
|
|
2382
|
-
return { icon: lucideReact.XCircle, color: "text-red-500", bg: "bg-red-500/10" };
|
|
2383
|
-
case "expired":
|
|
2384
|
-
return { icon: lucideReact.AlertCircle, color: "text-gray-500", bg: "bg-gray-500/10" };
|
|
2385
|
-
case "confirming":
|
|
2386
|
-
return { icon: lucideReact.RefreshCw, color: "text-blue-500", bg: "bg-blue-500/10" };
|
|
2387
|
-
default:
|
|
2388
|
-
return { icon: lucideReact.Clock, color: "text-gray-500", bg: "bg-gray-500/10" };
|
|
2389
|
-
}
|
|
2390
|
-
};
|
|
2391
|
-
if (!open) return null;
|
|
2392
|
-
if (isLoading) {
|
|
2393
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
|
|
2394
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
2395
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
|
|
2396
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Loading payment information..." })
|
|
2397
|
-
] }),
|
|
2398
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-8 w-8 animate-spin text-muted-foreground" }) })
|
|
2399
|
-
] }) });
|
|
2400
|
-
}
|
|
2401
|
-
if (shouldFetch && !isLoading && (error || !payment)) {
|
|
2402
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
|
|
2403
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
2404
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
|
|
2405
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Failed to load payment information" })
|
|
2406
|
-
] }),
|
|
2407
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
|
|
2408
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-12 w-12 text-destructive" }),
|
|
2409
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: error ? `Error: ${error}` : "Payment not found" }),
|
|
2410
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { onClick: () => mutate(), children: "Try Again" })
|
|
2411
|
-
] })
|
|
2412
|
-
] }) });
|
|
2413
|
-
}
|
|
2414
|
-
const statusInfo = getStatusInfo();
|
|
2415
|
-
const StatusIcon = statusInfo.icon;
|
|
2416
|
-
const qrCodeUrl = payment.pay_address ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
2417
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-lg", children: [
|
|
2418
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
2419
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogTitle, { children: "Payment Details" }),
|
|
2420
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Send cryptocurrency to complete your payment" })
|
|
2421
|
-
] }),
|
|
2422
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
2423
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-3 p-4 rounded-sm ${statusInfo.bg}`, children: [
|
|
2424
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { className: `h-5 w-5 ${statusInfo.color}` }),
|
|
2425
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
2426
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold capitalize", children: payment.status }),
|
|
2427
|
-
payment.status === "pending" && timeLeft && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
2428
|
-
"Expires in ",
|
|
2429
|
-
timeLeft
|
|
2430
|
-
] })
|
|
2431
|
-
] })
|
|
2432
|
-
] }),
|
|
2433
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
2434
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 bg-muted rounded-sm", children: [
|
|
2435
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Amount to send" }),
|
|
2436
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2437
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.TokenIcon, { symbol: String(payment.currency_code || "BTC"), size: 20 }),
|
|
2438
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono font-bold text-lg", children: [
|
|
2439
|
-
payment.pay_amount || "0.00000000",
|
|
2440
|
-
" ",
|
|
2441
|
-
payment.currency_code
|
|
2442
|
-
] })
|
|
2443
|
-
] })
|
|
2444
|
-
] }),
|
|
2445
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
2446
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Equivalent to" }),
|
|
2447
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-lg", children: [
|
|
2448
|
-
"$",
|
|
2449
|
-
parseFloat(payment.amount_usd || "0").toFixed(2),
|
|
2450
|
-
" USD"
|
|
2451
|
-
] })
|
|
2452
|
-
] }),
|
|
2453
|
-
payment.internal_payment_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
2454
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Payment Order #" }),
|
|
2455
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", children: payment.internal_payment_id })
|
|
2456
|
-
] }),
|
|
2457
|
-
payment.currency_network && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4", children: [
|
|
2458
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Network" }),
|
|
2459
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: payment.currency_network })
|
|
2460
|
-
] })
|
|
2461
|
-
] }),
|
|
2462
|
-
qrCodeUrl && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-6 bg-white rounded-sm", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: qrCodeUrl, alt: "Payment QR Code", className: "w-48 h-48" }) }),
|
|
2463
|
-
payment.pay_address && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
2464
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
|
|
2465
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2466
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.pay_address }),
|
|
2467
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CopyButton, { value: payment.pay_address, variant: "outline" })
|
|
2468
|
-
] })
|
|
2469
|
-
] }),
|
|
2470
|
-
payment.transaction_hash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
2471
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
2472
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 bg-muted rounded-sm font-mono text-sm break-all", children: payment.transaction_hash })
|
|
2473
|
-
] }),
|
|
2474
|
-
payment.payment_url && payment.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2475
|
-
uiNextjs.Button,
|
|
2476
|
-
{
|
|
2477
|
-
variant: "outline",
|
|
2478
|
-
className: "w-full",
|
|
2479
|
-
onClick: () => window.open(payment.payment_url, "_blank"),
|
|
2480
|
-
children: [
|
|
2481
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
2482
|
-
"Open in Payment Provider"
|
|
2483
|
-
]
|
|
2484
|
-
}
|
|
2485
|
-
),
|
|
2486
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t space-y-2 text-xs text-muted-foreground", children: [
|
|
2487
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
2488
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Payment ID" }),
|
|
2489
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: payment.id })
|
|
2490
|
-
] }),
|
|
2491
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
2492
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Created" }),
|
|
2493
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: new Date(payment.created_at).toLocaleString() })
|
|
2494
|
-
] }),
|
|
2495
|
-
payment.confirmations_count !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
2496
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Confirmations" }),
|
|
2497
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: payment.confirmations_count })
|
|
2498
|
-
] })
|
|
2499
|
-
] })
|
|
2500
|
-
] }),
|
|
2501
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogFooter, { children: [
|
|
2502
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { variant: "outline", onClick: handleClose, children: "Close" }),
|
|
2503
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { onClick: () => mutate(), variant: "ghost", size: "sm", children: [
|
|
2504
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
2505
|
-
"Refresh"
|
|
2506
|
-
] })
|
|
2507
|
-
] })
|
|
2508
|
-
] }) });
|
|
2509
|
-
};
|
|
2510
2525
|
var PaymentsLayout = () => {
|
|
2511
2526
|
return /* @__PURE__ */ jsxRuntime.jsx(RootPaymentsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full p-6 space-y-6", children: [
|
|
2512
2527
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
@@ -2545,7 +2560,7 @@ var PaymentsLayout = () => {
|
|
|
2545
2560
|
// package.json
|
|
2546
2561
|
var package_default = {
|
|
2547
2562
|
name: "@djangocfg/ext-payments",
|
|
2548
|
-
version: "1.0.
|
|
2563
|
+
version: "1.0.8",
|
|
2549
2564
|
description: "Payments system extension for DjangoCFG",
|
|
2550
2565
|
keywords: [
|
|
2551
2566
|
"django",
|
|
@@ -2613,7 +2628,8 @@ var package_default = {
|
|
|
2613
2628
|
"p-retry": "^7.0.0",
|
|
2614
2629
|
react: "^18 || ^19",
|
|
2615
2630
|
swr: "^2.3.7",
|
|
2616
|
-
zod: "^4.1.13"
|
|
2631
|
+
zod: "^4.1.13",
|
|
2632
|
+
moment: "^2.30.1"
|
|
2617
2633
|
},
|
|
2618
2634
|
devDependencies: {
|
|
2619
2635
|
"@djangocfg/api": "workspace:*",
|