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