Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 56 additions & 4 deletions app/mint/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const metadata: Metadata = {

import React, { useState, useEffect, useMemo } from 'react';
import Link from 'next/link';
import { useRouter, useSearchParams } from 'next/navigation';
import { PageContainer } from '@/components/layout/page-container';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
Expand Down Expand Up @@ -83,6 +84,8 @@ export default function MintPage() {
refetch: refetchBalance,
} = useBalance();
const kit = useStellarWalletsKit();
const router = useRouter();
const searchParams = useSearchParams();
const { uiError: mintUiError, setApiError: setMintApiError, clearError: clearMintError, isSubmitDisabled: isMintDisabled } = useApiError();
const { uiError: burnUiError, setApiError: setBurnApiError, clearError: clearBurnError, isSubmitDisabled: isBurnDisabled } = useApiError();
const [activeTab, setActiveTab] = useState<'mint' | 'burn' | 'rates'>('mint');
Expand Down Expand Up @@ -130,6 +133,34 @@ export default function MintPage() {
.finally(() => setFiatAccountsLoading(false));
}, [opts.token]);

useEffect(() => {
if (activeTab !== "rates") return;
setRatesLoading(true);
ratesApi
.getRates(opts)
.then(setRates)
.catch(() => setRates(null))
.finally(() => setRatesLoading(false));
}, [activeTab, opts.token]);

useEffect(() => {
const stepParam = searchParams.get("step");
if (stepParam === "confirm" || stepParam === "success") {
setStep(stepParam);
} else {
setStep("input");
}
}, [searchParams]);

const handleMintConfirm = () => {
setMintError("");
router.push("/mint?step=confirm", { scroll: false });
setStep("confirm");
};
const handleBurnConfirm = () => {
router.push("/mint?step=confirm", { scroll: false });
setStep("confirm");
};
const handleMintConfirm = () => {
clearMintError();
setStep("confirm");
Expand Down Expand Up @@ -236,7 +267,8 @@ export default function MintPage() {
setMintAcbuReceived(
typeof acbu === "number" && Number.isFinite(acbu) ? acbu : null,
);
refetchBalance();
refreshBalance();
router.replace("/mint?step=success", { scroll: false });
setStep("success");
} catch (e) {
setMintApiError(e);
Expand Down Expand Up @@ -313,6 +345,7 @@ export default function MintPage() {
opts,
);
setTxId(res.transaction_id || res.transactionId || null);
router.replace("/mint?step=success", { scroll: false });
setStep("success");
} catch (e) {
setBurnApiError(e);
Expand All @@ -328,6 +361,7 @@ export default function MintPage() {
};
const resetForm = () => {
setStep("input");
router.replace("/mint", { scroll: false });
setFiatAmount("");
setBurnAmount("");
clearBurnError();
Expand Down Expand Up @@ -661,7 +695,15 @@ export default function MintPage() {
</Tabs>
</PageContainer>

<AlertDialog open={step === "confirm"}>
<AlertDialog
open={step === "confirm"}
onOpenChange={(open) => {
if (!open) {
router.replace("/mint", { scroll: false });
}
setStep(open ? "confirm" : "input");
}}
>
<AlertDialogContent className="max-w-md border-border">
<AlertDialogHeader>
<AlertDialogTitle>
Expand Down Expand Up @@ -696,7 +738,10 @@ export default function MintPage() {
</div>
<div className="flex gap-2">
<AlertDialogCancel
onClick={() => setStep("input")}
onClick={() => {
setStep("input");
router.replace("/mint", { scroll: false });
}}
disabled={executing}
>
{t('mint.cancel')}
Expand All @@ -712,7 +757,14 @@ export default function MintPage() {
</AlertDialogContent>
</AlertDialog>

<AlertDialog open={step === "success"}>
<AlertDialog
open={step === "success"}
onOpenChange={(open) => {
if (!open) {
router.replace("/mint", { scroll: false });
}
}}
>
<AlertDialogContent className="max-w-md border-border">
<AlertDialogHeader>
<AlertDialogTitle>{t('mint.operationComplete')}</AlertDialogTitle>
Expand Down
131 changes: 93 additions & 38 deletions app/send/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const metadata: Metadata = {
import React, { useState, useEffect, useCallback, useMemo, useRef } from "react";
import { useVirtualizer } from "@tanstack/react-virtual";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
Expand Down Expand Up @@ -120,16 +121,41 @@ export default function SendPage() {
const [contactsError, setContactsError] = useState("");
const [submitError, setSubmitError] = useState("");
const [sending, setSending] = useState(false);
const [loadError, setLoadError] = useState("");

const contactsParentRef = useRef<HTMLDivElement>(null);

const virtualizer = useVirtualizer({
count: contacts.length,
getScrollElement: () => contactsParentRef.current?.parentElement as Element | null,
estimateSize: () => 36,
overscan: 5,
});
const router = useRouter();
const searchParams = useSearchParams();

useEffect(() => {
const step = searchParams.get("step");
setShowConfirmDialog(step === "confirm");
setShowSuccessDialog(step === "success");

if (step === "confirm") {
setShowSendDialog(true);
}
if (step === "success") {
setShowSendDialog(false);
}
}, [searchParams]);

const openConfirmDialog = () => {
setShowConfirmDialog(true);
router.push("/send?step=confirm", { scroll: false });
};

const closeConfirmDialog = () => {
setShowConfirmDialog(false);
router.replace("/send", { scroll: false });
};

const openSuccessDialog = () => {
setShowSuccessDialog(true);
router.replace("/send?step=success", { scroll: false });
};

const closeSuccessDialog = () => {
setShowSuccessDialog(false);
router.replace("/send", { scroll: false });
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const loadTransfers = useCallback(async () => {
setLoadError("");
Expand Down Expand Up @@ -251,6 +277,8 @@ export default function SendPage() {
refetchBalance();
setShowConfirmDialog(false);
setShowSendDialog(false);
setLastSentAmount(amount);
openSuccessDialog();
setLastSentAmount(confirmedAmount);
setShowSuccessDialog(true);

Expand Down Expand Up @@ -526,6 +554,8 @@ export default function SendPage() {
{t('send.cancel')}
</Button>
<Button
onClick={openConfirmDialog}
disabled={!isFormValid()}
onClick={() => {
setConfirmedAmount(amount);
setShowConfirmDialog(true);
Expand All @@ -541,12 +571,15 @@ export default function SendPage() {
</Dialog>

{/* Confirm Dialog */}
<AlertDialog open={showConfirmDialog} onOpenChange={(open) => {
if (!open && !sending) {
setConfirmedAmount("");
}
setShowConfirmDialog(open);
}}>
<AlertDialog
open={showConfirmDialog}
onOpenChange={(open) => {
setShowConfirmDialog(open);
if (!open) {
router.replace("/send", { scroll: false });
}
}}
>
<AlertDialogContent className="max-w-md border-border">
<AlertDialogHeader>
<AlertDialogTitle>{t('send.confirmTransfer')}</AlertDialogTitle>
Expand Down Expand Up @@ -589,30 +622,52 @@ export default function SendPage() {
)}
</div>
<div className="flex gap-3">
<AlertDialogCancel className="flex-1 border-border" disabled={sending}>{t('send.cancel')}</AlertDialogCancel>
<AlertDialogAction onClick={handleConfirmTransfer} className="flex-1 bg-primary text-primary-foreground hover:bg-primary/90" disabled={sending || isSubmitDisabled}>{sending ? t('send.sending') : t('send.sendAcbu', { amount })}</AlertDialogAction>
<AlertDialogCancel
className="flex-1 border-border"
disabled={sending}
onClick={closeConfirmDialog}
>
Cancel
</AlertDialogCancel>
<AlertDialogAction
onClick={handleConfirmTransfer}
className="flex-1 bg-primary text-primary-foreground hover:bg-primary/90"
disabled={sending}
>
{sending ? 'Sending...' : `Send ACBU ${amount}`}
</AlertDialogAction>
</div>
</AlertDialogContent>
</AlertDialog>

<Dialog open={showSuccessDialog} onOpenChange={setShowSuccessDialog}>
<DialogContent className="max-w-md border-border">
<div className="flex flex-col items-center text-center py-6">
<div className="rounded-full bg-green-100 dark:bg-green-900 p-4 mb-4">
<Check className="h-8 w-8 text-green-600 dark:text-green-300" />
</div>
<h2 className="text-xl font-bold text-foreground mb-2">
{t('send.transferSent')}
</h2>
<p className="text-muted-foreground mb-4">
{t('send.transferSentDescription', { amount: formatAmount(lastSentAmount) })}
</p>
<Badge variant="secondary" className="mb-4">
{t('send.pending')}
</Badge>
</div>
</DialogContent>
</Dialog>
</Tabs>
);

<Dialog
open={showSuccessDialog}
onOpenChange={(open) => {
setShowSuccessDialog(open);
if (!open) {
router.replace("/send", { scroll: false });
}
}}
>
<DialogContent className="max-w-md border-border">
<div className="flex flex-col items-center text-center py-6">
<div className="rounded-full bg-green-100 dark:bg-green-900 p-4 mb-4">
<Check className="h-8 w-8 text-green-600 dark:text-green-300" />
</div>
<h2 className="text-xl font-bold text-foreground mb-2">
Transfer Sent!
</h2>
<p className="text-muted-foreground mb-4">
Your transfer for ACBU {formatAmount(lastSentAmount)}{" "}
is being processed.
</p>
<Badge variant="secondary" className="mb-4">
Pending
</Badge>
</div>
</DialogContent>
</Dialog>
</>
);
}
Loading