Skip to content
Merged
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
9 changes: 6 additions & 3 deletions packages/nextjs/components/NewAccount/SuccessScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const SuccessScreen: React.FC<SuccessScreenProps> = ({ className, createdAccount
const router = useAppRouter();
const [isReceiveModalOpen, setIsReceiveModalOpen] = useState(false);
const [fundAddress, setFundAddress] = useState("");
const [fundChainId, setFundChainId] = useState<number | undefined>(undefined);

const { currentAccount } = useAccountStore();
const { openManageAccountsWithExpand } = useSidebarStore();
Expand All @@ -35,8 +36,9 @@ const SuccessScreen: React.FC<SuccessScreenProps> = ({ className, createdAccount
router.goToDashboard();
};

const handleFund = (address: string) => {
const handleFund = (address: string, chainId?: number) => {
setFundAddress(address);
setFundChainId(chainId);
setIsReceiveModalOpen(true);
};

Expand Down Expand Up @@ -108,7 +110,7 @@ const SuccessScreen: React.FC<SuccessScreenProps> = ({ className, createdAccount

{/* Fund button */}
<button
onClick={() => handleFund(acc.address)}
onClick={() => handleFund(acc.address, acc.chainId)}
className="shrink-0 bg-primary text-black text-xs font-semibold px-3 py-1.5 rounded-lg hover:bg-pink-400 transition-colors"
>
Fund
Expand Down Expand Up @@ -142,7 +144,7 @@ const SuccessScreen: React.FC<SuccessScreenProps> = ({ className, createdAccount
<span className="font-semibold text-base text-center text-white">See your account</span>
</button>
<button
onClick={() => handleFund(currentAccount?.address || "")}
onClick={() => handleFund(currentAccount?.address || "", currentAccount?.chainId)}
className="flex-1 bg-primary flex items-center justify-center px-6 py-2 rounded-xl shadow-lg hover:shadow-xl transition-all hover:scale-[1.02] cursor-pointer"
>
<span className="font-semibold text-base text-center text-black">Fund your account</span>
Expand All @@ -157,6 +159,7 @@ const SuccessScreen: React.FC<SuccessScreenProps> = ({ className, createdAccount
isOpen={isReceiveModalOpen}
onClose={() => setIsReceiveModalOpen(false)}
address={fundAddress || currentAccount?.address || ""}
chainId={fundChainId ?? currentAccount?.chainId}
/>
</div>
);
Expand Down
26 changes: 23 additions & 3 deletions packages/nextjs/components/Transfer/TransferContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,23 @@ export default function TransferContainer() {
const watchedAmount = form.watch("amount");
const isAmountValid = watchedAmount !== "" && parseFloat(watchedAmount) > 0;

const hasInsufficientBalance = (() => {
if (!isAmountValid || isLoadingBalances) return false;
try {
const amountBI = isNativeETH
? parseEther(watchedAmount)
: BigInt(parseTokenAmount(watchedAmount, selectedToken.decimals));
const balanceBI = isNativeETH
? parseEther(currentBalance)
: BigInt(parseTokenAmount(currentBalance, selectedToken.decimals));
return amountBI > balanceBI;
} catch {
return false;
}
})();

const canSubmit = isAmountValid && !!watchedRecipient && !hasInsufficientBalance && !isLoading;

return (
<div className="overflow-hidden relative w-full h-full flex flex-col rounded-lg">
{/* Background images */}
Expand Down Expand Up @@ -209,7 +226,10 @@ export default function TransferContainer() {
</div>

{form.formState.errors.amount && (
<p className="text-red-500 text-xs">{form.formState.errors.amount.message}</p>
<p className="text-red-500 text-xs text-center">{form.formState.errors.amount.message}</p>
)}
{hasInsufficientBalance && !form.formState.errors.amount && (
<p className="text-red-500 text-xs text-center">Insufficient {selectedToken.symbol} balance</p>
)}
</div>
{/* Visual divider */}
Expand Down Expand Up @@ -264,7 +284,7 @@ export default function TransferContainer() {
<div className="flex gap-2 items-center justify-center w-full max-w-xs">
<button
onClick={handleAddToBatch}
disabled={isLoading || !isAmountValid || !watchedRecipient}
disabled={!canSubmit}
className="bg-main-black flex items-center justify-center gap-2 px-3 py-2 rounded-[10px] disabled:opacity-50 cursor-pointer border-0 flex-1 transition-colors"
>
{isLoading && <Spinner />}
Expand All @@ -274,7 +294,7 @@ export default function TransferContainer() {
</button>
<button
onClick={form.handleSubmit(handleTransfer)}
disabled={isLoading || !isAmountValid || !watchedRecipient}
disabled={!canSubmit}
className="bg-pink-350 flex items-center justify-center gap-2 px-3 py-2 rounded-[10px] disabled:opacity-50 cursor-pointer border-0 flex-1 hover:bg-pink-450 transition-colors"
>
{isLoading && <Spinner />}
Expand Down
3 changes: 3 additions & 0 deletions packages/nextjs/components/modals/ModalContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface ModalProps {
desc?: string;
icon?: string;
isCloseButton?: boolean;
closeButtonClassName?: string;
className?: string;
loadingTransaction?: boolean;
preventClose?: boolean;
Expand All @@ -34,6 +35,7 @@ const ModalContainer = forwardRef<ModalRef, ModalProps>(
desc,
icon,
isCloseButton = true,
closeButtonClassName,
className,
loadingTransaction = false,
preventClose = false,
Expand Down Expand Up @@ -64,6 +66,7 @@ const ModalContainer = forwardRef<ModalRef, ModalProps>(
<DialogContent
className={cn("rounded-3xl w-[600px] px-1.5 py-4 shadow-modal", className)}
showCloseButton={isCloseButton}
closeButtonClassName={closeButtonClassName}
onEscapeKeyDown={e => loadingTransaction && e.preventDefault()}
onPointerDownOutside={e => loadingTransaction && e.preventDefault()}
>
Expand Down
6 changes: 4 additions & 2 deletions packages/nextjs/components/modals/QRAddressReceiverModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { notification } from "~~/utils/scaffold-eth";

interface QRAddressReceiverModalProps extends ModalProps {
address?: string;
chainId?: number;
}

const QRAddressReceiverModal: React.FC<QRAddressReceiverModalProps> = ({ isOpen, onClose, address }) => {
const QRAddressReceiverModal: React.FC<QRAddressReceiverModalProps> = ({ isOpen, onClose, address, chainId }) => {
const { currentAccount } = useAccountStore();
const networkIcon = currentAccount?.chainId ? getNetworkMeta(currentAccount.chainId).icon : "/logo/polypay-icon.svg";
const resolvedChainId = chainId ?? currentAccount?.chainId;
const networkIcon = resolvedChainId ? getNetworkMeta(resolvedChainId).icon : "/logo/polypay-icon.svg";
const handleCopy = () => {
navigator.clipboard.writeText(address ?? "");
notification.success("Address copied to clipboard");
Expand Down
5 changes: 3 additions & 2 deletions packages/nextjs/components/modals/ReceiveMethodModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ const ReceiveMethodModal: React.FC<ReceiveMethodModalProps> = ({
onClose={onClose}
title="Select a receive method"
isCloseButton
className="bg-white rounded-3xl w-[min(560px,92vw)] px-5 py-5 shadow-modal"
closeButtonClassName="top-1 right-2"
className="bg-white rounded-3xl w-[min(560px,92vw)] p-5 shadow-modal"
>
<div className="flex flex-col gap-3 pt-6">
<div className="flex flex-col gap-3 pt-5">
{/* Option 1 — QR */}
<button
type="button"
Expand Down
17 changes: 2 additions & 15 deletions packages/nextjs/components/modals/SwitchAccountModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,8 @@ const SwitchAccountModal: React.FC<ModalProps> = ({ isOpen, onClose }) => {
{step === 1 ? "Choose network" : "Choose your account"}
</span>

{/* Close button */}
<button
onClick={onClose}
className="w-[38px] h-icon-btn flex items-center justify-center rounded-lg border border-grey-200 hover:bg-grey-100 transition-colors"
>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none">
<path
d="M4.5 4.5L13.5 13.5M4.5 13.5L13.5 4.5"
stroke="#363636"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
{/* Spacer to balance back button so title stays centered */}
<div className="w-[38px] h-icon-btn" />
</div>

{/* Content */}
Expand Down
7 changes: 6 additions & 1 deletion packages/nextjs/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ function DialogContent({
className,
children,
showCloseButton = true,
closeButtonClassName,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
showCloseButton?: boolean;
closeButtonClassName?: string;
}) {
return (
<DialogPortal data-slot="dialog-portal">
Expand All @@ -58,7 +60,10 @@ function DialogContent({
{showCloseButton && (
<DialogPrimitive.Close
data-slot="dialog-close"
className="h-8 w-8 p-1.5 text-black bg-white cursor-pointer hover:bg-gray-200 absolute top-1 right-3 rounded-md "
className={cn(
"h-8 w-8 p-1.5 text-black bg-white cursor-pointer hover:bg-gray-200 absolute top-5 right-5 rounded-md",
closeButtonClassName,
)}
>
<X className="w-5 h-5" />
</DialogPrimitive.Close>
Expand Down
4 changes: 2 additions & 2 deletions packages/nextjs/scaffold.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ const scaffoldConfig = {
// If you want to use a different RPC for a specific network, you can add it here.
// The key is the chain ID, and the value is the HTTP RPC URL
rpcOverrides: {
// Example:
// [chains.mainnet.id]: "https://mainnet.buidlguidl.com",
// Default Alchemy key has no access to Base mainnet (403); public mainnet.base.org rate-limits (429).
[chains.base.id]: "https://base-rpc.publicnode.com",
},
// This is ours WalletConnect's default project ID.
// You can get your own at https://cloud.walletconnect.com
Expand Down
Loading