From 7ec922986a615641c14eb58c15d9420abbf5bd85 Mon Sep 17 00:00:00 2001 From: flexykrn Date: Wed, 17 Jun 2026 17:54:16 +0530 Subject: [PATCH] Docusaurus migration - website-src-components-4 Part 66 of the Docusaurus migration split. --- website/src/components/SpotlightCard.tsx | 51 ++++++++++++ website/src/components/StakingCalculator.tsx | 79 +++++++++++++++++++ .../src/components/TransactionLifecycle.tsx | 74 +++++++++++++++++ website/src/components/WalletSelector.tsx | 63 +++++++++++++++ 4 files changed, 267 insertions(+) create mode 100644 website/src/components/SpotlightCard.tsx create mode 100644 website/src/components/StakingCalculator.tsx create mode 100644 website/src/components/TransactionLifecycle.tsx create mode 100644 website/src/components/WalletSelector.tsx diff --git a/website/src/components/SpotlightCard.tsx b/website/src/components/SpotlightCard.tsx new file mode 100644 index 00000000..22b4abe5 --- /dev/null +++ b/website/src/components/SpotlightCard.tsx @@ -0,0 +1,51 @@ +import React, { useRef, useState, useCallback } from 'react'; + +/** + * SpotlightCard — adds a radial glow that follows the cursor. + * Premium hover effect used by Linear, Vercel, Clerk, etc. + */ + +interface SpotlightCardProps { + children: React.ReactNode; + className?: string; +} + +export function SpotlightCard({ children, className = '' }: SpotlightCardProps) { + const ref = useRef(null); + const [position, setPosition] = useState({ x: 0, y: 0 }); + const [opacity, setOpacity] = useState(0); + + const handleMouseMove = useCallback((e: React.MouseEvent) => { + if (!ref.current) return; + const rect = ref.current.getBoundingClientRect(); + setPosition({ + x: e.clientX - rect.left, + y: e.clientY - rect.top, + }); + }, []); + + const handleMouseEnter = useCallback(() => setOpacity(1), []); + const handleMouseLeave = useCallback(() => setOpacity(0), []); + + return ( +
+
+ {children} +
+ ); +} + +export default SpotlightCard; + diff --git a/website/src/components/StakingCalculator.tsx b/website/src/components/StakingCalculator.tsx new file mode 100644 index 00000000..5b5918d0 --- /dev/null +++ b/website/src/components/StakingCalculator.tsx @@ -0,0 +1,79 @@ +import React, { useState } from 'react'; +import { TrendingUp } from 'lucide-react'; + +export function StakingCalculator() { + const [amount, setAmount] = useState(1000000); + const [apy, setApy] = useState(8); + const [years, setYears] = useState(1); + + const reward = amount * Math.pow(1 + apy / 100, years) - amount; + const total = amount + reward; + + return ( +
+
+
+ +

Staking APY Calculator

+
+
+
+
+ + setAmount(Number(e.target.value))} + className="w-full accent-primary" + /> +
{amount.toLocaleString()} XDC
+
+ +
+
+ + setApy(Number(e.target.value))} + className="w-full accent-primary" + /> +
{apy}%
+
+
+ + setYears(Number(e.target.value))} + className="w-full accent-primary" + /> +
{years} year{years > 1 ? 's' : ''}
+
+
+ +
+
+ Total Reward + +{reward.toLocaleString(undefined, { maximumFractionDigits: 0 })} XDC +
+
+ Total Value + {total.toLocaleString(undefined, { maximumFractionDigits: 0 })} XDC +
+
+
+
+ ); +} + +export default StakingCalculator; diff --git a/website/src/components/TransactionLifecycle.tsx b/website/src/components/TransactionLifecycle.tsx new file mode 100644 index 00000000..b0d7143c --- /dev/null +++ b/website/src/components/TransactionLifecycle.tsx @@ -0,0 +1,74 @@ +import React, { useState } from 'react'; +import { Send, CheckCircle2, Clock, Box } from 'lucide-react'; + +const stages = [ + { id: 'broadcasted', title: 'Broadcasted', description: 'Transaction sent to the network' }, + { id: 'included', title: 'Included', description: 'Transaction added to a block' }, + { id: 'reversible', title: 'Reversible', description: 'Block confirmed but not yet final' }, + { id: 'finalized', title: 'Finalized', description: 'Transaction is irreversible' }, +]; + +export function TransactionLifecycle() { + const [activeStage, setActiveStage] = useState(3); + + return ( +
+
+
+ +

Transaction Lifecycle

+
+
+
+
+ {stages.map((stage, index) => ( + + ))} +
+
+
+
+ +
+

{stages[activeStage].title}

+

{stages[activeStage].description}

+
+ {activeStage === 3 ? 'Typical time on XDC: ~2-4 seconds' : `Step ${activeStage + 1} of ${stages.length}`} +
+
+
+
+ ); +} + +export default TransactionLifecycle; diff --git a/website/src/components/WalletSelector.tsx b/website/src/components/WalletSelector.tsx new file mode 100644 index 00000000..e50738c1 --- /dev/null +++ b/website/src/components/WalletSelector.tsx @@ -0,0 +1,63 @@ +import React, { useState } from 'react'; +import { Wallet, ArrowRight, CheckCircle2 } from 'lucide-react'; + +const wallets = [ + { name: 'XDCPay', type: 'Browser Extension', recommended: true }, + { name: 'MetaMask', type: 'Multi-chain Wallet' }, + { name: 'Ledger', type: 'Hardware Wallet' }, + { name: 'Trust Wallet', type: 'Mobile Wallet' }, +]; + +export function WalletSelector() { + const [selected, setSelected] = useState(wallets[0].name); + + return ( +
+
+
+ +

Choose a Wallet

+
+
+
+ {wallets.map((wallet) => ( + + ))} +
+
+ ); +} + +export default WalletSelector;