Skip to content

Commit e94542d

Browse files
committed
feat: realign to new payment widget, use the deployed registry
1 parent 5ebfc21 commit e94542d

File tree

18 files changed

+392
-377
lines changed

18 files changed

+392
-377
lines changed

components.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
"magicui": "@/components/magicui"
1818
},
1919
"registries": {
20-
"@requestnetwork": "https://ui.stage.request.network/r/{name}.json"
20+
"@requestnetwork": "https://ui.stage.request.network//r/{name}.json"
2121
}
2222
}

src/components/Playground/blocks/customize.tsx

Lines changed: 59 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,9 @@ import { Label } from "../../ui/label";
88
import { SectionHeader } from "../../ui/section-header";
99
import { useFormContext } from "react-hook-form";
1010
import { PlaygroundFormData } from "@/lib/validation";
11-
import {
12-
Select,
13-
SelectContent,
14-
SelectItem,
15-
SelectTrigger,
16-
SelectValue,
17-
} from "../../ui/select";
1811
import { Switch } from "../../ui/switch";
1912
import { useEffect } from "react";
13+
import { CurrencyCombobox } from "../../ui/combobox";
2014

2115
export const CustomizeForm = () => {
2216
const {
@@ -34,8 +28,8 @@ export const CustomizeForm = () => {
3428
id: (currentItems.length + 1).toString(),
3529
description: "",
3630
quantity: 1,
37-
unitPrice: 0,
38-
total: 0,
31+
unitPrice: "0",
32+
total: "0",
3933
currency: "USD",
4034
};
4135
setValue("receiptInfo.items", [...currentItems, newItem]);
@@ -51,29 +45,43 @@ export const CustomizeForm = () => {
5145
const updateItemTotal = (index: number) => {
5246
const items = formValues.receiptInfo.items;
5347
const item = items[index];
54-
const total = item.quantity * item.unitPrice;
55-
setValue(`receiptInfo.items.${index}.total`, total);
48+
const quantity = typeof item.quantity === 'string' ? parseFloat(item.quantity) || 0 : item.quantity;
49+
const unitPrice = typeof item.unitPrice === 'string' ? parseFloat(item.unitPrice) || 0 : item.unitPrice;
50+
const total = quantity * unitPrice;
51+
setValue(`receiptInfo.items.${index}.total`, total.toString());
5652
};
5753

5854
// Auto-calculate totals when items change
5955
useEffect(() => {
6056
const items = formValues.receiptInfo.items;
61-
const subtotal = items.reduce(
62-
(sum, item) => sum + (item.total || 0),
63-
0
64-
);
65-
const totalDiscount = items.reduce(
66-
(sum, item) => sum + (item.discount || 0),
67-
0
68-
);
69-
const totalTax = items.reduce((sum, item) => sum + (item.tax || 0), 0);
57+
const subtotal = items.reduce((sum, item) => {
58+
const total = typeof item.total === 'string' ? parseFloat(item.total) || 0 : item.total;
59+
return sum + total;
60+
}, 0);
61+
62+
const totalDiscount = items.reduce((sum, item) => {
63+
if (item.discount) {
64+
const discount = typeof item.discount === 'string' ? parseFloat(item.discount) || 0 : item.discount;
65+
return sum + discount;
66+
}
67+
return sum;
68+
}, 0);
69+
70+
const totalTax = items.reduce((sum, item) => {
71+
if (item.tax) {
72+
const tax = typeof item.tax === 'string' ? parseFloat(item.tax) || 0 : item.tax;
73+
return sum + tax;
74+
}
75+
return sum;
76+
}, 0);
77+
7078
const total = subtotal - totalDiscount + totalTax;
7179

7280
setValue("receiptInfo.totals", {
73-
totalDiscount,
74-
totalTax,
75-
total,
76-
totalUSD: total,
81+
totalDiscount: totalDiscount.toString(),
82+
totalTax: totalTax.toString(),
83+
total: total.toString(),
84+
totalUSD: total.toString(),
7785
});
7886

7987
// Update the payment amount
@@ -84,7 +92,7 @@ export const CustomizeForm = () => {
8492
<section className="flex flex-col gap-4">
8593
<SectionHeader title="Payment Configuration" />
8694

87-
<div className="flex flex-col gap-2">
95+
<div className="flex flex-col gap-2">
8896
<Label className="flex items-center">
8997
Recipient Wallet Address
9098
<span className="text-red-500 ml-1">*</span>
@@ -102,29 +110,6 @@ export const CustomizeForm = () => {
102110
)}
103111
</div>
104112

105-
<div className="flex flex-col gap-2">
106-
<Label className="flex items-center">
107-
Network
108-
<span className="text-red-500 ml-1">*</span>
109-
</Label>
110-
<Select
111-
value={formValues.paymentConfig.network}
112-
onValueChange={(value) => setValue("paymentConfig.network", value as any)}
113-
>
114-
<SelectTrigger>
115-
<SelectValue placeholder="Select network" />
116-
</SelectTrigger>
117-
<SelectContent>
118-
<SelectItem value="mainnet">Ethereum Mainnet</SelectItem>
119-
<SelectItem value="polygon">Polygon</SelectItem>
120-
<SelectItem value="arbitrum">Arbitrum</SelectItem>
121-
<SelectItem value="base">Base</SelectItem>
122-
<SelectItem value="optimism">Optimism</SelectItem>
123-
<SelectItem value="sepolia">Sepolia (Testnet)</SelectItem>
124-
</SelectContent>
125-
</Select>
126-
</div>
127-
128113
<div className="flex flex-col gap-2">
129114
<Label className="flex items-center">
130115
Request Network API Client ID
@@ -151,6 +136,24 @@ export const CustomizeForm = () => {
151136
/>
152137
</div>
153138

139+
<div className="flex flex-col gap-2">
140+
<Label className="flex items-center">
141+
Supported Currencies
142+
<span className="text-red-500 ml-1">*</span>
143+
</Label>
144+
<CurrencyCombobox
145+
register={register}
146+
name="paymentConfig.supportedCurrencies"
147+
className={cn(
148+
"border-2",
149+
errors.paymentConfig?.supportedCurrencies ? "border-red-500" : "border-gray-200"
150+
)}
151+
/>
152+
{errors.paymentConfig?.supportedCurrencies?.message && (
153+
<Error>{errors.paymentConfig.supportedCurrencies.message}</Error>
154+
)}
155+
</div>
156+
154157
<div className="flex flex-col gap-2">
155158
<Label>Fee Address</Label>
156159
<Input
@@ -208,7 +211,6 @@ export const CustomizeForm = () => {
208211
step="0.01"
209212
placeholder="0.00"
210213
{...register(`receiptInfo.items.${index}.unitPrice`, {
211-
valueAsNumber: true,
212214
onChange: () => updateItemTotal(index),
213215
})}
214216
/>
@@ -219,7 +221,7 @@ export const CustomizeForm = () => {
219221
type="number"
220222
step="0.01"
221223
readOnly
222-
value={item.total || 0}
224+
value={typeof item.total === 'string' ? parseFloat(item.total) || 0 : item.total}
223225
className="bg-gray-50"
224226
/>
225227
</div>
@@ -243,7 +245,7 @@ export const CustomizeForm = () => {
243245
</div>
244246

245247
<div className="flex items-center justify-between">
246-
<Label>Show Invoice Download</Label>
248+
<Label>Show Receipt Download</Label>
247249
<Switch
248250
checked={formValues.uiConfig?.showReceiptDownload || false}
249251
onCheckedChange={(checked) => setValue("uiConfig.showReceiptDownload", checked)}
@@ -253,28 +255,29 @@ export const CustomizeForm = () => {
253255
<div className="flex flex-col gap-2">
254256
<Label>Receipt Number</Label>
255257
<Input
256-
placeholder="INV-001"
258+
placeholder="REC-001"
257259
{...register("receiptInfo.invoiceNumber")}
258260
/>
259261
</div>
260262

263+
{/* Totals Display */}
261264
<div className="border-t pt-4">
262265
<div className="space-y-2">
263266
<div className="flex justify-between">
264267
<span>Subtotal:</span>
265-
<span>${formValues.receiptInfo.totals.total.toFixed(2)}</span>
268+
<span>${(parseFloat(formValues.receiptInfo.totals.total) || 0).toFixed(2)}</span>
266269
</div>
267270
<div className="flex justify-between">
268271
<span>Discount:</span>
269-
<span>-${formValues.receiptInfo.totals.totalDiscount.toFixed(2)}</span>
272+
<span>-${(parseFloat(formValues.receiptInfo.totals.totalDiscount) || 0).toFixed(2)}</span>
270273
</div>
271274
<div className="flex justify-between">
272275
<span>Tax:</span>
273-
<span>${formValues.receiptInfo.totals.totalTax.toFixed(2)}</span>
276+
<span>${(parseFloat(formValues.receiptInfo.totals.totalTax) || 0).toFixed(2)}</span>
274277
</div>
275278
<div className="flex justify-between font-bold text-lg border-t pt-2">
276279
<span>Total:</span>
277-
<span>${formValues.receiptInfo.totals.totalUSD.toFixed(2)}</span>
280+
<span>${(parseFloat(formValues.receiptInfo.totals.totalUSD) || 0).toFixed(2)}</span>
278281
</div>
279282
</div>
280283
</div>

src/components/Playground/index.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ export const Playground = () => {
2828
recipientWallet: "",
2929
paymentConfig: {
3030
walletConnectProjectId: undefined,
31-
network: "sepolia",
3231
rnApiClientId: "YOUR_CLIENT_ID_HERE",
3332
supportedCurrencies: [],
3433
feeInfo: {
@@ -60,16 +59,16 @@ export const Playground = () => {
6059
id: "1",
6160
description: "",
6261
quantity: 1,
63-
unitPrice: 0,
64-
total: 0,
62+
unitPrice: '0',
63+
total: '0',
6564
currency: "USD",
6665
},
6766
],
6867
totals: {
69-
totalDiscount: 0,
70-
totalTax: 0,
71-
total: 0,
72-
totalUSD: 0,
68+
totalDiscount: '0',
69+
totalTax: '0',
70+
total: '0',
71+
totalUSD: '0',
7372
},
7473
invoiceNumber: "",
7574
},

src/components/payment-widget/components/currency-select.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface CurrencySelectProps {
1818

1919
export function CurrencySelect({ onSubmit }: CurrencySelectProps) {
2020
const {
21-
paymentConfig: { rnApiClientId, network, supportedCurrencies },
21+
paymentConfig: { rnApiClientId, supportedCurrencies },
2222
} = usePaymentWidgetContext();
2323
const [selectedCurrency, setSelectedCurrency] = useState<string>("");
2424

@@ -28,8 +28,8 @@ export function CurrencySelect({ onSubmit }: CurrencySelectProps) {
2828
isError,
2929
refetch,
3030
} = useQuery({
31-
queryKey: ["conversionCurrencies", rnApiClientId, network],
32-
queryFn: () => getConversionCurrencies(rnApiClientId, network),
31+
queryKey: ["conversionCurrencies", rnApiClientId],
32+
queryFn: () => getConversionCurrencies(rnApiClientId),
3333
});
3434

3535
const handleSubmit = () => {
@@ -60,8 +60,8 @@ export function CurrencySelect({ onSubmit }: CurrencySelectProps) {
6060
return <div>No conversion currencies available.</div>;
6161
}
6262

63-
const lowerCaseSupportedCurrencies = (supportedCurrencies || []).map(
64-
(currency) => currency.toLowerCase(),
63+
const lowerCaseSupportedCurrencies = supportedCurrencies.map((currency) =>
64+
currency.toLowerCase(),
6565
);
6666

6767
const eligibleCurrencies =

src/components/payment-widget/components/payment-confirmation.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ export function PaymentConfirmation({
3232
amountInUsd,
3333
recipientWallet,
3434
connectedWalletAddress,
35-
paymentConfig: { rnApiClientId, feeInfo, network },
35+
paymentConfig: { rnApiClientId, feeInfo },
3636
receiptInfo: { companyInfo: { name: companyName } = {} },
3737
onError,
3838
walletAccount,
3939
} = usePaymentWidgetContext();
40-
const { isExecuting, executePayment } = usePayment(network, walletAccount);
40+
const { isExecuting, executePayment } = usePayment(
41+
selectedCurrency.network,
42+
walletAccount,
43+
);
4144
const [localError, setLocalError] = useState<string | null>(null);
4245

4346
const handleExecutePayment = async (e: React.FormEvent) => {
@@ -168,7 +171,7 @@ export function PaymentConfirmation({
168171
variant="outline"
169172
onClick={onBack}
170173
className="flex-1"
171-
disabled={isExecuting}
174+
disabled={isExecuting || !connectedWalletAddress}
172175
>
173176
Back
174177
</Button>

src/components/payment-widget/components/payment-success.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export function PaymentSuccess({
3232
connectedWalletAddress,
3333
receiptInfo,
3434
uiConfig,
35-
paymentConfig: { network },
3635
} = usePaymentWidgetContext();
3736
const receiptRef = useRef<HTMLDivElement>(null);
3837

@@ -46,9 +45,10 @@ export function PaymentSuccess({
4645
walletAddress: connectedWalletAddress || "",
4746
},
4847
payment: {
49-
chain: network,
48+
amount: amountInUsd, // TODO connect to actual payout and exchange rate
49+
chain: selectedCurrency.network,
5050
currency: selectedCurrency.symbol,
51-
exchangeRate: 1,
51+
exchangeRate: "1",
5252
transactionHash: txHash,
5353
},
5454
items: receiptInfo.items,

src/components/payment-widget/components/receipt/receipt-template.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ export const ReceiptPDFTemplate: FC<{ receipt: ReceiptData }> = ({
123123
<td className="center">{item.quantity}</td>
124124
<td className="right">
125125
{formatCryptoAmount(
126-
item.unitPrice,
126+
item.unitPrice.toString(),
127127
item.currency || receipt.payment.currency,
128128
)}
129129
</td>
130130
<td className="center">{item.discount || 0}%</td>
131131
<td className="center">{item.tax || 0}%</td>
132132
<td className="right amount">
133133
{formatCryptoAmount(
134-
item.total,
134+
item.total.toString(),
135135
item.currency || receipt.payment.currency,
136136
)}
137137
</td>
@@ -142,25 +142,25 @@ export const ReceiptPDFTemplate: FC<{ receipt: ReceiptData }> = ({
142142

143143
<div className="totals-section">
144144
<div className="totals-box">
145-
{receipt.totals.totalDiscount > 0 && (
145+
{receipt.totals.totalDiscount.length > 0 && (
146146
<div className="total-line">
147147
<span>Discount:</span>
148148
<span className="total-amount">
149149
-
150150
{formatCryptoAmount(
151-
receipt.totals.totalDiscount,
151+
receipt.totals.totalDiscount.toString(),
152152
receipt.payment.currency,
153153
)}
154154
</span>
155155
</div>
156156
)}
157157

158-
{receipt.totals.totalTax > 0 && (
158+
{receipt.totals.totalTax.length > 0 && (
159159
<div className="total-line">
160160
<span>Tax:</span>
161161
<span className="total-amount">
162162
{formatCryptoAmount(
163-
receipt.totals.totalTax,
163+
receipt.totals.totalTax.toString(),
164164
receipt.payment.currency,
165165
)}
166166
</span>
@@ -171,7 +171,7 @@ export const ReceiptPDFTemplate: FC<{ receipt: ReceiptData }> = ({
171171
<span>Subtotal:</span>
172172
<span className="total-amount">
173173
{formatCryptoAmount(
174-
receipt.totals.total,
174+
receipt.payment.amount,
175175
receipt.payment.currency,
176176
)}
177177
</span>

0 commit comments

Comments
 (0)