DEV Community

Arif Can
Arif Can

Posted on

Transferring BTC Total data to amount on page 2 (help)

I want my Total BTC data in Bitcoin-Payment.tsx to be taken and when I click the "Pay with BTC" button, I want it to be directed to the 2nd page, BtcPaymentConfirmation.tsx, and I want the total data on the 1st page to appear in the "amount:" section, along with the 8-digit random order number. Can you help me?

//btc-payment.tsx page(1.page)
"use client";
import AnimationContainer from "@/components/global/animation-container";
import React, { useState, useEffect } from "react";
import axios from "axios";
import { FaCreditCard, FaMoneyBillWave } from "react-icons/fa";
import { useRouter } from "next/compat/router";

const BtcPayment = () => {
    const [selectedProduct, setSelectedProduct] = useState<string | null>(null);
    const [selectedCardSubType, setSelectedCardSubType] = useState<string | null>(null);
    const [selectedBalanceType, setSelectedBalanceType] = useState<string | null>(null);
    const [isLoading, setIsLoading] = useState(false);
    const [btcRate, setBtcRate] = useState<number | null>(null);
    const router = useRouter();

    const handlePayment = () => {
        const orderNumber = Math.floor(10000000 + Math.random() * 90000000).toString();
        const total = selectedProduct
            ? (selectedProduct === "Virtual Subscription" && selectedBalanceType
                ? {
                    "$50": 5,
                    "$100": 10,
                    "$200": 20,
                }[selectedBalanceType] || 0
                : products.find(p => p.name === selectedProduct)?.usdPrice! || 0) / (btcRate || 1)
            : 0;

        if (total > 0) {
            if (router) {
                router.push({
                    pathname: "/BtcPaymentConfirmation",
                    query: { orderNumber, btcAmount: total.toFixed(4) },
                });
            }
        } else {
            console.error("Total amount is zero or invalid");
        }
    };

    // Updated products with random names and options
    const products = [
        { name: "Digital Product A", usdPrice: 100, icon: <FaCreditCard /> },
        { name: "Digital Product B", usdPrice: 200, icon: <FaCreditCard /> },
        { name: "Virtual Subscription", usdPrice: 50, icon: <FaMoneyBillWave /> },
    ];

    useEffect(() => {
        const fetchBtcRate = async () => {
            try {
                const response = await axios.get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd");
                setBtcRate(response.data.bitcoin.usd);
            } catch (error) {
                console.error("Error fetching BTC rate:", error);
            }
        };

        fetchBtcRate();
        const interval = setInterval(fetchBtcRate, 60000);
        return () => clearInterval(interval);
    }, []);

    const handleProductSelect = (productName: string) => {
        setSelectedProduct(productName === selectedProduct ? null : productName);
        setSelectedCardSubType(null);
        setSelectedBalanceType(null);
    };

    const total = selectedProduct
        ? (selectedProduct === "Virtual Subscription" && selectedBalanceType
            ? {
                "$50": 5,
                "$100": 10,
                "$200": 20,
              }[selectedBalanceType] || 0
            : products.find(p => p.name === selectedProduct)?.usdPrice! || 0) / (btcRate || 1)
        : 0;

    return (
        <div className="flex flex-col items-center justify-center py-20">
            <AnimationContainer delay={0.1}>
                <h1 className="text-2xl md:text-4xl lg:text-5xl font-semibold font-heading text-center mt-6 !leading-tight">
                    Select Your Product
                </h1>
                <p className="text-base md:text-lg mt-6 text-center text-muted-foreground">
                    Choose the product you want to purchase with BTC.
                </p>
            </AnimationContainer>

            <div className="mt-10 w-full max-w-md">
                <div className="flex flex-col items-center mt-4 space-y-4">
                    {products.map((product) => (
                        <button
                            key={product.name}
                            className={`w-full p-2 rounded border flex items-center justify-between ${
                                selectedProduct === product.name
                                    ? "bg-primary text-primary-foreground"
                                    : "bg-white text-black"
                            }`}
                            onClick={() => handleProductSelect(product.name)}
                        >
                            <span className="flex items-center space-x-2">
                                {product.icon}
                                <span>{product.name}</span>
                            </span>
                            <span>{btcRate ? (product.usdPrice / btcRate).toFixed(4) : "Loading..."} BTC</span>
                        </button>
                    ))}

                    {selectedProduct && (selectedProduct === "Digital Product A" || selectedProduct === "Digital Product B") && (
                        <div className="mt-6 w-full max-w-xs border-t pt-4">
                            <p className="text-center mb-2">Choose Card Type</p>
                            <div className="flex justify-center space-x-4">
                                {["Visa", "MasterCard", "American Express"].map((cardType) => (
                                    <button
                                        key={cardType}
                                        className={`px-4 py-2 rounded border ${
                                            selectedCardSubType === cardType
                                                ? "bg-primary text-primary-foreground"
                                                : "bg-white text-black"
                                        }`}
                                        onClick={() => setSelectedCardSubType(cardType)}
                                    >
                                        {cardType}
                                    </button>
                                ))}
                            </div>
                        </div>
                    )}

                    {selectedProduct === "Virtual Subscription" && (
                        <div className="mt-6 w-full max-w-xs border-t pt-4">
                            <p className="text-center mb-2">Choose Balance Type</p>
                            <div className="flex justify-center space-x-4">
                                {["$50", "$100", "$200"].map((balanceType) => (
                                    <button
                                        key={balanceType}
                                        className={`px-4 py-2 rounded border ${
                                            selectedBalanceType === balanceType
                                                ? "bg-primary text-primary-foreground"
                                                : "bg-white text-black"
                                        }`}
                                        onClick={() => setSelectedBalanceType(balanceType)}
                                    >
                                        {balanceType}
                                    </button>
                                ))}
                            </div>
                        </div>
                    )}
                </div>

                <div className="mt-6 text-center">
                    <p className="text-lg font-medium">
                        Total: {total.toFixed(4)} BTC
                    </p>
                    <button
                        className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 active:scale-95 transition-all bg-primary text-primary-foreground hover:bg-primary/90 primary h-9 px-4 py-2 mt-4"
                        disabled={
                            isLoading ||
                            !selectedProduct ||
                            ((selectedProduct === "Digital Product A" || selectedProduct === "Digital Product B") && !selectedCardSubType) ||
                            (selectedProduct === "Virtual Subscription" && !selectedBalanceType)
                        }
                        onClick={handlePayment}
                    >
                        {isLoading ? (
                            <span className="loader mr-2"></span>
                        ) : (
                            "Pay with BTC"
                        )}
                    </button>
                </div>

                {selectedProduct && (
                    <div className="mt-6 text-center">
                        <p className="text-lg font-semibold">Selected Product: {selectedProduct}</p>
                        {selectedProduct === "Virtual Subscription" && selectedBalanceType && (
                            <p className="text-md">Balance Type: {selectedBalanceType}</p>
                        )}
                        {(selectedProduct === "Digital Product A" || selectedProduct === "Digital Product B") && selectedCardSubType && (
                            <p className="text-md">Card Type: {selectedCardSubType}</p>
                        )}
                    </div>
                )}
            </div>

            <style jsx>{`
                .loader {
                    border: 4px solid rgba(255, 255, 255, 0.3);
                    border-top: 4px solid #ffffff;
                    border-radius: 50%;
                    width: 24px;
                    height: 24px;
                    animation: spin 1s linear infinite;
                }

                @keyframes spin {
                    0% {
                        transform: rotate(0deg);
                    }
                    100% {
                        transform: rotate(360deg);
                    }
                }
            `}</style>
        </div>
    );
};

export default BtcPayment;

Enter fullscreen mode Exit fullscreen mode
//BtcPaymentConfirmation.tsx (2.page)
"use client"
import { BorderBeam } from "@/components/ui/border-beam";
import { useEffect, useState } from "react";
import { Copy } from 'lucide-react'; // Importing the Copy icon

const BtcPaymentConfirmation = () => {
    const [timeLeft, setTimeLeft] = useState(900); // 15-minute countdown
    const [copyMessage, setCopyMessage] = useState(""); // State for copy feedback

    const walletAddress = "bc1qmpph23yp6dgqwd2dzee02djauevp9d57rqw8nu"; // Replace with actual wallet address

    // Google Charts API URL for QR code generation
    const qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=180x180&data=${encodeURIComponent(walletAddress)}`;

    // Countdown timer
    useEffect(() => {
        if (timeLeft > 0) {
            const timer = setInterval(() => setTimeLeft(prev => prev - 1), 1000);
            return () => clearInterval(timer);
        }
    }, [timeLeft]);

    const formatTime = (seconds: number) => {
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = seconds % 60;
        return `${minutes}:${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}`;
    };

    const percentageLeft = (timeLeft / 900) * 100; // Calculate percentage left

    // Function to copy wallet address
    const copyToClipboard = () => {
        navigator.clipboard.writeText(walletAddress).then(() => {
            setCopyMessage("Copied!"); // Show feedback message
            setTimeout(() => setCopyMessage(""), 2000); // Clear message after 2 seconds
        }).catch(err => {
            console.error('Failed to copy: ', err);
        });
    };

    return (
        <div className="flex items-center justify-center min-h-screen">
            <div className="shadow-md rounded-lg p-8 w-full max-w-lg text-center border border-white">

                <h1 className="text-2xl md:text-4xl lg:text-5xl font-semibold font-heading mt-4 mb-4">Payment Confirmation</h1>
                <p className="text-lg font-semibold mb-2">Order Number:</p>
                <p className="text-lg mb-4 font-semibold font-heading">Amount:</p>

                <div className="relative mt-4 border-2 border-violet-500 rounded p-1 inline-block"> {/* Tighter frame design */}
                    <img src={qrCodeUrl} alt="QR Code" width={180} height={180} className="mx-auto" />
                </div>
                <p className="text-center mt-2">Scan to Pay</p>

                <div className="mt-6">
                    <p className="text-center text-sm font-semibold font-heading">Wallet Address:</p>
                    <div className="flex items-center justify-center">
                        <p className="text-sm font-semibold font-heading mr-2">{walletAddress}</p>
                        <button 
                            onClick={copyToClipboard} 
                            className="p-2 text-white rounded flex items-center justify-center"
                            aria-label="Copy wallet address"
                        >
                            <Copy className="h-5 w-5" />
                        </button>
                    </div>
                    {copyMessage && <p className="text-white font-semibold font-heading mt-2">{copyMessage}</p>} {/* Feedback message */}
                </div>

                <div className="mt-6 text-lg font-semibold font-heading text-white">
                    <span className="text-transparent bg-gradient-to-r from-violet-500 to-fuchsia-500 bg-clip-text inline-block">
                        Complete your payment in: {formatTime(timeLeft)} 
                    </span>
                </div>

                {/* Countdown bar */}
                <div className="mt-4 h-4 bg-gray-500 rounded">
                    <div
                        className="h-full bg-white rounded"
                        style={{ width: `${percentageLeft}%` }}
                    />
                </div>
            </div>
        </div>
    );
};

export default BtcPaymentConfirmation;

Enter fullscreen mode Exit fullscreen mode

Top comments (0)