From 6153f1e9f44ed7d97a3d13af08eb2d330fe8ce72 Mon Sep 17 00:00:00 2001 From: Ugo-X Date: Mon, 28 Jul 2025 10:50:30 +0100 Subject: [PATCH 01/58] cleanup/initial --- app/about/page.tsx | 25 - app/components/Ethereum-provider.tsx | 103 --- app/components/FAQ.tsx | 105 --- app/components/HomeNav.tsx | 145 ----- app/components/Sidebar.tsx | 53 -- app/components/Starknet-provider.tsx | 38 -- app/components/TradingChart/Coins.tsx | 146 ----- app/components/TradingChart/chart.tsx | 171 ----- app/components/TradingChart/data.ts | 75 --- app/components/TradingChart/trading-chart.tsx | 139 ---- app/components/about-core-problems.tsx | 167 ----- app/components/about-header.tsx | 81 --- app/components/about-team.tsx | 142 ---- app/components/about-technology.tsx | 186 ------ app/components/about.tsx | 135 ---- app/components/analyticgraph.tsx | 211 ------ app/components/analytics.tsx | 383 ----------- app/components/claim-burn.tsx | 608 ------------------ app/components/connectWallet.tsx | 129 ---- app/components/deposit.tsx | 170 ----- app/components/ethereumWallet.tsx | 75 --- app/components/footer.tsx | 150 ----- app/components/header.tsx | 286 -------- app/components/how-it-works.tsx | 195 ------ app/components/join-community.tsx | 57 -- app/components/lock-liquidity.tsx | 146 ----- app/components/lock-summary.tsx | 79 --- app/components/mobile-navigator.tsx | 59 -- app/components/navbar.tsx | 420 ------------ app/components/rippleSVG.tsx | 435 ------------- app/components/starknetWallet.tsx | 90 --- .../success-state/animated-icon.tsx | 51 -- .../success-state/success-state.tsx | 62 -- app/components/swap.tsx | 564 ---------------- app/components/testimonial.tsx | 188 ------ app/components/tokenclaim.tsx | 34 - app/components/ui/button.tsx | 67 -- app/components/walletcard.tsx | 30 - app/config.ts | 19 - app/dashboard/analytics/page.tsx | 20 - app/dashboard/claim-burn/page.tsx | 189 ------ app/dashboard/lock-liquidity/page.tsx | 80 --- app/dashboard/page.tsx | 40 +- app/dashboard/swap/page.tsx | 17 - app/db/schema.sql | 9 - app/globals.css | 221 ------- app/governance/page.tsx | 235 ------- app/governance/voting-proposals/[id]/page.tsx | 455 ------------- app/governance/voting-proposals/page.tsx | 212 ------ app/hooks/useRegistration.ts | 103 --- app/hooks/useWalletState.ts | 40 -- app/layout.tsx | 106 --- app/lock-summary/page.tsx | 10 - app/page.tsx | 27 +- app/success/page.tsx | 32 - lib/utils.ts | 6 - public/Chart.png | Bin 1895 -> 0 bytes public/Claim.png | Bin 870 -> 0 bytes public/Cog.png | Bin 2476 -> 0 bytes public/Coins.png | Bin 1823 -> 0 bytes public/GithubLogo.svg | 10 - public/Menu.png | Bin 585 -> 0 bytes public/Notification.png | Bin 1424 -> 0 bytes public/Swap.png | Bin 875 -> 0 bytes public/XLogo.svg | 3 - public/about-header-icon.png | Bin 66597 -> 0 bytes public/about-header.png | Bin 111837 -> 0 bytes public/aboutTeamBlur.svg | 12 - public/aboutTeamBlur2.svg | 12 - public/arrowdownfaq.svg | 9 - public/background.svg | 34 - public/bell.png | Bin 1551 -> 0 bytes public/blocky.svg | 15 - public/check-bg.svg | 218 ------- public/dashboard.png | Bin 502 -> 0 bytes public/down-pointer-desktop.png | Bin 310 -> 0 bytes public/down-pointer.png | Bin 324 -> 0 bytes public/eth-icon.png | Bin 984 -> 0 bytes public/file.svg | 1 - public/filter.svg | 3 - public/globe-bridge.svg | 492 -------------- public/globe-grid.png | Bin 77360 -> 0 bytes public/globe-grid.svg | 58 -- public/globe-icon.svg | 9 - public/globe.svg | 1 - public/header-globe.svg | 9 - public/hero-bg.png | Bin 1079309 -> 0 bytes public/hero-bg.svg | 261 -------- public/icons/cross.svg | 3 - public/icons/hammenu.svg | 5 - public/icons/logo.svg | 15 - public/images/assets-transfer.png | Bin 142322 -> 0 bytes public/images/centralized-icon.png | Bin 107134 -> 0 bytes public/images/ellipse-1.png | Bin 7058219 -> 0 bytes public/images/ellipse.png | Bin 4775061 -> 0 bytes public/images/liquidity-chain.png | Bin 199748 -> 0 bytes public/images/liquidity-chart.png | Bin 146035 -> 0 bytes public/images/problem.png | Bin 34213 -> 0 bytes public/images/quotes.svg | 3 - public/images/shape.svg | 43 -- public/images/shapes-1.svg | 140 ---- public/images/solution.png | Bin 23636 -> 0 bytes public/images/testimonial-card-profile.png | Bin 12720 -> 0 bytes public/images/testimonial-float-1.png | Bin 13948 -> 0 bytes public/join-community/ellipse.svg | 12 - public/join-community/grid.svg | 198 ------ public/large-grid.svg | 290 --------- public/menu-mobile.png | Bin 340 -> 0 bytes public/next.svg | 1 - public/outerBlur.svg | 12 - public/right-arrow.svg | 9 - public/scroll.svg | 9 - public/small-grid.svg | 226 ------- public/sol-icon.png | Bin 1079 -> 0 bytes public/solana.svg | 9 - public/success-state/burn1.svg | 14 - public/success-state/burn2.svg | 19 - public/success-state/lock1.svg | 9 - public/success-state/lock2.svg | 9 - public/success-state/swap1.svg | 10 - public/success-state/swap2.svg | 41 -- public/success-state/wallet1.svg | 18 - public/success-state/wallet2.svg | 18 - public/testimonial-float-2.png | Bin 2889 -> 0 bytes public/testimonial-float-3.png | Bin 3077 -> 0 bytes public/token.svg | 9 - public/topBlur.svg | 12 - public/ugo-x.svg | 15 - public/up-pointer.png | Bin 288 -> 0 bytes public/vercel.svg | 1 - public/wallet.svg | 9 - public/window.svg | 1 - public/write.svg | 9 - public/zerologo-white.png | Bin 2538 -> 0 bytes public/zerologo-white.svg | 15 - public/zerologo.png | Bin 25427 -> 0 bytes utils/cn.ts | 6 - 137 files changed, 9 insertions(+), 10349 deletions(-) delete mode 100644 app/about/page.tsx delete mode 100644 app/components/Ethereum-provider.tsx delete mode 100644 app/components/FAQ.tsx delete mode 100644 app/components/HomeNav.tsx delete mode 100644 app/components/Sidebar.tsx delete mode 100644 app/components/Starknet-provider.tsx delete mode 100644 app/components/TradingChart/Coins.tsx delete mode 100644 app/components/TradingChart/chart.tsx delete mode 100644 app/components/TradingChart/data.ts delete mode 100644 app/components/TradingChart/trading-chart.tsx delete mode 100644 app/components/about-core-problems.tsx delete mode 100644 app/components/about-header.tsx delete mode 100644 app/components/about-team.tsx delete mode 100644 app/components/about-technology.tsx delete mode 100644 app/components/about.tsx delete mode 100644 app/components/analyticgraph.tsx delete mode 100644 app/components/analytics.tsx delete mode 100644 app/components/claim-burn.tsx delete mode 100644 app/components/connectWallet.tsx delete mode 100644 app/components/deposit.tsx delete mode 100644 app/components/ethereumWallet.tsx delete mode 100644 app/components/footer.tsx delete mode 100644 app/components/header.tsx delete mode 100644 app/components/how-it-works.tsx delete mode 100644 app/components/join-community.tsx delete mode 100644 app/components/lock-liquidity.tsx delete mode 100644 app/components/lock-summary.tsx delete mode 100644 app/components/mobile-navigator.tsx delete mode 100644 app/components/navbar.tsx delete mode 100644 app/components/rippleSVG.tsx delete mode 100644 app/components/starknetWallet.tsx delete mode 100644 app/components/success-state/animated-icon.tsx delete mode 100644 app/components/success-state/success-state.tsx delete mode 100644 app/components/swap.tsx delete mode 100644 app/components/testimonial.tsx delete mode 100644 app/components/tokenclaim.tsx delete mode 100644 app/components/ui/button.tsx delete mode 100644 app/components/walletcard.tsx delete mode 100644 app/dashboard/analytics/page.tsx delete mode 100644 app/dashboard/claim-burn/page.tsx delete mode 100644 app/dashboard/lock-liquidity/page.tsx delete mode 100644 app/dashboard/swap/page.tsx delete mode 100644 app/db/schema.sql delete mode 100644 app/governance/page.tsx delete mode 100644 app/governance/voting-proposals/[id]/page.tsx delete mode 100644 app/governance/voting-proposals/page.tsx delete mode 100644 app/hooks/useRegistration.ts delete mode 100644 app/hooks/useWalletState.ts delete mode 100644 app/lock-summary/page.tsx delete mode 100644 app/success/page.tsx delete mode 100644 public/Chart.png delete mode 100644 public/Claim.png delete mode 100644 public/Cog.png delete mode 100644 public/Coins.png delete mode 100644 public/GithubLogo.svg delete mode 100644 public/Menu.png delete mode 100644 public/Notification.png delete mode 100644 public/Swap.png delete mode 100644 public/XLogo.svg delete mode 100644 public/about-header-icon.png delete mode 100644 public/about-header.png delete mode 100644 public/aboutTeamBlur.svg delete mode 100644 public/aboutTeamBlur2.svg delete mode 100644 public/arrowdownfaq.svg delete mode 100644 public/background.svg delete mode 100644 public/bell.png delete mode 100644 public/blocky.svg delete mode 100644 public/check-bg.svg delete mode 100644 public/dashboard.png delete mode 100644 public/down-pointer-desktop.png delete mode 100644 public/down-pointer.png delete mode 100644 public/eth-icon.png delete mode 100644 public/file.svg delete mode 100644 public/filter.svg delete mode 100644 public/globe-bridge.svg delete mode 100644 public/globe-grid.png delete mode 100644 public/globe-grid.svg delete mode 100644 public/globe-icon.svg delete mode 100644 public/globe.svg delete mode 100644 public/header-globe.svg delete mode 100644 public/hero-bg.png delete mode 100644 public/hero-bg.svg delete mode 100644 public/icons/cross.svg delete mode 100644 public/icons/hammenu.svg delete mode 100644 public/icons/logo.svg delete mode 100644 public/images/assets-transfer.png delete mode 100644 public/images/centralized-icon.png delete mode 100644 public/images/ellipse-1.png delete mode 100644 public/images/ellipse.png delete mode 100644 public/images/liquidity-chain.png delete mode 100644 public/images/liquidity-chart.png delete mode 100644 public/images/problem.png delete mode 100644 public/images/quotes.svg delete mode 100644 public/images/shape.svg delete mode 100644 public/images/shapes-1.svg delete mode 100644 public/images/solution.png delete mode 100644 public/images/testimonial-card-profile.png delete mode 100644 public/images/testimonial-float-1.png delete mode 100644 public/join-community/ellipse.svg delete mode 100644 public/join-community/grid.svg delete mode 100644 public/large-grid.svg delete mode 100644 public/menu-mobile.png delete mode 100644 public/next.svg delete mode 100644 public/outerBlur.svg delete mode 100644 public/right-arrow.svg delete mode 100644 public/scroll.svg delete mode 100644 public/small-grid.svg delete mode 100644 public/sol-icon.png delete mode 100644 public/solana.svg delete mode 100644 public/success-state/burn1.svg delete mode 100644 public/success-state/burn2.svg delete mode 100644 public/success-state/lock1.svg delete mode 100644 public/success-state/lock2.svg delete mode 100644 public/success-state/swap1.svg delete mode 100644 public/success-state/swap2.svg delete mode 100644 public/success-state/wallet1.svg delete mode 100644 public/success-state/wallet2.svg delete mode 100644 public/testimonial-float-2.png delete mode 100644 public/testimonial-float-3.png delete mode 100644 public/token.svg delete mode 100644 public/topBlur.svg delete mode 100644 public/ugo-x.svg delete mode 100644 public/up-pointer.png delete mode 100644 public/vercel.svg delete mode 100644 public/wallet.svg delete mode 100644 public/window.svg delete mode 100644 public/write.svg delete mode 100644 public/zerologo-white.png delete mode 100644 public/zerologo-white.svg delete mode 100644 public/zerologo.png diff --git a/app/about/page.tsx b/app/about/page.tsx deleted file mode 100644 index 95903f2..0000000 --- a/app/about/page.tsx +++ /dev/null @@ -1,25 +0,0 @@ -'use client' -import React from 'react'; -import AboutTech from '../components/about-technology'; -import AboutTeam from '../components/about-team'; -import AboutCoreProblems from "../components/about-core-problems"; -import HomeNav from '../components/HomeNav'; -import Footer from '../components/footer'; -import AboutHeader from '../components/about-header'; - -const AboutPage = () => { - return ( -
- -
- - - - -
-
-
- ); -}; - -export default AboutPage; diff --git a/app/components/Ethereum-provider.tsx b/app/components/Ethereum-provider.tsx deleted file mode 100644 index bf9e3f3..0000000 --- a/app/components/Ethereum-provider.tsx +++ /dev/null @@ -1,103 +0,0 @@ -"use client"; - -import { createContext, useContext, useEffect, useState } from "react"; -import { ethers } from "ethers"; - -interface EthereumContextType { - provider: ethers.BrowserProvider | null; - signer: ethers.JsonRpcSigner | null; - isConnected: boolean; - connectWallet: () => Promise; - address: string | null; -} - -const EthereumContext = createContext({ - provider: null, - signer: null, - isConnected: false, - connectWallet: async () => {}, - address: null, -}); - -export const EthereumProvider = ({ children }: { children: React.ReactNode }) => { - const [provider, setProvider] = useState(null); - const [signer, setSigner] = useState(null); - const [isConnected, setIsConnected] = useState(false); - const [address, setAddress] = useState(null); - - const connectWallet = async () => { - try { - if (typeof window.ethereum === "undefined") { - throw new Error("Please install MetaMask"); - } - - const provider = new ethers.BrowserProvider(window.ethereum); - await provider.send("eth_requestAccounts", []); - const signer = await provider.getSigner(); - const address = await signer.getAddress(); - - setProvider(provider); - setSigner(signer); - setAddress(address); - setIsConnected(true); - } catch (error) { - console.error("Error connecting wallet:", error); - } - }; - - useEffect(() => { - const checkConnection = async () => { - if (typeof window.ethereum !== "undefined") { - const provider = new ethers.BrowserProvider(window.ethereum); - const accounts = await provider.send("eth_accounts", []); - - if (accounts.length > 0) { - const signer = await provider.getSigner(); - const address = await signer.getAddress(); - - setProvider(provider); - setSigner(signer); - setAddress(address); - setIsConnected(true); - } - } - }; - - checkConnection(); - - // Listen for account changes - if (window.ethereum) { - window.ethereum.on("accountsChanged", () => { - checkConnection(); - }); - } - - return () => { - if (window.ethereum) { - window.ethereum.removeListener("accountsChanged", checkConnection); - } - }; - }, []); - - return ( - - {children} - - ); -}; - -export const useEthereum = () => { - const context = useContext(EthereumContext); - if (context === undefined) { - throw new Error("useEthereum must be used within an EthereumProvider"); - } - return context; -}; \ No newline at end of file diff --git a/app/components/FAQ.tsx b/app/components/FAQ.tsx deleted file mode 100644 index 404a724..0000000 --- a/app/components/FAQ.tsx +++ /dev/null @@ -1,105 +0,0 @@ -"use client"; -import { Manrope, Roboto_Serif } from "next/font/google"; -import Image from "next/image"; -import React, { useState } from "react"; - -interface FaqItem { - item: { - question: string; - answer: string; - }; - onToggle: () => void; - isOpen: boolean; -} -const manrope = Manrope({ - subsets: ["latin"], - weight: ["400", "600", "700"], -}); -const roboto = Roboto_Serif({ - subsets: ["latin"], - weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"], -}); -const FaqItem = ({ item, onToggle, isOpen }: FaqItem) => { - return ( -
-
-

- {item.question} -

- - arrowdown -
- -
-

- {item.answer} -

-
-
- ); -}; - -const FAQ = () => { - const [isOpenIndex, setIsOpenIndex] = useState(null); - const onToggle = (index: number | null) => { - setIsOpenIndex(isOpenIndex === index ? null : index); - }; - return ( -
-
-

- You have a Question You’re not clear about? -

-

- ZeroXBridge is here to answer all your questions and keep you updated. -

- - {Array(7) - .fill(null) - .map((_, index) => { - return ( - onToggle(index)} - isOpen={index === isOpenIndex} - /> - ); - })} - -
- -
-
- ); -}; - -export default FAQ; diff --git a/app/components/HomeNav.tsx b/app/components/HomeNav.tsx deleted file mode 100644 index bbdb688..0000000 --- a/app/components/HomeNav.tsx +++ /dev/null @@ -1,145 +0,0 @@ -"use client"; -import { useState } from "react"; -import Link from "next/link"; -import { Button } from "./ui/button"; -import Image from "next/image"; - - -type NavLink = { - name: string; - href: string; -}; - -const navLinks: NavLink[] = [ - { name: "About Us", href: "/about" }, - { name: "Pricing", href: "#" }, - { name: "Features", href: "#" }, - { name: "Contact Us", href: "#" }, -]; - -const HomeNav = () => { - const [isMenuOpen, setIsMenuOpen] = useState(false); - - const toggleMenu = () => { - setIsMenuOpen(!isMenuOpen); - }; - - return ( -
- -
- ); -}; - -export default HomeNav; diff --git a/app/components/Sidebar.tsx b/app/components/Sidebar.tsx deleted file mode 100644 index 03f0242..0000000 --- a/app/components/Sidebar.tsx +++ /dev/null @@ -1,53 +0,0 @@ -'use client'; -import { useState } from "react"; -import Image from "next/image"; -import Chart from "../../public/Chart.png"; -import Swap from "../../public/Swap.png"; -import Claim from "../../public/Claim.png"; -import Coins from "../../public/Coins.png"; -import Dashboard from "../../public/dashboard.png"; -import { cn } from "@/utils/cn"; -import { useTheme } from '../ThemeContext'; -import { Settings } from "lucide-react"; -import Link from "next/link"; - -const Sidebar = () => { - const { isDarkMode } = useTheme(); - const [activeTab, setActiveTab] = useState("Dashboard"); - - return ( - - ); -}; - -export default Sidebar; \ No newline at end of file diff --git a/app/components/Starknet-provider.tsx b/app/components/Starknet-provider.tsx deleted file mode 100644 index bf12b1d..0000000 --- a/app/components/Starknet-provider.tsx +++ /dev/null @@ -1,38 +0,0 @@ -"use client"; -import React from "react"; - -import { sepolia, mainnet } from "@starknet-react/chains"; -import { - StarknetConfig, - publicProvider, - argent, - braavos, - useInjectedConnectors, - voyager -} from "@starknet-react/core"; - - -export function StarknetProvider({ children }: { children: React.ReactNode }) { - const { connectors } = useInjectedConnectors({ - // Show these connectors if the user has no connector installed. - recommended: [ - argent(), - braavos(), - ], - // Hide recommended connectors if the user has any connector installed. - includeRecommended: "onlyIfNoConnectors", - // Randomize the order of the connectors. - order: "random" - }); - - return ( - - {children} - - ); -} \ No newline at end of file diff --git a/app/components/TradingChart/Coins.tsx b/app/components/TradingChart/Coins.tsx deleted file mode 100644 index a499df4..0000000 --- a/app/components/TradingChart/Coins.tsx +++ /dev/null @@ -1,146 +0,0 @@ -export const BTCIcon = () => { - return ( - - - - - ) -} - -export const BCHIcon = () => { - return ( - - - - - - ) -} - -export const ETHIcon = () => { - return ( - - - - - ) -} - -export const LTCIcon = () => { - return ( - - - - ) -} - -export const ETCIcon = () => { - return ( - - - - - ) -} - -export const XRPIcon = () => { - return ( - - - - - ) -} - -export const FCTIcon = () => { - return ( - - - - - ) -} - -export const LSKIcon = () => { - return ( - - - - - ) -} - -export const XEMIcon = () => { - return ( - - - - - ) -} - -export const USKIcon = () => { - return ( - - - - - ) -} - -export const FilterIcon = () => { - return ( - - - - - ) -} - -export const DownArrow = () => { - return ( - - - - ) -} - -export const UpArrow = () => { - return ( - - - - ) -} - -export const NotificationIcon = () => { - return ( - - - - - - - - - - - - ) -} - -export const DetailsIcon = () => { - return ( - - - - ) -} \ No newline at end of file diff --git a/app/components/TradingChart/chart.tsx b/app/components/TradingChart/chart.tsx deleted file mode 100644 index a559581..0000000 --- a/app/components/TradingChart/chart.tsx +++ /dev/null @@ -1,171 +0,0 @@ -'use client' - -import { CandlestickData, CandlestickSeries, ColorType, createChart, HistogramData, HistogramSeries, IChartApi, Time } from "lightweight-charts" -import React, { useEffect, useRef, useState } from "react" -import { DetailsIcon } from "./Coins" - -type ChartProps = { - selectedInterval: { - name: string, secondsValue: number - }, - isDarkMode: boolean -} - -const toTime = (timestamp: number): Time => timestamp as Time - -const generateMockData = () => { - const intervalInSeconds = 300; // 5 minutes - const numberOfPoints = 30 * 24 * 12; - const startTime = Date.now() / 1000 - numberOfPoints * intervalInSeconds; - const data: CandlestickData[] = []; - let previousClose = 720000; - - for (let i = 0; i < numberOfPoints; i++) { - const time = toTime(Math.floor(startTime + i * intervalInSeconds)); - const open = previousClose; - const close = open + (Math.random() - 0.5) * 2000; - const high = Math.max(open, close) + Math.random() * 1000; - const low = Math.min(open, close) - Math.random() * 1000; - - data.push({ time, open, high, low, close }); - previousClose = close; - } - return data; -}; - -export default function Chart({ selectedInterval, isDarkMode }: ChartProps) { - const chartContainerRef = useRef(null) - - const chartRef = useRef(null) - const [scrollPos, setScrollPos] = useState(0) - const [dataLength, setDataLength] = useState(0) - - useEffect(() => { - - const candleStickData = generateMockData() - setDataLength(candleStickData.length) - - const volumeData: HistogramData[] = candleStickData.map(candle => ({ - time: candle.time, - value: Math.floor(Math.random() * 100) + 30, - color: '#EFF2FC' - })) - - if (!chartContainerRef.current) return - - const chart = createChart(chartContainerRef.current, { - layout: { - background: { type: ColorType.Solid, color: 'transparent' }, - textColor: '#808080' - }, - width: chartContainerRef.current.clientWidth - 10, - height: 440, - timeScale: { - timeVisible: true, - barSpacing: 16, - borderVisible: false, - rightOffset: -4, - fixLeftEdge: true, - lockVisibleTimeRangeOnResize: true - }, - grid: { - vertLines: { visible: false }, - horzLines: { visible: true } - } - }) - - chartRef.current = chart - - const candleSeries = chart.addSeries(CandlestickSeries, { - upColor: '#CCB7FF', - downColor: '#8280FF', - borderVisible: false, - wickUpColor: '#CCB7FF', - wickDownColor: '#8280FF' - }) - - const volumeSeries = chart.addSeries(HistogramSeries, { - color: '#EFF2FC', - priceFormat: { type: 'volume' }, - priceScaleId: 'volume', // Give volume its own scale - priceLineVisible: false - }) - - // Configure the main price scale (candlesticks) - chart.priceScale('right').applyOptions({ - scaleMargins: { - top: 0.1, // Leave space at the top - bottom: 0.2 // Leave room for volume - }, - borderVisible: false - }) - - // Configure the volume scale - chart.priceScale('volume').applyOptions({ - scaleMargins: { - top: 0.9, // Position volume at the bottom - bottom: 0 // Align with bottom of chart - }, - borderVisible: false, - visible: false // Hide the volume scale - }) - - const secondsToHours = (secondsValue: number) => { - const hoursValue = secondsValue / 3600 - return hoursValue - } - - chart?.timeScale()?.setVisibleLogicalRange({ - from: candleStickData.length - (12 * (9 * secondsToHours(selectedInterval.secondsValue)) + 3), - to: candleStickData.length - }) - - candleSeries.setData(candleStickData) - volumeSeries.setData(volumeData) - - const handleRangeChange = () => { - const currentPos = chart.timeScale().scrollPosition() - setScrollPos(currentPos) - } - chart.timeScale().subscribeVisibleLogicalRangeChange(handleRangeChange) - - return () => { - chart.timeScale().unsubscribeVisibleLogicalRangeChange(handleRangeChange); - chart.remove(); - } - }, [selectedInterval]) - - const handleScrollChange = (e: React.ChangeEvent) => { - const newPos = Number(e.target.value) - setScrollPos(newPos) - - chartRef.current?.timeScale().scrollToPosition(newPos, false) - } - - return ( -
- {/* Chart Container */} -
-
- - {/* 'Scroll bar' under the chart */} -
-
- -
- -
-
- ) -} \ No newline at end of file diff --git a/app/components/TradingChart/data.ts b/app/components/TradingChart/data.ts deleted file mode 100644 index 267474b..0000000 --- a/app/components/TradingChart/data.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { JSX } from "react"; -import { BCHIcon, BTCIcon, ETCIcon, ETHIcon, FCTIcon, LSKIcon, LTCIcon, USKIcon, XEMIcon, XRPIcon } from "./Coins"; - -type CoinData = { - name: string, icon: () => JSX.Element, price: string, performance: number -} - -export const coinData: CoinData[] = [ - { - name: 'BTC', - icon: BTCIcon, - price: '721,882', - performance: -4.66 - }, - { - name: 'BCH', - icon: BCHIcon, - price: '48,782', - performance: +0.66 - }, - { - name: 'ETH', - icon: ETHIcon, - price: '22,882', - performance: -4.66 - }, - { - name: 'LTC', - icon: LTCIcon, - price: '1,882', - performance: +0.66 - }, - { - name: 'ETC', - icon: ETCIcon, - price: '721,882', - performance: -4.66 - }, - { - name: 'XRP', - icon: XRPIcon, - price: '721,882', - performance: -4.66 - }, - { - name: 'FCT', - icon: FCTIcon, - price: '721,882', - performance: +0.66 - }, - { - name: 'LSK', - icon: LSKIcon, - price: '721,882', - performance: -4.66 - }, - { - name: 'XEM', - icon: XEMIcon, - price: '721,882', - performance: -4.66 - }, - { - name: 'XEM', - icon: XEMIcon, - price: '721,882', - performance: -4.66 - }, - { - name: 'USK', - icon: USKIcon, - price: '721,882', - performance: +0.66 - }, -] \ No newline at end of file diff --git a/app/components/TradingChart/trading-chart.tsx b/app/components/TradingChart/trading-chart.tsx deleted file mode 100644 index 547bfee..0000000 --- a/app/components/TradingChart/trading-chart.tsx +++ /dev/null @@ -1,139 +0,0 @@ -'use client' - -import { useState } from "react"; -import Chart from "./chart"; -import { DownArrow, FilterIcon, NotificationIcon, UpArrow } from "./Coins"; -import { coinData } from "./data"; - -type Interval = { - name: string, secondsValue: number -} - -export default function TradingChartComponent({ isDarkMode }: { isDarkMode: boolean }){ - - const intervals: Interval[] = [ - { name: '1min', secondsValue: 60}, - { name: '5min', secondsValue: 60 * 5 }, - { name: '15min', secondsValue: 60 * 15 }, - { name: '1 hr', secondsValue: 60 * 60 }, - { name: '4 hr', secondsValue: 60 * 60 * 4 } - ] - - const [selectedInterval, setSelectedInterval] = useState(intervals[3]) - - - return ( -
-
-
-

- BTC - /IPY - -

- -
-
-

- 721,882 - -4 - -

-

- High - 725,974 -

-

- 24h Volume - 677.7 BTC -

-

- Price Alert - -

-
-
-
- {/*

1min

-

5min

-

15min

-

1 hr

-

4 hr

*/} - { - intervals.map((int, idx) => ( -

setSelectedInterval(int)} - > - {int.name} -

- )) - } -
-
- -
-
-
- -
-
-

- - - - - - - - - - Market Cap -

- -
- -
- - { - coinData.map((coinObject, index) => { - const Icon = coinObject.icon - return ( -
-
- - {coinObject.name} -
-

- - ÂĄ {coinObject.price} - - - - {coinObject.performance < 0 ? `${coinObject.performance}`:`+${coinObject.performance}`} - - - {coinObject.performance < 0 ? ( - - ) : ( - - )} - - -

-
- ) - }) - } -
-
-
- ) -} \ No newline at end of file diff --git a/app/components/about-core-problems.tsx b/app/components/about-core-problems.tsx deleted file mode 100644 index 273dd5e..0000000 --- a/app/components/about-core-problems.tsx +++ /dev/null @@ -1,167 +0,0 @@ -"use client"; -import React from "react"; -import Image from "next/image"; -import coreProblemImg from "@/public/images/problem.png"; -import coreSolutionImg from "@/public/images/solution.png"; -import Arrow from "@/public/icons/Arrow"; -import blur3 from "@/public/topBlur.svg"; // Import the blur effect SVG - -interface SectionTitleProps { - children: React.ReactNode; -} - -interface SectionTextProps { - children: React.ReactNode; -} - -interface ListItemProps { - children: React.ReactNode; -} - -interface SubListProps { - items: string[]; -} - -interface SolutionItem { - title: string; - description: string; - subItems: string[]; -} - -export const SectionTitle: React.FC = ({ children }) => ( -

- {children} -

-); - -const SectionText: React.FC = ({ children }) => ( -

- {children} -

-); - -const ListItem: React.FC = ({ children }) => ( -
  • - - {children} -
  • -); - -const SubList: React.FC = ({ items }) => ( -
      - {items.map((item, index) => ( -
    • {item}
    • - ))} -
    -); - -const AboutCoreProblems: React.FC = () => { - // Data for the component - const problems: string[] = [ - "Security vulnerabilities in centralized bridges leading to hacks and exploits", - "Inefficient capital allocation due to wrapped tokens and fragmented liquidity", - "Limited cross-chain utility of liquid staking tokens", - "High gas fees and delays in asset transfers" - ]; - - const solutionItems: SolutionItem[] = [ - { - title: "Zero-Knowledge Proofs", - description: "Instead of moving assets between chains, we use ZK-STARK proofs to verify asset ownership on Ethereum while unlocking liquidity on Starknet.", - subItems: [] - }, - { - title: "Trustless Architecture", - description: "", - subItems: [ - "Users deposit collateral on Ethereum L1.", - "ZK-STARK proof verifies the deposit without exposing sensitive data.", - "Starknet validates the proof and enables borrowing from liquidity vaults.", - "Users can immediately access trading, lending, and borrowing capabilities." - ] - }, - { - title: "Capital Efficiency", - description: "", - subItems: [ - "No wrapped tokens required.", - "Assets remain secure on Ethereum while being utilized on Starknet.", - "Liquid staking tokens can be used cross-chain without unstaking.", - "Instant settlement through proof verification." - ] - } - ]; - - return ( -
    -
    - Glow Effect -
    - - {/* Problems Section */} -
    -
    - Core Problems - - It is not a new thing that Traditional cross-chain solutions face - critical challenges such as: - -
      - {problems.map((problem, index) => ( - {problem} - ))} -
    -
    -
    -
    - Problem illustration -
    -
    -
    - - {/* Solutions Section */} -
    -
    -
    - Solution illustration -
    -
    -
    - The Solution - - There is no doubt that ZeroXBridge is solving these problems through - these innovative approaches: - -
      - {solutionItems.map((solution, index) => ( -
      - - {solution.title} - {solution.description ? `: ${solution.description}` : ""} - - {solution.subItems.length > 0 && } -
      - ))} -
    -
    -
    -
    - ); -}; - -export default AboutCoreProblems; \ No newline at end of file diff --git a/app/components/about-header.tsx b/app/components/about-header.tsx deleted file mode 100644 index 1c6d9dc..0000000 --- a/app/components/about-header.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import Image from "next/image"; -import { Button } from "./ui/button"; -import Link from "next/link"; -import { SectionTitle } from "./about-core-problems"; - -const aboutUs = { - title: 'About Us', - description: 'ZeroXBridge is more than a cross-chain solutions, it is a Revolution', - activities: [ - { - title: "OUR MISSION", - description: "We plan to revolutionize cross-chain liquidity by enabling trustless, secure asset settlement between Ethereum and Starknet without the risks of traditional bridge transfers.", - }, - { - title: "OUR VISION", - description: "We aspire to be a DeFi ecosystem where users can seamlessly access their Ethereum assets liquidity on Starknet while keeping their assets securely locked on L1.", - }, - ], -}; - -const AboutHeader = () => { - return ( -
    -
    - {aboutUs.title} -
    - -

    - {aboutUs.description} -

    - -
    -
    -
    - { - aboutUs.activities.map((item) => { - return ( -
    -

    {item.title}

    -

    {item.description}

    -
    - ) - }) - } -
    - - - -
    -
    - Glow Effect -
    -
    -
    -
    - Glow Effect -
    -
    -
    - ); -}; - -export default AboutHeader; diff --git a/app/components/about-team.tsx b/app/components/about-team.tsx deleted file mode 100644 index 6b256a9..0000000 --- a/app/components/about-team.tsx +++ /dev/null @@ -1,142 +0,0 @@ -"use client"; -import React from "react"; -import { Manrope, Roboto_Serif } from "next/font/google"; -import Image from "next/image"; -import blocky from "@/public/blocky.svg"; -import ugo from "@/public/ugo-x.svg"; -import x from "@/public/XLogo.svg"; -import github from "@/public/GithubLogo.svg"; -import blur1 from "@/public/aboutTeamBlur.svg"; -import blur2 from "@/public/aboutTeamBlur2.svg"; -import blur3 from "@/public/topBlur.svg"; - -const manrope = Manrope({ - subsets: ["latin"], - weight: ["400", "600", "700"], -}); -const roboto = Roboto_Serif({ - subsets: ["latin"], - weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"], -}); - -const AboutTeam = () => { - return ( -
    -
    - Glow Effect -
    -
    -
    - Glow Effect -
    -
    - Glow Effect -
    - -

    - Meet the Team -

    -

    - ZeroXBridge's Team leads -

    -
    -
    - ugo-x -

    Ugo-X

    -

    Blockchain Developer

    -

    Co-Founder

    - -
    -
    - blocky -

    BlockJ

    -

    Blockchain Developer

    -

    Co-Founder

    - -
    -
    -
    -
    - ); -}; - -export default AboutTeam; diff --git a/app/components/about-technology.tsx b/app/components/about-technology.tsx deleted file mode 100644 index ae2ee27..0000000 --- a/app/components/about-technology.tsx +++ /dev/null @@ -1,186 +0,0 @@ -import Image from "next/image"; -import pointer from "../../public/up-pointer.png" -import pointerdown from "../../public/down-pointer.png" -import pointerdownDesktop from "../../public/down-pointer-desktop.png" -import blur3 from "@/public/outerBlur.svg"; -import { useState } from "react"; -import { motion, AnimatePresence } from "framer-motion"; - -interface AccordionItemProps { - title: string; - description: string; - content: string[]; - isOpen: boolean; - onClick: () => void; -} - -const AccordionItem = ({ title, description, content, isOpen, onClick }: AccordionItemProps) => { - return ( -
    -
    -
    - - - {isOpen && ( - -
    - {description} -
      - { - content.map((item, index) => ( -
    • - {item} -
    • - )) - } -
    -
    -
    - )} -
    -
    - ); -}; - -const AboutTech = () => { - const [openIndex, setOpenIndex] = useState(0); - - const accordionItems = [ - { - title: "How ZeroXBridge differs", - description: "ZeroXBridge continues to stand out from others, and here are some ways:", - content: [ - "Traditional bridges fragment liquidity across multiple chains, reducing efficiency. ZeroXBridge maintains liquidity cohesion by enabling cross-chain transactions daily without worry of efficiency problems.", - "Centralized bridges introduce single point of failure and custodial risks. ZeroXBridge uses decentralized, trustless zk-STARK proof to ensure security and transparency.", - "Traditional bridges require moving assets between chains, thereby exposing them to security risks like hacks and exploits. ZeroXBridge eliminates this by keeping your collateral securely locked on Ethereum while unlocking liquidity on Starknet." - ] - }, - { - title: "What is ZK Proofs", - description: "", - content: [] - }, - { - title: "Key differences between ZeroXBridge and Traditional Bridges", - description: "", - content: [] - }, - { - title: "Security Benefits", - description: "", - content: [] - } - ]; - - return ( -
    -
    - Glow Effect -
    -
    -
    -
    -

    - Our Technology -

    -

    Terms and their explanations

    -
    - - {/* Mobile Accordion */} -
    - {accordionItems.map((item, index) => ( - setOpenIndex(openIndex === index ? -1 : index)} - /> - ))} -
    - - {/* Desktop Two Columns */} -
    - {/* Left Column - Titles */} -
    - {accordionItems.map((item, index) => ( - - ))} -
    - - {/* Right Column - Content */} -
    - {accordionItems.map((item, index) => ( -
    -

    - {item.description} -

    -
      - { - item.content.map((content, index) => ( -
    • - {content} -
    • - )) - } -
    -
    - ))} -
    -
    -
    -
    -
    - ); -}; - -export default AboutTech; \ No newline at end of file diff --git a/app/components/about.tsx b/app/components/about.tsx deleted file mode 100644 index aebb532..0000000 --- a/app/components/about.tsx +++ /dev/null @@ -1,135 +0,0 @@ -"use client"; - -import React from "react"; -import Image from "next/image"; -import { Manrope, Roboto_Serif } from "next/font/google"; -import JoinCommunity from "./join-community"; - -const manrope = Manrope({ - weight: ["700"], - subsets: ["latin"], -}); - -const robotoSerif = Roboto_Serif({ - weight: ["300"], - subsets: ["latin"], -}); - -const AboutUs = () => { - return ( -
    - {/* Eclipse Background */} -
    - Background Glow -
    - - {/* Main Section Content */} -
    - {/* Title */} -

    - ZeroXBridge is here to
    - Redefine Cross-Chain Liquidity -

    - -

    - With ZeroXBridge eliminating the vulnerabilities of traditional cross-chain solutions: -

    - -
    - {/* No Asset Transfers */} -
    -
    -
    - No Asset Transfers -
    -
    -

    - No Asset Transfers -

    -

    - Traditional bridges require moving assets between chains, exposing them - to security risks like hacks and exploits. ZeroXBridge eliminates this - by keeping your collateral securely locked on Ethereum while unlocking - liquidity on Starknet. -

    -
    -
    - - - {/* No Centralized Intermediaries */} -
    -
    - No Centralized Intermediaries -
    - -
    -

    - No Centralized Intermediaries -

    -

    - Centralized bridges introduce single points of failure and custodial risks. - ZeroXBridge uses decentralized, trustless zk-STARK proofs to ensure security - and transparency. -

    -
    -
    - -
    - - {/* No Liquidity Fragmentation */} -
    -
    - Liquidity Chain - Liquidity Chart -
    - -

    - No Liquidity Fragmentation -

    -

    - Traditional bridges fragment liquidity across multiple chains, - reducing efficiency. ZeroXBridge maintains liquidity cohesion by - enabling cross-chain transactions without moving assets. You can - make numerous transactions daily without worry of efficiency problems. -

    -
    - -
    -
    - - -
    - ); -}; - -export default AboutUs; diff --git a/app/components/analyticgraph.tsx b/app/components/analyticgraph.tsx deleted file mode 100644 index e4678f0..0000000 --- a/app/components/analyticgraph.tsx +++ /dev/null @@ -1,211 +0,0 @@ -"use client"; -import { Area, AreaChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts"; -import { useState, useEffect } from "react"; -import { FilterIcon } from "lucide-react"; - -interface DataItem { - month: string; - thisYear: number; - lastYear: number; -} - -const data: DataItem[] = [ - { month: "JAN", thisYear: 1000, lastYear: 800 }, - { month: "FEB", thisYear: 2000, lastYear: 1600 }, - { month: "MAR", thisYear: 1800, lastYear: 1800 }, - { month: "APR", thisYear: 2200, lastYear: 2000 }, - { month: "MAY", thisYear: 2400, lastYear: 2200 }, - { month: "JUN", thisYear: 3200, lastYear: 2400 }, - { month: "JUL", thisYear: 3800, lastYear: 2800 }, - { month: "AUG", thisYear: 4000, lastYear: 3000 }, - { month: "SEP", thisYear: 3800, lastYear: 3200 }, - { month: "OCT", thisYear: 3600, lastYear: 3400 }, - { month: "NOV", thisYear: 3800, lastYear: 3600 }, - { month: "DEC", thisYear: 4000, lastYear: 3800 }, -]; - -const timeRanges = ["ALL", "6M", "3M", "1M", "1W"]; - -export default function Analytictable( {isDarkMode}: {isDarkMode: boolean} ) { - const [selectedRange, setSelectedRange] = useState("ALL"); - const [filteredData, setFilteredData] = useState(data); - const [isFilterOpen, setIsFilterOpen] = useState(false); - const [isMounted, setIsMounted] = useState(false); - - // Add effect to handle client-side rendering - useEffect(() => { - setIsMounted(true); - }, []); - - const handleFilterChange = (selectedMonth: string) => { - if (selectedMonth === "ALL") { - setFilteredData(data); - } else { - const filtered = data.filter(item => item.month === selectedMonth); - setFilteredData(filtered); - } - setIsFilterOpen(false); - }; - - return ( -
    -
    -
    -
    $0.00
    -
    -100.00% (-29.51) this week
    -
    -
    - - {isFilterOpen && ( -
    - - {data.map((item) => ( - - ))} -
    - )} -
    -
    -
    -
    - -
    -
    -
    -
    - {["Total Users", "Total Projects", "Operating Status"].map((label) => ( - - ))} -
    - -
    -
    -
    - This year -
    -
    -
    - Last year -
    -
    -
    - - {/* Add explicit height to this flex container */} -
    -
    - {timeRanges.map((range) => ( - - ))} -
    - - {/* Only render chart when mounted & with explicit height */} -
    - {isMounted && ( - - - - - - - - - - - - - - - { - if (active && payload && payload.length) { - return ( -
    -
    -
    - This Year - {payload[0].value} -
    -
    - Last Year - {payload[1].value} -
    -
    -
    - ); - } - return null; - }} - /> - - -
    -
    - )} -
    -
    -
    -
    -
    -
    -
    - ); -} \ No newline at end of file diff --git a/app/components/analytics.tsx b/app/components/analytics.tsx deleted file mode 100644 index 66efa1b..0000000 --- a/app/components/analytics.tsx +++ /dev/null @@ -1,383 +0,0 @@ -import { cn } from "@/lib/utils"; -import { useState, useEffect } from "react"; -import { - LineChart, - Line, - XAxis, - YAxis, - Tooltip, - ResponsiveContainer, - PieChart, - Pie, - Cell, - CartesianGrid, -} from "recharts"; - -const DUMMY_DATA = [ - { hour: "10am", value: 85 }, - { hour: "11am", value: 45 }, - { hour: "12am", value: 90 }, - { hour: "01am", value: 55 }, - { hour: "02am", value: 30 }, - { hour: "03am", value: 85 }, - { hour: "04am", value: 15 }, - { hour: "05am", value: 95 }, - { hour: "06am", value: 90 }, - { hour: "07am", value: 120 }, -]; - -const LOCKED_ASSETS_COLORS = ["#5088FF", "#D456FD"]; -const XZB_BALANCE_COLORS = ["#9E8FFF", "#FF9000"]; - -interface AnalyticsDashboardProps { - isDarkMode: boolean; - isConnected?: boolean; -} - -export default function AnalyticsDashboard({ - isDarkMode, - isConnected = false, -}: AnalyticsDashboardProps) { - const [mounted, setMounted] = useState(false); - const [activeMetric, setActiveMetric] = useState("TVL"); - - useEffect(() => { - setMounted(true); - }, []); - - const lockedAssets = [ - { name: "ETH", value: 8000, amount: "10.5 ETH", display: "$21,000" }, - { name: "USDC", value: 5000, amount: "5000 USDC", display: "$5,000" }, - ]; - - const xzbBalance = [ - { name: "xZB 1", value: 12520, amount: "26,000 xZB", display: "$26,520" }, - { name: "xZB 2", value: 10200, amount: "10,000 xZB", display: "$10,200" }, - ]; - - if (!mounted) { - return null; - } - - const cardBg = isDarkMode ? "#21192F" : "#F8F4FF"; - const textPrimary = isDarkMode ? "text-white" : "text-[#09050E]"; - const textSecondary = isDarkMode ? "text-gray-400" : "text-[#53436D]"; - const borderColor = isDarkMode ? "border-[#614199]" : "border-[#F8F4FF]"; - const tabActiveBg = isDarkMode ? "#7D53C4" : "#ECE1FF"; - const chartGridColor = isDarkMode ? "#6B7280" : "#D1D5DB"; - const tooltipBg = isDarkMode ? "#282433" : "#FBF9FF"; - const emptyChartColor = isDarkMode ? "#8B8B8B" : "#53436D"; - - const MetricCard = ({ - title, - value, - change = null, - }: { - title: string; - value: string; - change?: number | null; - }) => ( -
    -

    {title}

    -

    ${value}

    - {change !== null && ( -

    0 ? "text-[#4AD991]" : "text-red-500" - }`} - > - {change > 0 ? "+" : ""} - {change}% (24h) -

    - )} -
    - ); - - const CustomDonut = ({ - data, - colors, - isEmpty = false, - }: { - data: { name: string; value: number }[]; - colors: string[]; - isEmpty?: boolean; - }) => ( - - - {data.map((entry, index) => ( - - ))} - - - ); - - return ( -
    -
    - - - -
    - -
    -
    -
    -
    -

    - Protocol Metrics -

    -
    - {["TVL", "Volume", "Price"].map((metric) => ( - - ))} -
    -
    - - - - - - - - - - - - - - - - -
    -
    - - {/* Right Column - Donut Charts */} -
    - {/* Locked Assets */} -
    -

    - Your Locked Assets -

    -
    - -
    - {isConnected ? ( - lockedAssets.map((asset, index) => ( -
    -
    -
    -

    - {asset.amount} -

    -

    - {asset.display} -

    -
    -
    - )) - ) : ( - <> -
    -
    -
    -

    0 xZB

    -

    $0.00

    -
    -
    -
    -
    -
    -

    0 ETH

    -

    $0.00

    -
    -
    - - )} -
    -
    -
    - - {/* xZB Balance */} -
    -

    - Your xZB Balance -

    -
    - -
    - {isConnected ? ( - xzbBalance.map((balance, index) => ( -
    -
    -
    -

    - {balance.amount} -

    -

    - {balance.display} -

    -
    -
    - )) - ) : ( - <> -
    -
    -
    -

    0 xZB

    -

    $0.00

    -
    -
    -
    -
    -
    -

    0 xZB

    -

    $0.00

    -
    -
    - - )} -
    -
    -
    -
    -
    -
    - ); -} diff --git a/app/components/claim-burn.tsx b/app/components/claim-burn.tsx deleted file mode 100644 index 50ecd1a..0000000 --- a/app/components/claim-burn.tsx +++ /dev/null @@ -1,608 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import React, { useState, useEffect } from "react"; -import { ChevronDown, Info } from "lucide-react"; -import Image from "next/image"; -import { useEthereum } from "./Ethereum-provider"; -import { ethers } from "ethers"; - -interface TokenData { - available: number; - balance: number; - usdValue: number; -} - -interface Asset { - id: string; - name: string; - symbol: string; - icon: string; - address?: string; -} - -interface XZBInterfaceProps { - tokenData: TokenData; - onClaim: (asset: string) => void; - onBurn: (amount: string, asset: string) => void; - isConnected: boolean | undefined; - isDarkMode: boolean; - isLoading?: boolean; -} - -const SAMPLE_ASSETS: Asset[] = [ - { - id: "1", - name: "Ethereum", - symbol: "ETH", - icon: "/token.svg", - address: "0x0000000000000000000000000000000000000000" // ETH address - }, - { - id: "2", - name: "USD Coin", - symbol: "USDC", - icon: "/token.svg", - address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // USDC address - }, - { - id: "3", - name: "Tether", - symbol: "USDT", - icon: "/token.svg", - address: "0xdAC17F958D2ee523a2206206994597C13D831ec7" // USDT address - }, -]; - -const XZBInterface: React.FC = ({ - tokenData, - onClaim, - onBurn, - isConnected, - isDarkMode, - isLoading, -}) => { - const [activeTab, setActiveTab] = useState<"claim" | "burn">("claim"); - const [selectedAsset, setSelectedAsset] = useState(null); - const [burnAmount, setBurnAmount] = useState(""); - const [isAssetSelectorOpen, setIsAssetSelectorOpen] = useState(false); - const [hasBurned, setHasBurned] = useState(false); - const [error, setError] = useState(null); - const [isProcessing, setIsProcessing] = useState(false); - const [userEthBalance, setUserEthBalance] = useState(null); - const [maxAmount, setMaxAmount] = useState(""); - - const { - isConnected: isEthereumConnected, - // connect: connectEthereum, - // depositAsset, - // claimTokens, - address: ethereumAddress, - provider - } = useEthereum(); - - // Reset error when tab changes - useEffect(() => { - setError(null); - }, [activeTab]); - - // Add effect to fetch ETH balance when connected - useEffect(() => { - const fetchBalance = async () => { - if (isEthereumConnected && ethereumAddress && provider) { - try { - const balance = await provider.getBalance(ethereumAddress); - const balanceInEth = ethers.formatEther(balance); - setUserEthBalance(balanceInEth); - // Set max amount slightly less than balance to account for gas - const maxForGas = Number(balanceInEth) * 0.95; // Leave 5% for gas - setMaxAmount(maxForGas.toString()); - } catch (error) { - console.error("Error fetching balance:", error); - setUserEthBalance(null); - } - } else { - setUserEthBalance(null); - setMaxAmount(""); - } - }; - - fetchBalance(); - }, [isEthereumConnected, ethereumAddress, provider]); - - const calculateRedemptionAmount = (amount: string) => { - const value = parseFloat(amount) || 0; - return (value * 0.97).toFixed(2); // 3% fee - }; - - const handleAssetSelect = (asset: Asset) => { - setSelectedAsset(asset); - setIsAssetSelectorOpen(false); - setError(null); - }; - - // Update input validation - const handleAmountChange = (e: React.ChangeEvent) => { - const value = e.target.value; - if (value === "" || /^\d*\.?\d*$/.test(value)) { // Allow empty or decimal numbers - setBurnAmount(value); - - // Clear error if amount is valid - if (selectedAsset?.symbol === "ETH" && userEthBalance) { - const inputAmount = Number(value); - const maxAllowed = Number(maxAmount); - - if (inputAmount > maxAllowed) { - setError(`Amount exceeds available balance (${Number(userEthBalance).toFixed(5)} ETH). Please enter a smaller amount.`); - } else { - setError(null); - } - } - } - }; - - // Update MAX button handler - const handleMaxClick = () => { - if (selectedAsset?.symbol === "ETH" && maxAmount) { - setBurnAmount(maxAmount); - setError(null); - } else { - setBurnAmount(tokenData.balance.toString()); - } - }; - - const handleBurn = async (amount: string, assetId: string) => { - try { - setError(null); - setIsProcessing(true); - - // Check if wallet is connected - if (!isConnected) { - throw new Error("Please connect your wallet first"); - } - - // Check if Ethereum wallet is connected for L1 - if (!isEthereumConnected || !ethereumAddress) { - try { - // await connectEthereum(); - await new Promise(resolve => setTimeout(resolve, 1000)); - - if (!isEthereumConnected || !ethereumAddress) { - throw new Error("Failed to connect Ethereum wallet"); - } - } catch (error: any) { - console.error('error', error) - throw new Error("Please connect your Ethereum wallet first"); - } - } - - if (!selectedAsset) { - throw new Error("Please select an asset first"); - } - - if (!amount || parseFloat(amount) <= 0) { - throw new Error("Please enter a valid amount"); - } - - // Determine asset type (0 for ETH, 1 for ERC20) - const assetType = selectedAsset.symbol === "ETH" ? 0 : 1; - - // Get asset address - const tokenAddress = selectedAsset.address || "0x0000000000000000000000000000000000000000"; - - // For ETH transfers, validate balance before proceeding - if (assetType === 0) { - const balance = await provider?.getBalance(ethereumAddress); - if (!balance) { - throw new Error("Could not get your ETH balance"); - } - - const amountInWei = ethers.parseEther(amount); - if (balance < amountInWei) { - const balanceInEth = ethers.formatEther(balance); - throw new Error( - `Insufficient ETH balance. You have ${Number(balanceInEth).toFixed(5)} ETH but trying to send ${amount} ETH. Please reduce the amount or add more ETH to your wallet.` - ); - } - } - - console.log("Initiating burn transaction:", { - assetType, - tokenAddress, - amount, - userAddress: ethereumAddress, - isEthereumConnected, - hasAddress: !!ethereumAddress - }); - - // Call depositAsset function - // const txHash = await depositAsset( - // assetType, - // tokenAddress, - // amount - // ); - - // console.log("Transaction hash:", txHash); - setHasBurned(true); - onBurn(amount, assetId); - } catch (error) { - console.error("Error in handleBurn:", error); - const errorMessage = error instanceof Error ? error.message : "An error occurred while burning tokens"; - setError(errorMessage); - - // If it's an insufficient funds error, add a suggestion - if (errorMessage.includes("Insufficient")) { - setTimeout(() => { - setError(errorMessage + "\n\nTip: Try reducing the amount or adding more funds to your wallet."); - }, 100); - } - } finally { - setIsProcessing(false); - } - }; - - const handleClaim = async () => { - try { - setError(null); - setIsProcessing(true); - - if (!isEthereumConnected || !ethereumAddress) { - // await connectEthereum(); - return; - } - - // await claimTokens(); - onClaim(selectedAsset?.id || ""); - } catch (error) { - console.error("Error in handleClaim:", error); - setError(error instanceof Error ? error.message : "An error occurred while claiming tokens"); - } finally { - setIsProcessing(false); - } - }; - - const handleConnect = async () => { - try { - setError(null); - setIsProcessing(true); - - if (activeTab === "claim" && !isEthereumConnected) { - // await connectEthereum(); - // Wait a bit for the connection to be established - await new Promise(resolve => setTimeout(resolve, 1000)); - - // Check if connection was successful - if (!isEthereumConnected || !ethereumAddress) { - throw new Error("Failed to connect Ethereum wallet"); - } - } - } catch (error) { - console.error("Error connecting:", error); - setError(error instanceof Error ? error.message : "An error occurred while connecting"); - } finally { - setIsProcessing(false); - } - }; - - return ( -
    - {/* Tab Buttons */} -
    - - -
    - -
    - {error && ( -
    -

    {error}

    -
    - )} - - {/* Title */} -

    - {activeTab === "claim" - ? "Claim Your xZB Tokens Now" - : "Burn Your xZB Tokens Now"} -

    - - {/* Burn First Warning */} - {activeTab === "claim" && !hasBurned && ( -
    -

    - Please burn your tokens first before claiming. This ensures proper token redemption. -

    -
    - )} - - {/* Balance Display */} -
    -

    - {activeTab === "claim" ? "Available to claim" : "xZB Balance"} -

    -

    - {activeTab === "claim" - ? tokenData.available.toLocaleString() - : tokenData.balance.toLocaleString()}{" "} - xZB -

    -

    - -${tokenData.usdValue.toLocaleString()} -

    -
    - - {activeTab === "burn" && ( -
    -

    - Enter amount to Burn - {selectedAsset?.symbol === "ETH" && userEthBalance && ( - - (Available: {Number(userEthBalance).toFixed(5)} ETH) - - )} -

    -
    - - -
    -
    - )} - - {/* Asset Selector */} -
    -

    - {activeTab === "burn" ? "Receive Asset" : "Select Asset"} -

    - - - {/* Dropdown Menu */} - {isAssetSelectorOpen && ( -
    - {SAMPLE_ASSETS.map((asset) => ( - - ))} -
    - )} -
    - - {/* Info Box */} -
    - {activeTab === "claim" ? ( -
    -

    - You will receive xZB Tokens on Starknet after claiming -

    -
    - ) : ( - <> -
    -
    - - Redemption Fee - - 3% -
    -
    - - You will receive - - {calculateRedemptionAmount(burnAmount)} ETH -
    -
    -
    - Burning xZB is irreversible and subject to a 3% redemption fee -
    - - )} - {/* Learn More */} - -
    - - {/* Action Button */} - {isConnected ? ( - - ) : ( - - )} -
    -
    - ); -}; - -export default XZBInterface; diff --git a/app/components/connectWallet.tsx b/app/components/connectWallet.tsx deleted file mode 100644 index 3da903e..0000000 --- a/app/components/connectWallet.tsx +++ /dev/null @@ -1,129 +0,0 @@ -"use client"; - -import React, { useState } from 'react'; -import { useAccount as useStarknetAccount } from '@starknet-react/core'; -import { useAccount as useEthereumAccount } from 'wagmi'; -import { X } from 'lucide-react'; -import StarknetWalletModal from './starknetWallet'; -import EthereumWalletModal from './ethereumWallet'; - -interface ConnectModalProps { - isModalOpen: boolean; - setIsModalOpen: (isModalOpen: boolean) => void; -} - -const ConnectModal: React.FC = ({ isModalOpen, setIsModalOpen }) => { - const [activeChain, setActiveChain] = useState<'ethereum' | 'starknet' | null>(null); - - const { address: starknetAddress } = useStarknetAccount(); - const { address: ethereumAddress } = useEthereumAccount(); - - const handleOverlayClick = () => { - setIsModalOpen(false); - }; - - const handleModalClick = (e: React.MouseEvent) => { - e.stopPropagation(); - }; - - const handleBack = () => { - setActiveChain(null); - }; - - return ( -
    -
    - {/* Close Button */} - - - {/* Title */} -

    - {activeChain === null - ? 'Select a Network' - : activeChain === 'ethereum' - ? 'Connect Ethereum Wallet' - : 'Connect Starknet Wallet' - } -

    - - {/* Content */} -
    - {activeChain === null ? ( -
    - {/* Ethereum Option */} - - - {/* Starknet Option */} - -
    - ) : activeChain === 'ethereum' ? ( - - ) : ( - - )} -
    -
    -
    - ); -}; - -export default ConnectModal; \ No newline at end of file diff --git a/app/components/deposit.tsx b/app/components/deposit.tsx deleted file mode 100644 index 990ab40..0000000 --- a/app/components/deposit.tsx +++ /dev/null @@ -1,170 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import React, { useState } from "react"; -import { X } from "lucide-react"; -import { -// useContract, - useAccount, - useBalance, -// useSendTransaction -} from "@starknet-react/core"; -import { useTheme } from "../ThemeContext"; -// import { uint256 } from "starknet"; - -interface DepositProps { - token: string; - onClose: () => void; -} - -const Deposit: React.FC = ({ token, onClose }) => { - const [amount, setAmount] = useState(""); - const [error, setError] = useState(""); - const { isDarkMode } = useTheme(); - - // Starknet React Hooks - const { account } = useAccount(); -// // Get contract instance -// const { contract } = useContract({ -// address: `0x${contractAddress}`, -// abi: [], // Add your contract ABI here -// }); - - // Get token balance - const { data: balance, isLoading: isLoadingBalance } = useBalance({ - address: `0x${account?.address}`, - token: `0x${token}`, - }); - -// // Add transaction to transaction manager -// const { send } = useSendTransaction({ -// calls: [ -// { -// contractAddress: contractAddress, -// entrypoint: "deposit", -// calldata: [], -// }, -// ], -// }); - -// const handleDeposit = async () => { -// if (!contract || !account) { -// setError("Please connect your wallet"); -// return; -// } - -// try { -// setError(""); - -// // Convert amount to uint256 -// const amountInWei = uint256.bnToUint256( -// BigInt(parseFloat(amount) * 10 ** 18) -// ); - -// // Update calldata with the correct values -// const tx = send([ -// { -// contractAddress: contractAddress, -// entrypoint: "deposit", -// calldata: [ -// account.address, -// amountInWei.low, -// amountInWei.high, -// ], -// }, -// ]); -// console.log('transaction result', tx); -// // Clear input and close modal -// setAmount(""); -// onClose(); - -// } catch (err) { -// setError(err instanceof Error ? err.message : "Failed to deposit"); -// } -// }; - - // Format balance for display - const formattedBalance = balance - ? parseFloat(balance.toString()) / 10 ** 18 - : "0"; - - return ( -
    - {/* Header with close button */} -
    -

    Deposit {token}

    - -
    - -
    -
    - - -
    - -
    -
    - - - Balance: {isLoadingBalance ? "Loading..." : formattedBalance} - -
    - { - // Only allow numbers and one decimal point - const value = e.target.value.replace(/[^0-9.]/g, ""); - if (value.split(".").length <= 2) { - setAmount(value); - } - }} - /> - -
    -
    - - {error && ( -

    {error}

    - )} - - -
    - ); -}; - -export default Deposit; \ No newline at end of file diff --git a/app/components/ethereumWallet.tsx b/app/components/ethereumWallet.tsx deleted file mode 100644 index e554702..0000000 --- a/app/components/ethereumWallet.tsx +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import React from 'react'; -import { useConnect } from 'wagmi'; -import { ChevronLeft } from 'lucide-react'; - -interface EthereumWalletModalProps { - onBack: () => void; -} - -const EthereumWalletModal: React.FC = ({ onBack }) => { - const { connect, connectors } = useConnect(); - - const walletIcons: Record = { - metamask: '/icons/wallets/metamask.svg', - coinbase: '/icons/wallets/coinbase-logo.svg', - walletconnect: '/icons/wallets/walletconnect.svg', - injected: '/wallet.svg', - }; - - return ( -
    - {/* Back Button */} - - - {/* Wallet List */} -
    - {connectors.map((connector: any) => ( - - ))} -
    - - {/* Help Text */} -

    - New to Ethereum?{' '} - - Learn more about wallets - -

    -
    - ); -}; - -export default EthereumWalletModal; \ No newline at end of file diff --git a/app/components/footer.tsx b/app/components/footer.tsx deleted file mode 100644 index eeef758..0000000 --- a/app/components/footer.tsx +++ /dev/null @@ -1,150 +0,0 @@ -"use client" - -import Image from 'next/image' -import Link from 'next/link' -import { Manrope } from 'next/font/google' - -const manrope = Manrope({ - subsets: ["latin"], - weight: ["400", "500", "600", "700"], -}) - -const Footer = () => { - const footerLinks = { - product: [ - { name: 'About Us', href: '/about' }, - { name: 'FAQs', href: '#' }, - { name: 'Documentation', href: '#' }, - { name: 'Prices', href: '#' }, - ], - company: [ - { name: 'Career', href: '#' }, - { name: 'Contact US', href: '#' }, - { name: 'Address', href: '#' }, - { name: 'Developers', href: '#' }, - ], - socials: [ - { name: 'Telegram', href: '#' }, - { name: 'Twitter', href: '#' }, - { name: 'Discord', href: '#' }, - { name: 'Github', href: '#' }, - ], - } - - return ( -
    - -
    -
    - ZEROXBRIDGE -
    -
    - -
    -
    - {/* Logo and Description Section */} -
    -
    -
    - ZeroXBridge Logo -
    -
    -

    - Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Nunc vulputate libero et velit interdum, ac aliquet odio - mattis. Class aptent taciti sociosqu ad litora torquent per - conubia nostra, per inceptos. -

    -
    - - {/* Links Section */} -
    -
    -

    - PRODUCT -

    -
      - {footerLinks.product.map((link) => ( -
    • - - {link.name} - -
    • - ))} -
    -
    - -
    -

    - COMPANY -

    -
      - {footerLinks.company.map((link) => ( -
    • - - {link.name} - -
    • - ))} -
    -
    - -
    -

    - SOCIALS -

    -
      - {footerLinks.socials.map((link) => ( -
    • - - {link.name} - -
    • - ))} -
    -
    -
    -
    -
    -
    - ) -} - -export default Footer \ No newline at end of file diff --git a/app/components/header.tsx b/app/components/header.tsx deleted file mode 100644 index e3a5898..0000000 --- a/app/components/header.tsx +++ /dev/null @@ -1,286 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -"use client"; - -import { useState, useEffect } from "react"; -import Image from "next/image"; -import RightArrow from "@/public/right-arrow.svg"; -import Link from "next/link"; -import { Button } from "./ui/button"; - -interface StatItem { - value: string; - label: string; - endValue: number; -} - -const STATS_DATA: StatItem[] = [ - { value: "70M+", label: "Total Transactions", endValue: 70 }, - { value: "7K+", label: "Active Users", endValue: 7 }, - { value: "20M+", label: "Total earned", endValue: 20 }, - { value: "10M+", label: "Investments", endValue: 10 }, -]; - -const NETWORK_NODES = [ - { top: "5.7%", left: "26%", translateX: "0", translateY: "0", delay: "0s" }, - { top: "6%", left: "67.7%", translateX: "0", translateY: "0", delay: "1.5s" }, - { - top: "38.5%", - left: "83.5%", - translateX: "0", - translateY: "-50%", - delay: "0.7s", - }, - { - top: "71.5%", - left: "90.9%", - translateX: "0", - translateY: "0", - delay: "2.2s", - }, - { - top: "48%", - left: "51%", - translateX: "-50%", - translateY: "0", - delay: "1.2s", - }, - { - top: "85%", - left: "19%", - translateX: "0", - translateY: "0", - delay: "2.8s", - }, - { - top: "58%", - left: "4%", - translateX: "0", - translateY: "-50%", - delay: "0.4s", - }, - { - top: "47%", - left: "9%", - translateX: "0", - translateY: "0", - delay: "3.3s", - }, - { - top: "32%", - left: "5%", - translateX: "0", - translateY: "0", - delay: "1.8s", - }, - { top: "67%", left: "46%", translateX: "0", translateY: "0", delay: "2.5s" }, - { - top: "37.5%", - left: "55.4%", - translateX: "0", - translateY: "0", - delay: "0.9s", - }, - { top: "52%", left: "77%", translateX: "0", translateY: "0", delay: "0.9s" }, - { top: "54%", left: "90%", translateX: "0", translateY: "0", delay: "3.1s" }, - { - top: "92.7%", - left: "70%", - translateX: "0", - translateY: "0", - delay: "3.1s", - }, - { top: "93%", left: "42%", translateX: "0", translateY: "0", delay: "3.1s" }, - { - top: "87%", - left: "30.5%", - translateX: "0", - translateY: "0", - delay: "3.1s", - }, - { - top: "78.4%", - left: "59.5%", - translateX: "0", - translateY: "0", - delay: "3.1s", - }, - { - top: "66.5%", - left: "28%", - translateX: "0", - translateY: "0", - delay: "3.1s", - }, -]; - -const Header = () => { - const [is4K, setIs4K] = useState(false); - const [counts, setCounts] = useState(STATS_DATA.map(() => 0)); - const [isVisible, setIsVisible] = useState(false); - - useEffect(() => { - // Check if screen is 4K or higher - const check4K = () => { - setIs4K(window.innerWidth >= 3000); - }; - - check4K(); - window.addEventListener("resize", check4K); - return () => window.removeEventListener("resize", check4K); - }, []); - - // Then in your node mapping: - // Add a small adjustment to positions for 4K screens - const getNodePosition = (node: any) => { - if (is4K) { - // Adjust position for 4K screens - fine-tune these values - return { - top: `calc(${node.top} + 0.4%)`, - left: `calc(${node.left} - 2.2%)`, - }; - } - return { top: node.top, left: node.left }; - }; - - useEffect(() => { - setIsVisible(true); - }, []); - - useEffect(() => { - if (!isVisible) return; - - const animationDuration = 2000; - const steps = 60; - const interval = animationDuration / steps; - - const animations = STATS_DATA.map((stat, index) => { - let currentStep = 0; - return setInterval(() => { - if (currentStep === steps) { - clearInterval(animations[index]); - return; - } - - setCounts((prevCounts) => { - const newCounts = [...prevCounts]; - newCounts[index] = Math.min( - Math.ceil((stat.endValue * currentStep) / steps), - stat.endValue - ); - return newCounts; - }); - - currentStep++; - }, interval); - }); - - return () => animations.forEach((interval) => clearInterval(interval)); - }, [isVisible]); - - const renderStatItem = (stat: StatItem, index: number) => ( -
    - Right Arrow -
    -
    - {counts[index]} - {stat.value.slice(-2)} -
    -
    - {stat.label} -
    -
    -
    - ); - - return ( -
    -
    -
    -
    -

    - Secure Cross-Chain Liquidity with Zero-Knowledge Proofs -

    -
    -

    - Unlock liquidity on Starknet using Ethereum collateral—no asset - transfers, -

    -

    - no wrapping, no centralized bridges. -

    -
    -
    - - - -
    -
    - -
    - {/* Spinning globe (inner element) */} -
    - Spinning Globe -
    - - {/* Static network overlay (outer element) */} -
    - Network Overlay -
    - - {/* Flashing nodes */} -
    - {NETWORK_NODES.map((node, index) => { - const position = getNodePosition(node); - return ( -
    -
    -
    - ); - })} -
    -
    -
    -
    -
    - {STATS_DATA.map(renderStatItem)} -
    -
    -
    -
    - ); -}; - -export default Header; diff --git a/app/components/how-it-works.tsx b/app/components/how-it-works.tsx deleted file mode 100644 index ff52f82..0000000 --- a/app/components/how-it-works.tsx +++ /dev/null @@ -1,195 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import React, { useState, useEffect } from 'react'; -import Image from 'next/image'; -import wallet from '../../public/wallet.svg'; -import write from '../../public/write.svg'; -import scroll from '../../public/scroll.svg'; -import token from '../../public/token.svg'; -import blur3 from "@/public/outerBlur.svg"; - -const steps = [ - { - number: 1, - title: "Connect Wallet", - image: wallet, - description: "First, you'll have to connect your wallet and then deposit collateral (ETH, USDC, STRK etc) on Ethereum L1." - }, - { - number: 2, - title: "ZK-STARK Proof", - image: write, - description: "A ZK-STARK proof verifies the deposit without exposing sensitive data." - }, - { - number: 3, - title: "STARKNET VERIFIES PROOF", - image: scroll, - description: "Starknet verifies the proof and unlocks borrowing power from liquidity vaults." - }, - { - number: 4, - title: "BORROW, LEND OR TRADE", - image: token, - description: "And that's all, you can now borrow, lend, or trade using their collateralized funds." - } -]; - -const HowItWorks = () => { - const [currentStep, setCurrentStep] = useState(0); - const [isAnimating, setIsAnimating] = useState(false); - - useEffect(() => { - const timer = setInterval(() => { - setIsAnimating(true); - setTimeout(() => { - setCurrentStep((prev) => (prev + 1) % steps.length); - setTimeout(() => { - setIsAnimating(false); - }, 500); // Allow transition to complete before removing animation class - }, 500); // Time to fade out current step - }, 5000); - - return () => clearInterval(timer); - }, []); - - const handleStepChange = (index: any) => { - if (currentStep === index || isAnimating) return; // Prevent changing during animation - setIsAnimating(true); - setTimeout(() => { - setCurrentStep(index); - setTimeout(() => { - setIsAnimating(false); - }, 500); - }, 500); - }; - - return ( -
    - {/* Background Effects */} -
    - Glow Effect -
    - - {/* For Large Screens */} - Glow Effect - -
    - {/* Section Title */} -
    -

    - How it Works -

    -

    - These easy 4 steps are all you need to Get Started -

    -
    - - {/* Content Grid */} -
    - {/* Image Section */} -
    -
    - {steps.map((step, index) => ( -
    -
    -
    - {step.title} -
    -
    -
    - ))} -
    -
    - - {/* Text Section */} -
    -
    -
    -
    - {steps[currentStep].number}. -
    -
    -

    - {steps[currentStep].title} -

    -

    - {steps[currentStep].description} -

    - - {/* Navigation Dots */} -
    - {steps.map((_, index) => ( -
    -
    -
    -
    -
    -
    -
    - - -
    - ); -}; - -export default HowItWorks; \ No newline at end of file diff --git a/app/components/join-community.tsx b/app/components/join-community.tsx deleted file mode 100644 index 2d433ea..0000000 --- a/app/components/join-community.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Manrope, Roboto_Serif } from "next/font/google"; -import Image from "next/image"; -import ellipse from "@/public/join-community/ellipse.svg"; - -const manrope = Manrope({ - weight: ["700"], - subsets: ["latin"], -}); - -const robotoSerif = Roboto_Serif({ - weight: ["400"], - subsets: ["latin"], -}); - -const JoinCommunity = () => { - return ( -
    -
    - community ellipse with blur filter -
    -
    -

    - Join Our Wonderful Community Today! -

    -

    - Stay Connected with exciting updates, do not be left out of this - revolution -

    -
    -
    - -
    -
    -
    -
    - ); -}; - - -export default JoinCommunity; \ No newline at end of file diff --git a/app/components/lock-liquidity.tsx b/app/components/lock-liquidity.tsx deleted file mode 100644 index 769934b..0000000 --- a/app/components/lock-liquidity.tsx +++ /dev/null @@ -1,146 +0,0 @@ -"use client"; -import { useAccount } from "@starknet-react/core"; -import Image from "next/image"; -import { useState } from "react"; -import Deposit from "./deposit"; - -interface LiquidityLockTableProps { - isDarkMode: boolean; - className?: string; -} - -const LiquidityLockTable = ({ - isDarkMode, - className, -}: LiquidityLockTableProps) => { - const { isConnected } = useAccount() - const [depositToken, setDepositToken] = useState('SOL'); - const [DepositModal, setDepositModal] = useState(false); - const liquidityRows = [ - { - token: "SOL", - currentPrice: "$177.08", - currentLiquidity: "$500,000", - xzTokenRate: "0.01", - }, - { - token: "SOL", - currentPrice: "$177.08", - currentLiquidity: "$500,000", - xzTokenRate: "0.01", - }, - { - token: "SOL", - currentPrice: "$177.08", - currentLiquidity: "$500,000", - xzTokenRate: "0.01", - }, - { - token: "SOL", - currentPrice: "$177.08", - currentLiquidity: "$500,000", - xzTokenRate: "0.01", - }, - { - token: "SOL", - currentPrice: "$177.08", - currentLiquidity: "$500,000", - xzTokenRate: "0.01", - }, - { - token: "SOL", - currentPrice: "$177.08", - currentLiquidity: "$500,000", - xzTokenRate: "0.01", - }, - ]; - - const showDepositModal = (token: string) => { - setDepositToken(token); - setDepositModal(true); - }; - - const handleClose = () => { - setDepositModal(false); - } - - return ( -
    -

    - Lock Liquidity by making a deposit -

    - {/* This div handles the overflow internally */} -
    - - - - - - - - - - - {liquidityRows.map((row, index) => ( - - - - - - - ))} - - -
    - Token - Current LiquidityxZB Token Rate - Lock Amount -
    - Token icon - {row.token} - - {row.currentLiquidity} -
    {row.currentPrice}
    -
    {row.xzTokenRate} - -
    - - {DepositModal && ( - - )} -
    -
    - ); -}; - -export default LiquidityLockTable; diff --git a/app/components/lock-summary.tsx b/app/components/lock-summary.tsx deleted file mode 100644 index 8041494..0000000 --- a/app/components/lock-summary.tsx +++ /dev/null @@ -1,79 +0,0 @@ -"use client" - -import { Info, X } from "lucide-react"; - -export default function LockSummary() { - - const handleInputChange = (event: React.FormEvent) => { - const target = event.currentTarget; - target.value = target.value.replace(/[^0-9.]/g, ""); - }; - - return ( -
    -
    - -

    - Lock Summary -

    - - - -
    -
    -

    Token

    -

    USDC

    -
    - -
    -

    - xZB to Receive -

    -

    0 xZB

    -
    - -
    -

    Token

    -

    Low Risk

    -
    - -
    -

    - Assets remain securely Locked on Ethereum while you use xZB on - Starknet -

    -
    - -
    - -

    Requires signatures from both Ethereum and Starknet wallets

    -
    -
    - - -
    -
    - ); -} diff --git a/app/components/mobile-navigator.tsx b/app/components/mobile-navigator.tsx deleted file mode 100644 index b73ef66..0000000 --- a/app/components/mobile-navigator.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from "react"; -import Link from "next/link"; -import { usePathname } from "next/navigation"; -import { Landmark, LayoutGrid } from "lucide-react"; -import { PiChartPieSlice, PiCoins, PiSwap } from "react-icons/pi"; -import { useTheme } from "../ThemeContext"; - -const NavigationBar = () => { - const router = usePathname(); - const {isDarkMode} = useTheme() - const currentPath = router; - - const navItems = [ - { name: "Dashboard", path: "/dashboard", icon: LayoutGrid }, - { name: "Swap", path: "/dashboard/swap", icon: PiSwap }, - { name: "Claim", path: "/dashboard/claim-burn", icon: Landmark }, - { name: "Lock", path: "/dashboard/lock-liquidity", icon: PiCoins }, - { name: "Analytics", path: "/dashboard/analytics", icon: PiChartPieSlice }, - ]; - - return ( -
    -
    - {navItems.map((item) => { - const isActive = currentPath === item.path; - const activeColor = "#A26DFF"; - const inactiveColor = isDarkMode ? "#D4D4D4" : "#53436D"; - - const IconComponent = item.icon; - - return ( - -
    - {isActive && ( -
    - )} -
    - -
    - - {item.name} - -
    - - ); - })} -
    -
    - ); -}; - -export default NavigationBar; \ No newline at end of file diff --git a/app/components/navbar.tsx b/app/components/navbar.tsx deleted file mode 100644 index 506b637..0000000 --- a/app/components/navbar.tsx +++ /dev/null @@ -1,420 +0,0 @@ -"use client"; -import { - Search, - Moon, - Sun, - Menu, - X, - SearchIcon, - Bell, - Settings, -} from "lucide-react"; -import Notification from "../../public/bell.png"; -import Image from "next/image"; -import Logo from "../../public/zerologo.png"; -import LogoWhite from "../../public/zerologo-white.svg"; -import Link from "next/link"; -import { useState } from "react"; -import { useEffect } from "react"; -import ConnectModal from "./connectWallet"; -import { useAccount } from "@starknet-react/core"; -import { useWalletState } from "../hooks/useWalletState"; -// import { useRegistration } from '../hooks/useRegistration'; - -interface NavbarProps { - isDarkMode: boolean; - toggleDarkMode: () => void; - onConnectWallet?: () => void; -} - -const Navbar: React.FC = ({ isDarkMode, toggleDarkMode }) => { - const [mobileMenuOpen, setMobileMenuOpen] = useState(false); - const [isModalOpen, setIsModalOpen] = useState(false); - const [disconnectModal, setdisconnectModalOpen] = useState(false); - const { isConnected } = useAccount(); - - const toggleMobileMenu = () => { - setMobileMenuOpen(!mobileMenuOpen); - }; - - const { - // isAnyWalletConnected, - isAllConnected, - getDisplayAddress, - ethereumAddress, - starknetAddress, - disconnectEthereum, - disconnectStarknet, - disconnectAll, - } = useWalletState(); - - // const { registerUser, isRegistering } = useRegistration(); - - // useEffect(() => { - // const handleRegistration = async () => { - // if (isAllConnected) { - // try { - // await registerUser(); - // // You could add a success notification here - // } catch (err) { - // console.error("Registration failed:", err); - // // You could add an error notification here - // } - // } - // }; - - // handleRegistration(); - // }, [isAllConnected, registerUser]); - - const handleConnectWallet = () => { - if (isAllConnected) { - // disconnectAll(); - setdisconnectModalOpen(true); - } else { - setIsModalOpen(true); - } - }; - - useEffect(() => { - if (isConnected) { - setIsModalOpen(false); - } - }, [isConnected]); - - const gradientBorder = - "bg-gradient-to-b from-[#A26DFF] to-[#A26DFF] p-[0.7px] rounded-full"; - - return ( - <> -
    - {/* Logo section with border */} - - - - - {/* Main content */} -
    -
    - {/* Search Input with gradient border */} -
    -
    -
    - -
    -
    - -
    - - {/* Notification with gradient border */} -
    -
    - bell -
    -
    -
    - - {/* Mobile menu button */} -
    - -
    - - {/* Right side controls */} -
    -
    - {/* Dark mode toggle with gradient border */} - {isDarkMode ? ( - - ) : ( - - )} -
    - - - {/* Connect Wallet button with gradient border */} -
    - -
    -
    -
    -
    - - {isModalOpen && ( -
    - {/* Backdrop */} -
    setIsModalOpen(false)} - /> - {/* Modal Content */} -
    - -
    -
    - )} - - {disconnectModal && ( -
    - {/* Backdrop */} -
    setdisconnectModalOpen(false)} - /> - {/* Modal Content */} -
    -
    - {/* Ethereum Option */} - - - {/* Starknet Option */} - - - {/* Disconnect all */} - -
    -
    -
    - )} - - {/* Mobile Menu Overlay */} -
    -
    - {/* Mobile Menu Header */} -
    - {/* Logo for mobile */} - - ZeroxBridge Logo - - - {/* Close button */} - -
    - - {/* Menu Content */} -
    - {/* Navigation Links */} - -
    -
    -
    - - ); -}; - -export default Navbar; diff --git a/app/components/rippleSVG.tsx b/app/components/rippleSVG.tsx deleted file mode 100644 index 3d89b0c..0000000 --- a/app/components/rippleSVG.tsx +++ /dev/null @@ -1,435 +0,0 @@ -"use client" - -import type React from "react" -import { useEffect, useRef } from "react" -import { motion, useAnimation } from "framer-motion" - -const GlowingSvg: React.FC = () => { - const controls1 = useAnimation() - const controls2 = useAnimation() - const controls3 = useAnimation() - const controls4 = useAnimation() - const isMounted = useRef(false) - - useEffect(() => { - // Set the component as mounted - isMounted.current = true - - // Set initial opacity states - controls1.set({ opacity: 0.2 }) - controls2.set({ opacity: 0.2 }) - controls3.set({ opacity: 0.4 }) - controls4.set({ opacity: 0.4 }) - - const startRippleSequence = async () => { - // Check if still mounted before starting each animation sequence - if (!isMounted.current) return - - try { - // Start with innermost circle (controls4) completely disappearing - await controls4.start({ - opacity: [0.8, 0.2, 0], - transition: { duration: 1, ease: "easeInOut" } - }) - - if (!isMounted.current) return - - // Second ring now pulses dramatically (appearing and fading) - await controls3.start({ - opacity: [0.6, 1, 0.2], - transition: { duration: 1.5, ease: "easeInOut" } - }) - - if (!isMounted.current) return - - // Third ring pulses next - await controls2.start({ - opacity: [0.6, 1, 0.2], - transition: { duration: 1.5, ease: "easeInOut" } - }) - - if (!isMounted.current) return - - // Outermost ring completes the ripple effect - await controls1.start({ - opacity: [0.4, 1, 0.2], - transition: { duration: 1.5, ease: "easeInOut" } - }) - - if (!isMounted.current) return - - // Reset the innermost ring to prepare for next sequence - await controls4.start({ - opacity: 0.4, - transition: { duration: 0.5, ease: "easeOut" } - }) - } catch (error) { - // Handle potential errors if component unmounts during animation - console.error("Animation error:", error) - } - } - - // Wait a bit longer to ensure DOM is fully ready - const initialTimeout = setTimeout(() => { - if (isMounted.current) { - startRippleSequence() - } - }, 500) // Increased from 100ms to 500ms - - // Then repeat it at intervals - const interval = setInterval(() => { - if (isMounted.current) { - startRippleSequence() - } - }, 6500) - - return () => { - isMounted.current = false - clearTimeout(initialTimeout) - clearInterval(interval) - } - }, []) // Removed the dependencies that might cause unnecessary re-renders - - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) -} - -export default GlowingSvg \ No newline at end of file diff --git a/app/components/starknetWallet.tsx b/app/components/starknetWallet.tsx deleted file mode 100644 index 7f7e218..0000000 --- a/app/components/starknetWallet.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ - -"use client"; - -import Image from "next/image"; -import { useState } from "react"; -import { useConnect } from "@starknet-react/core"; -import { X } from "lucide-react"; - -interface ConnectModalProps { - onBack: () => void; -} - -export default function ConnectModal({ - onBack -}: ConnectModalProps) { - // StarkNet React hooks - const { connect, connectors } = useConnect(); - - const handleModalClick = (e: React.MouseEvent) => { - e.stopPropagation(); // Prevent closing modal when clicking inside - }; - - - - return ( -
    - - {/* Modal Container */} -
    - {/* Close Button */} - - - {/* Title */} -

    - Select a wallet -

    - - {/* Subtitle */} -

    - Securely authenticate & start earning. -

    - - {/* Wallet List */} -
    - {connectors.map((wallet, idx) => ( -
    { - connect({ connector: wallet }); - onBack(); - }} - > - - - {/* Divider between wallet items, except after last one */} - {idx < connectors.length - 1 && ( -
    - )} -
    - ))} -
    -
    -
    - ); -} \ No newline at end of file diff --git a/app/components/success-state/animated-icon.tsx b/app/components/success-state/animated-icon.tsx deleted file mode 100644 index 68e20cb..0000000 --- a/app/components/success-state/animated-icon.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React, { useEffect, useState } from "react"; -import Image from "next/image"; -import wallet1 from "../../../public/success-state/wallet1.svg"; -import wallet2 from "../../../public/success-state/wallet2.svg"; -import burn1 from "../../../public/success-state/burn1.svg"; -import burn2 from "../../../public/success-state/burn2.svg"; -import swap1 from "../../../public/success-state/swap1.svg"; -import swap2 from "../../../public/success-state/swap2.svg"; -import lock1 from "../../../public/success-state/lock1.svg"; -import lock2 from "../../../public/success-state/lock2.svg"; - - - -type IconType = "claim" | "swap" | "burn" | "lock"; // Add more types as needed - -interface AnimatedIconProps { - iconType: IconType; // Type of icon set // Time between transitions (ms) -} - -const iconSets: Record = { - claim: [wallet1, wallet2], - burn: [burn1, burn2], - swap: [swap1, swap2], - lock: [lock1, lock2], -}; - -const AnimatedIcon: React.FC = ({ iconType }) => { - const icons = iconSets[iconType]; - const [currentIconIndex, setCurrentIconIndex] = useState(0); - - useEffect(() => { - const iconInterval = setInterval(() => { - setCurrentIconIndex(1); - }, 700); - - return () => clearInterval(iconInterval); // Cleanup on unmount - }, [icons]); - - return ( -
    - {`${iconType} -
    - ); -}; - -export default AnimatedIcon; \ No newline at end of file diff --git a/app/components/success-state/success-state.tsx b/app/components/success-state/success-state.tsx deleted file mode 100644 index 1be8bec..0000000 --- a/app/components/success-state/success-state.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; -import { Manrope} from "next/font/google"; -import { X } from 'lucide-react'; -import Link from 'next/link'; - -const manrope = Manrope({ - weight: ["400", "700"], - subsets: ['latin'], - preload: true -}); - -interface SuccessStateProps { - isOpen: boolean; - isDarkMode: boolean; - onClose: React.Dispatch>; - message: string; - icon: React.ReactNode; -} - -const SuccessState: React.FC = ({ - isOpen, - isDarkMode, - onClose, - message, - icon, -}) => { - if (!isOpen) return null; - - return ( -
    -
    -
    - - -
    - {icon} -
    -

    - CONGRATULATIONS! -

    - -

    - {message} -

    - - - Go to Dashboard - -
    -
    - ); -}; - -export default SuccessState; \ No newline at end of file diff --git a/app/components/swap.tsx b/app/components/swap.tsx deleted file mode 100644 index c6d7cdd..0000000 --- a/app/components/swap.tsx +++ /dev/null @@ -1,564 +0,0 @@ -"use client"; -import { useState } from "react"; -import { - ChevronDown, - Settings, - ArrowUpDown, - Wallet2, - AlarmClock, - FuelIcon, -} from "lucide-react"; -import Image from "next/image"; -import { useTheme } from "../ThemeContext"; -import { useAccount } from "@starknet-react/core"; - -const tokens = ["ETH", "SOL"]; - -const Swap = () => { - const [fromValue, setFromValue] = useState("0.00034"); - const [toValue, setToValue] = useState("5.79"); - const [fromToken, setFromToken] = useState("ETH"); - const [toToken, setToToken] = useState("SOL"); - const [showFromDropdown, setShowFromDropdown] = useState(false); - const [showToDropdown, setShowToDropdown] = useState(false); - const { isDarkMode } = useTheme(); - const {isConnected} = useAccount(); - - const handleSwap = () => { - setFromToken(toToken); - setToToken(fromToken); - setFromValue(toValue); - setToValue(fromValue); - }; - - return ( -
    - {isConnected ? ( -
    -
    -
    -

    - Swap Tokens -

    - -
    - -
    -
    -
    - setFromValue(e.target.value)} - className={`bg-transparent text-xl font-semibold w-full focus:outline-none ${ - isDarkMode ? "text-white" : "text-[#1F1333]" - }`} - /> -

    - - $3.85 USD -

    -
    - -

    - 7.04{" "} - - MAX - -

    -
    -
    - -
    - - - {showFromDropdown && ( -
    - {tokens.map((token) => ( -
    { - setFromToken(token); - setShowFromDropdown(false); - }} - > - {token} -
    - ))} -
    - )} -
    -
    -
    - -
    - -
    - -
    -
    -
    - setToValue(e.target.value)} - className={`${isDarkMode ? "text-white" : "text-[#1F1333]"} - bg-transparent text-xl font-semibold w-full focus:outline-none`} - /> -

    - - $3.9 USD (-1.24%) -

    - -
    - -

    - 0.00{" "} -

    -
    -
    - -
    - - - {showToDropdown && ( -
    - {tokens.map((token) => ( -
    { - setToToken(token); - setShowToDropdown(false); - }} - > - {token} -
    - ))} -
    - )} -
    -
    - -
    - -
    -
    -

    Price:

    -0.7785 USDT per Eth

    -
    -
    -

    Frontend Fee:

    $0

    -
    -
    - -
    -
    - {toToken} - - $70 - -
    - -
    - - -

    - ~$0.01 -

    -
    -
    - -
    -

    Advanced Option

    - -
    - - -
    - - -
    - ) : ( -
    -
    -
    -
    -

    - From -

    -

    - $10 -

    -
    - -
    - - - {showFromDropdown && ( -
    - {tokens.map((token) => ( -
    { - setFromToken(token); - setShowFromDropdown(false); - }} - > - {token} -
    - ))} -
    - )} -
    -
    -
    - -
    - -
    - -
    -
    -
    -

    To

    -

    - $70 -

    -
    - -
    - - - {showToDropdown && ( -
    - {tokens.map((token) => ( -
    { - setToToken(token); - setShowToDropdown(false); - }} - > - {token} -
    - ))} -
    - )} -
    -
    -
    - - -
    - )} -
    - ); -}; - -export default Swap; diff --git a/app/components/testimonial.tsx b/app/components/testimonial.tsx deleted file mode 100644 index c23398a..0000000 --- a/app/components/testimonial.tsx +++ /dev/null @@ -1,188 +0,0 @@ -"use client" - -import { useState, useEffect } from "react" -import Image from "next/image" -import GlowingProtractorSVG from "./rippleSVG"; - -import { motion } from 'framer-motion'; - -interface Testimonial { - id: number - content: string - author: { - name: string - image: string - } -} - -const testimonials: Testimonial[] = [ - { - id: 1, - content: - "Traditional bridges require moving assets between chains, exposing them to security risks like hacks and exploits. ZeroXBridge eliminates this by keeping your collateral securely locked on Ethereum while unlocking liquidity on Starknet.", - author: { - name: "Elon White", - image: "/images/testimonial-card-profile.png", - }, - }, - { - id: 2, - content: - "Traditional bridges require moving assets between chains, exposing them to security risks like hacks and exploits. ZeroXBridge eliminates this by keeping your collateral securely locked on Ethereum while unlocking liquidity on Starknet.", - author: { - name: "Elon White", - image: "/images/testimonial-card-profile.png", - }, - }, - { - id: 3, - content: - "Traditional bridges require moving assets between chains, exposing them to security risks like hacks and exploits. ZeroXBridge eliminates this by keeping your collateral securely locked on Ethereum while unlocking liquidity on Starknet.", - author: { - name: "Elon White", - image: "/images/testimonial-card-profile.png", - }, - } -] - -export default function Testimonial() { - const [currentSlide, setCurrentSlide] = useState(0) - - useEffect(() => { - const interval = setInterval(() => { - setCurrentSlide((prevSlide) => (prevSlide + 1) % testimonials.length) - }, 5000) - - return () => clearInterval(interval) - }, []) - - const handleManualNavigation = (index: number) => { - setCurrentSlide(index) - } - - return ( -
    - {/* Background Glow Effect */} -
    - Glow Effect -
    - - {/* Main Container */} -
    - - {/* Header */} -
    -

    - Hear what people are saying about us -

    -

    - Don't be left out of this Revolution -

    -
    - - {/* Glowing SVG Lines */} -
    - -
    - - {/* Testimonial Cards */} -
    -
    - {testimonials.map((testimonial, index) => { - const offset = (index - currentSlide + testimonials.length) % testimonials.length - let translateX = "0%" - let zIndex = 0 - let opacity = 1 - let visibilityClass = "block" // Default visible - - if (offset === 0) { - zIndex = 3 - } else if (offset === 1 || offset === testimonials.length - 1) { - translateX = offset === 1 ? "105%" : "-105%" - zIndex = 2 - opacity = 0.7 - } else { - translateX = offset === 2 ? "210%" : "-210%" - zIndex = 1 - opacity = 0.4 - } - - // Hide side cards on mobile - if (offset !== 0) { - visibilityClass = "hidden sm:block" - } - - return ( - - quotes icon -
    - {testimonial.content} -
    -
    - {testimonial.author.name} - {testimonial.author.name} -
    -
    - ) - })} - -
    -
    - - {/* Navigation Lines */} -
    - {testimonials.map((_, index) => ( - handleManualNavigation(index)} - className={`w-8 md:w-12 h-[2px] bg-gray-700`} - whileHover={{ scale: 1.1 }} - whileTap={{ scale: 0.9 }} - > - - - ))} -
    -
    -
    - ) -} \ No newline at end of file diff --git a/app/components/tokenclaim.tsx b/app/components/tokenclaim.tsx deleted file mode 100644 index cf895d4..0000000 --- a/app/components/tokenclaim.tsx +++ /dev/null @@ -1,34 +0,0 @@ -"use client"; -import { useRouter } from "next/navigation"; // Import Next.js router - -interface TokenClaimProps { - isConnected: boolean | undefined; - onConnect: () => void; - isDarkMode: boolean; -} - -export default function TokenClaim({ isConnected, onConnect, isDarkMode }: TokenClaimProps) { - const router = useRouter(); // Initialize the router - - const handleClick = () => { - if (isConnected) { - router.push("/dashboard"); //this routes to the get startedd page - } else { - onConnect(); // this connects the wallet - } - }; - - return ( -
    -
    -

    Claim/Burn XZB Tokens

    - -
    -
    - ); -} diff --git a/app/components/ui/button.tsx b/app/components/ui/button.tsx deleted file mode 100644 index 47535d2..0000000 --- a/app/components/ui/button.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils" - -const buttonVariants = cva( - "relative inline-flex items-center rounded-full justify-center font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-50", - { - variants: { - variant: { - default: "bg-[#4C327A] text-white hover:bg-opacity-90", - secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", - gradientPrimary: [ - "relative p-[2px] text-white", - "before:absolute before:inset-0 before:rounded-full", - "before:bg-[linear-gradient(20deg,#A26DFF,#4C327A,#A26DFF,#A26DFF)]", - "before:bg-[length:400%_100%]", - "before:content-[''] before:z-[0]", - "before:animate-[rotate_6s_linear_infinite]", - "after:absolute after:inset-[2px] after:rounded-full", - "after:bg-[#4C327A] after:z-[1]", - ].join(" "), - }, - size: { - default: "h-12", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } -) - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean -} - -const Button = React.forwardRef( - ({ className, variant, size, children, ...props }, ref) => { - if (variant === 'gradientPrimary') { - return ( - - ) - } - - return ( - - ) : ( -
    // Placeholder to maintain layout - )} -
    - ${balance} -
    -
    - -

    You can add another Address and also switch Addresses

    -
    -
    - ) -} - diff --git a/app/config.ts b/app/config.ts index 2804055..e69de29 100644 --- a/app/config.ts +++ b/app/config.ts @@ -1,19 +0,0 @@ -import { http, createConfig } from 'wagmi' -import { base, mainnet} from 'wagmi/chains' -import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' - -const projectId = '' - -export const config = createConfig({ - chains: [mainnet, base], - connectors: [ - injected(), - walletConnect({ projectId }), - metaMask(), - safe(), - ], - transports: { - [mainnet.id]: http(), - [base.id]: http(), - }, -}) \ No newline at end of file diff --git a/app/dashboard/analytics/page.tsx b/app/dashboard/analytics/page.tsx deleted file mode 100644 index abfe015..0000000 --- a/app/dashboard/analytics/page.tsx +++ /dev/null @@ -1,20 +0,0 @@ -'use client' -import AnalyticsDashboard from "@/app/components/analytics"; -import { useTheme } from "@/app/ThemeContext"; -import { useAccount } from "@starknet-react/core"; - - -export default function AnalyticsPage() { - const { isDarkMode } = useTheme(); - const { isConnected } = useAccount(); - return ( -
    - {/* to test out the connect state, please change isconnected to true */} - -
    - ); -} \ No newline at end of file diff --git a/app/dashboard/claim-burn/page.tsx b/app/dashboard/claim-burn/page.tsx deleted file mode 100644 index 992ed9b..0000000 --- a/app/dashboard/claim-burn/page.tsx +++ /dev/null @@ -1,189 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -"use client"; -import XZBInterface from "@/app/components/claim-burn"; -import { useTheme } from "@/app/ThemeContext"; -import { useAccount, useContract } from "@starknet-react/core"; -import { shortString } from "starknet"; -import { useReadContract } from "@starknet-react/core"; -import { useEffect, useState } from "react"; - -const Index = () => { - const { isConnected, address, account } = useAccount(); - const { isDarkMode } = useTheme(); - const [isLoading, setIsLoading] = useState(false); - const [xzbSupplyRate, setXzbSupplyRate] = useState(""); - const [dynamicRate, setDynamicRate] = useState(""); - - const tokenData = { - available: 2468, - balance: 12468, - usdValue: 2475, - }; - - // Contract address - replace with your actual deployed contract address - const contractAddress = "0x06799866e50962817ce737ed1c2611e64fdfd34a1934edd3960322e79a22fd96"; // Example address, replace with actual - - // Initialize contract - const { contract } = useContract({ - address: contractAddress, - abi: [ - { - name: "burn", - type: "function", - inputs: [ - { name: "amount", type: "felt" }, - { name: "asset", type: "felt" } - ], - outputs: [], - state_mutability: "external" - } - ] - }); - - const handleClaim = async (asset: string) => { - try { - setIsLoading(true); - // Implement claim logic here - console.log("Claiming with asset:", asset); - } catch (error) { - console.error("Error claiming:", error); - } finally { - setIsLoading(false); - } - }; - - const handleBurn = async (amount: string, asset: string) => { - try { - setIsLoading(true); - if (!address) { - throw new Error("No wallet connected"); - } - - if (!contract) { - throw new Error("Contract not initialized"); - } - - if (!account) { - throw new Error("No account available"); - } - - // Validate amount - const parsedAmount = parseFloat(amount); - if (isNaN(parsedAmount) || parsedAmount <= 0) { - throw new Error("Invalid amount"); - } - - // Convert amount to the correct format for the contract - const amountInWei = BigInt(Math.floor(parsedAmount * 1e18)).toString(); - - // Validate asset - if (!asset) { - throw new Error("No asset selected"); - } - - // Convert asset to felt - const assetFelt = shortString.encodeShortString(asset); - - // Call the burn function using the account - const result = await account.execute({ - contractAddress, - entrypoint: "burn", - calldata: [amountInWei, assetFelt] - }); - - console.log("Burn transaction:", result); - } catch (error) { - console.error("Error burning tokens:", error); - // You might want to show this error to the user - } finally { - setIsLoading(false); - } - }; - - const address1 = `0x${""}`; - - // Proper hook to read data from a Cairo function - const { - data: supplyRate, - isError, - } = useReadContract({ - address: address1, // Replace with actual contract address - abi: [ - { - // Define the ABI for the Cairo function - name: "get_current_xzb_supply", - type: "function", - state_mutability: "view", - inputs: [], - outputs: [{ type: "uint256" }], - }, - ], - functionName: "get_current_xzb_supply", - args: undefined, - watch: true, - }); - - // Function to handle the supply rate data - const getSupplyRate = () => { - if (!isLoading && !isError && supplyRate !== undefined) { - setXzbSupplyRate(supplyRate); - console.log("xzb supply rate", xzbSupplyRate); - } - }; - - const { data: dynamic_Rate } = useReadContract({ - address: address1, // Replace with actual contract address - abi: [ - { - // Define the ABI for the Cairo function - name: "get_dynamic_rate", - type: "function", - state_mutability: "view", - inputs: [], - outputs: [{ type: "uint256" }], - }, - ], - functionName: "get_dynamic_rate", - args: undefined, - watch: true, - }); - - // Function to handle the supply rate data - const getDynamicRate = () => { - if (dynamic_Rate !== undefined) { - setDynamicRate(dynamic_Rate); - console.log("xzb dynamic rate", dynamicRate); - } - }; - - // Call getSupplyRate when supplyRate changes - useEffect(() => { - getSupplyRate(); - getDynamicRate(); - }, [supplyRate, dynamicRate]); - - return ( -
    -
    - -
    -
    - ); -}; - -export default Index; diff --git a/app/dashboard/lock-liquidity/page.tsx b/app/dashboard/lock-liquidity/page.tsx deleted file mode 100644 index 60da18d..0000000 --- a/app/dashboard/lock-liquidity/page.tsx +++ /dev/null @@ -1,80 +0,0 @@ -"use client"; -import React from "react"; -import LiquidityLockTable from "@/app/components/lock-liquidity"; -import { useTheme } from "@/app/ThemeContext"; - -const LockTokens = () => { - const { isDarkMode } = useTheme(); - return ( -
    -
    -
    -

    - Lock your Ethereum Assets to receive xZB Tokens on Starknet L2 -

    -

    - All you have to do is to take the following steps -

    - -
    - {[ - { - title: "1. Select & Lock", - desc: "Choose your assets and lock amount on Ethereum L1.", - }, - { - title: "2. ZK Proof Generation", - desc: "System generates and verifies ZK proof of your deposit", - }, - { - title: "3. Receive xZB", - desc: "Get xZB tokens on Starknet based on your locked amount.", - }, - { - title: "4. Use your xZB Tokens", - desc: "Use Tokens for DeFi activities on Starknet (trade, lend & stake).", - }, - ].map((step, index) => ( -
    -
    {step.title}
    -

    - {step.desc} -

    -
    - ))} -
    - - {/* LiquidityLockTable - Ensure it takes full width */} -
    - -
    -
    -
    -
    - ); -}; - -export default LockTokens; diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index dba806e..47043df 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -1,43 +1,9 @@ -"use client"; -import React, { useState } from "react"; -import WalletCard from "../components/walletcard"; -import TokenClaim from "../components/tokenclaim"; -import Analytictable from "../components/analyticgraph"; -import LiquidityLockTable from "../components/lock-liquidity"; -import TradingChartComponent from "../components/TradingChart/trading-chart"; -import { useTheme } from '../ThemeContext'; -import { useAccount } from "@starknet-react/core"; +import { div } from 'framer-motion/client'; const DashboardPage = () => { - const {isConnected } = useAccount(); - const [balance, setBalance] = useState("-,--"); - const { isDarkMode } = useTheme(); - - const handleConnect = () => { - setBalance("1,234.56"); - }; - return ( -
    -
    -
    -
    - - -
    -
    - -
    -
    - -
    - -
    - -
    - -
    -
    +
    +

    Hello world

    ); }; diff --git a/app/dashboard/swap/page.tsx b/app/dashboard/swap/page.tsx deleted file mode 100644 index c647bdf..0000000 --- a/app/dashboard/swap/page.tsx +++ /dev/null @@ -1,17 +0,0 @@ -'use client' -import Swap from '@/app/components/swap' -import { useTheme } from '@/app/ThemeContext' -import React from 'react' - -const SwapPage = () => { - const { isDarkMode } = useTheme(); - return ( -
    - -
    - ) -} - -export default SwapPage \ No newline at end of file diff --git a/app/db/schema.sql b/app/db/schema.sql deleted file mode 100644 index 22f5803..0000000 --- a/app/db/schema.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE users ( - id SERIAL PRIMARY KEY, - eth_address VARCHAR(42) NOT NULL, - starknet_address VARCHAR(66) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - is_registered BOOLEAN DEFAULT false, - UNIQUE(eth_address), - UNIQUE(starknet_address) -); \ No newline at end of file diff --git a/app/globals.css b/app/globals.css index 91e302e..e69de29 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,221 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -/* Theme Variables */ -:root { - --background-light: #09050e; - --foreground-light: #171717; - --primary-light: #a26dff; - --purple-light: #a26dff; - --white-light: #f0f0f0; - --white-2-light: #d4d4d4; - - --background-dark: #09050e; - --foreground-dark: #09050e; - --primary-dark: #a26dff; - --purple-dark: #a26dff; - --white-dark: #1e1e1e; - --white-2-dark: #2d2d2d; - - /* Default (Light Mode) */ - --background: var(--background-light); - --foreground: var(--foreground-light); - --primary: var(--primary-light); - --purple: var(--purple-light); - --white: var(--white-light); - --white-2: var(--white-2-light); -} - -/* Dark Mode Handling */ -@media (prefers-color-scheme: dark) { - :root { - --background: #edebf0; - --foreground: #d4d4d4; - } -} - -/* Smooth Animation */ -@keyframes rotate { - from { - background-position: 0% center; - } - to { - background-position: 400% center; - } -} - -/* Base Styles */ -body { - color: var(--foreground); - background: var(--background); - font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif; -} - -/* Gradient Effects */ -.gradient-01, -.gradient-02 { - position: absolute; - width: 250px; - height: 200px; - background: var(--purple); - backdrop-filter: blur(150px); - filter: blur(130px); - transform: rotate(-114.2deg); - opacity: 1; - pointer-events: none; -} - -.gradient-01 { - right: -70px; - top: 40%; -} - -.gradient-02 { - left: -50px; - bottom: -150px; -} - -.gradient-border { - @apply bg-gradient-to-b from-[#A26DFF] to-[#A26DFF] p-[0.7px] rounded-full; -} - -/* Custom Range Slider */ -.custom-range { - @apply w-full appearance-none cursor-pointer; -} - -.custom-range::-webkit-slider-runnable-track, -.custom-range::-moz-range-track { - @apply h-6 bg-[#907DBD]; -} - -.custom-range::-webkit-slider-thumb, -.custom-range::-moz-range-thumb { - @apply w-8 h-6 bg-white rounded; - -webkit-appearance: none; - border: none; -} - -/* Footer Styling */ -.footer-gradient { - background: linear-gradient( - 180deg, - rgba(9, 5, 14, 1) 0%, - rgba(74, 42, 130, 1) 100% - ); -} - -.footer-background { - position: absolute; - inset: 0; - background: linear-gradient( - 180deg, - rgba(9, 5, 14, 1) 0%, - rgba(74, 42, 130, 1) 100% - ); - pointer-events: none; -} - -.footer-background-text { - background: linear-gradient( - 180deg, - rgba(0, 0, 0, 0.8) 0%, - rgba(74, 42, 130, 0.3) 100% - ); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; -} - -/* Custom Scrollbar - Combined and Simplified */ -.custom-scrollbar::-webkit-scrollbar { - height: 8px; - width: 8px; -} - -.custom-scrollbar::-webkit-scrollbar-track { - background: transparent; - margin: 0 4px; -} - -.custom-scrollbar::-webkit-scrollbar-thumb { - border-radius: 20px; - background: #d4c2f3; - transition: background 0.2s ease; -} - -.custom-scrollbar::-webkit-scrollbar-thumb:hover { - background: #b69fe6; -} - -.dark .custom-scrollbar::-webkit-scrollbar-thumb { - background: #3b2a65; -} - -.dark .custom-scrollbar::-webkit-scrollbar-thumb:hover { - background: #5c4a85; -} - -/* Ensure Smooth Rendering on Webkit Browsers */ -@media screen and (-webkit-min-device-pixel-ratio: 0) { - .footer-background-text { - -webkit-font-smoothing: antialiased; - } -} - -@keyframes pulse { - 0% { - transform: scale(0.8); - opacity: 0; - box-shadow: 0 0 0 0 rgba(162, 109, 255, 0.7); - } - 50% { - transform: scale(1.2); - opacity: 1; - box-shadow: 0 0 10px rgba(255, 255, 255, 0.7), 0 0 20px rgba(162, 109, 255, 0.6); - } - 100% { - transform: scale(0.8); - opacity: 0; - box-shadow: 0 0 0 0 rgba(162, 109, 255, 0); - } -} - -.shadow-glow { - box-shadow: 0 0 10px rgba(255, 255, 255, 0.7), 0 0 20px rgba(162, 109, 255, 0.6); -} - -/* Add this to your global CSS file */ - -@keyframes glow { - 0%, 100% { - filter: brightness(1) drop-shadow(0 0 2px rgba(255, 255, 255, 0.3)); - } - 20% { - filter: brightness(0.8) drop-shadow(0 0 0px rgba(255, 255, 255, 0.2)); - } - 50% { - filter: brightness(1.2) drop-shadow(0 0 4px rgba(255, 255, 255, 0.3)); - } - 70% { - filter: brightness(1.4) drop-shadow(0 0 0px rgba(255, 255, 255, 0.7)); - } -} - -.animate-glowSlow { - animation: glow 4s cubic-bezier(0.6, 0.8, 0.6, 1) infinite; -} - -/* Remove default borders from all images */ -img { - border: none !important; - outline: none !important; - box-shadow: none !important; -} - -.globe-grid-image { - border: none !important; - outline: none !important; - background: transparent !important; -} diff --git a/app/governance/page.tsx b/app/governance/page.tsx deleted file mode 100644 index a91e936..0000000 --- a/app/governance/page.tsx +++ /dev/null @@ -1,235 +0,0 @@ -import { - ArrowRight, - CheckSquare, - Coins, - Home, - Info, - MessageSquare, -} from "lucide-react"; -import Link from "next/link"; -import React from "react"; - -// Types for our data -interface Proposal { - id: string; - title: string; - status: "CLOSED"; - endedTime: string; - commentCount: number; - progressPercentage: number; -} - -export default function GovernancePage() { - // Sample data for proposals - const proposals: Proposal[] = [ - { - id: "1", - title: "Staking on Starknet V2", - status: "CLOSED", - endedTime: "3 weeks ago", - commentCount: 43, - progressPercentage: 75, - }, - { - id: "2", - title: "Test Vote", - status: "CLOSED", - endedTime: "1 month ago", - commentCount: 30, - progressPercentage: 90, - }, - { - id: "3", - title: "Termination of Transaction Versions 0,1,2.", - status: "CLOSED", - endedTime: "5 months ago", - commentCount: 181, - progressPercentage: 80, - }, - { - id: "4", - title: "Staking on Starknet", - status: "CLOSED", - endedTime: "7 months ago", - commentCount: 306, - progressPercentage: 85, - }, - { - id: "5", - title: "[TEST] Staking on Starknet test vote", - status: "CLOSED", - endedTime: "7 months ago", - commentCount: 154, - progressPercentage: 88, - }, - ]; - - return ( -
    - {/* Sidebar */} -
    -
    -
    -
    - ⚡ -
    -
    -
    - Governance Hub -
    -
    -
    -
    - -
    -
    - -

    Home

    -
    -
    - -

    Manage vSTRK

    -
    - -
    - -

    Voting Proposals

    -
    - -
    -
    - - {/* Main Content */} -
    - {/* Header */} -
    -
    - - - 🔍 - -
    - -
    - -
    - {/* Hero Section */} -
    -
    -
    - âś§ -

    - Starknet -

    -
    -

    - Governance Hub -

    -

    - Where the community propose, debate and vote on -
    - the direction of Starknet -

    -
    -
    - - {/* Stats Section */} -
    -
    -
    - -

    STRK

    -
    -
    -
    - 8,805,421 -
    -
    - STRK -
    -
    - -
    -
    - 1,418,367,970 -
    -
    - STRK L2 -
    -
    - -
    -
    1%
    -
    - vSTRK of total STRK -
    -
    -
    -
    - - {/* Proposals Section */} -
    -
    -
    -

    - Starknet voting proposals -

    -

    - Review, discuss and vote on the future of Starknet's core - protocol -

    -
    - -
    - -
    - {proposals.map((proposal) => ( -
    -
    -

    - {proposal.title} -

    -
    - -
    -
    -
    -
    - -
    - {proposal.status} -
    - -
    - Ended {proposal.endedTime} -
    - -
    - -

    {proposal.commentCount}

    -
    -
    -
    - ))} -
    -
    -
    -
    -
    - ); -} diff --git a/app/governance/voting-proposals/[id]/page.tsx b/app/governance/voting-proposals/[id]/page.tsx deleted file mode 100644 index 0dfca2a..0000000 --- a/app/governance/voting-proposals/[id]/page.tsx +++ /dev/null @@ -1,455 +0,0 @@ -'use client' -import React from "react"; -import { - ArrowLeft, - ChevronDown, - Copy, - Home, - CheckSquare, - Coins, - Share2, - ThumbsUp, - MessageCircle, - Search, - MoreHorizontal, -} from "lucide-react"; -import Link from "next/link"; - -interface Vote { - address: string; - votes: string; -} - -interface Comment { - id: string; - address: string; - time: string; - content: string; - likes: number; -} - -export default function VotingProposalPage() { - - // Mock data for the proposal - const proposal = { - id: "8", - title: "Staking on Starknet V2", - status: "CLOSED", - timestamp: "Mar 20th 2025", - address: "0x04ea...c527", - comments: 43, - votingResults: { - for: { - percentage: 89.18, - amount: "578.6M STRK" - }, - against: { - percentage: 10.82, - amount: "70.2M STRK" - }, - abstain: { - percentage: 0.01, - amount: "35.3K STRK" - }, - totalVotingPower: "102.93%", - totalVoters: "6.17%" - } - }; - - // Mock data for votes - const votes: Vote[] = [ - { address: "0x0718...73e8", votes: "61.4k votes" }, - { address: "0x0546...1db4", votes: "25.6k votes" }, - { address: "0x05e5...418d", votes: "456.8000 votes" }, - { address: "0x0386...301e", votes: "10.2k votes" }, - { address: "0x04e5...50ad", votes: "159.0000 votes" }, - { address: "0x019e...471f", votes: "202.0000 votes" }, - { address: "0x02d4...839c", votes: "10.2k votes" }, - { address: "0x0224...9dcb", votes: "101.0000 votes" }, - { address: "0x0799...de6d", votes: "201.1520 votes" }, - { address: "0x01c6...a048", votes: "14.3k votes" }, - { address: "0x0064...c512", votes: "487.6760 votes" }, - { address: "0x06fe...ff2c", votes: "1.2869 votes" }, - { address: "0x0277...5418", votes: "25.0000 votes" }, - { address: "0x02c1...2198", votes: "406.0000 votes" }, - { address: "0x008c...6308", votes: "3.5200 votes" } - ]; - - // Mock data for comments - const comments: Comment[] = [ - { - id: "1", - address: "0x04af...ef7b", - time: "4w", - content: "i vote For", - likes: 0 - }, - { - id: "2", - address: "0x04af...ef7b", - time: "4w", - content: "go go", - likes: 0 - }, - { - id: "3", - address: "0xc71f...5bc6", - time: "4w", - content: "Go-go)", - likes: 0 - } - ]; - - return ( -
    - {/* Sidebar */} -
    -
    -
    -
    - ⚡ -
    -
    -
    - Governance Hub -
    -
    ALPHA
    -
    -
    -
    - -
    - } text="Home" active={false} /> - } text="Manage vSTRK" active={false} /> - } text="Voting proposals" active={true} /> -
    -
    - - {/* Main Content */} -
    - {/* Header */} -
    -
    - - - Voting proposals - -
    -
    - - -
    - - -
    - - -
    -
    - -
    -
    - {/* Main Proposal Content */} -
    - {/* Proposal Header */} -
    -
    -
    - CLOSED -
    -
    - - • - {proposal.timestamp} - • - {proposal.comments} comments -
    -
    -

    {proposal.title}

    - -
    - - {/* Introduction */} -
    -

    Introduction

    -

    - This proposal outlines the planned upgrade to Starknet Staking v2 as can be seen in SNIP 28. - The upgrade is aimed at enhancing network security and decentralization by adding to the - current requirement that stakers run full nodes or delegate, and introducing validator block - attestation and allowing for increased validator commission. These changes are crucial steps - toward achieving a fully decentralized Starknet. -

    -

    - Staking v2 addresses two primary needs: -

    -
      -
    1. - Verifying Validator Reliability: Before entrusting validators with consensus responsibilities, it's - essential to ensure they can maintain high liveness and actively participate in the network. -
    2. -
    3. - Improving Economic Incentives: The current commission structure needs adjustments to - ensure long-term validator participation and network stability, especially as the demands on - validators increase with network growth and decentralization. -
    4. -
    -
    - - {/* Vote Details */} -
    -

    Vote Details

    -

    - A vote will be conducted to determine the approval or rejection of the following: -

    -
      -
    1. - Validator Block Attestation: Validators will be required to attest to randomly selected blocks - within each epoch. For more details, see the "Validator block attestation". -
    2. -
    3. - Validator Commission Increase: Validators will be able to commit to a maximum commission - rate. For more details, see the "Validator Commission Increase". -
    4. -
    -
    - - {/* Validator Block Attestation */} -
    -

    Validator block attestation:

    -
      -
    • - Epochs: Introduce the concept of epochs, fixed time periods where validator staking power is - determined. This ensures predictable input for the consensus algorithm. -
    • -
    • - Attestation Mechanism: Validators will be required to attest to randomly selected blocks within - each epoch. This proves their active participation and allows delegators to assess validator - reliability. -
    • -
    • - Rewards: Validators who successfully attest to blocks will receive staking rewards proportional - to their stake. Those who fail to attest will receive no rewards for that epoch. -
    • -
    -
    - Block Attestation Diagram -
    -
    - - {/* Validator Commission Increase */} -
    -

    Validator Commission Increase

    -
      -
    • - Commission Commitments and increase: Validators will be able to commit to a certain - maximum commission M, and the last date (in Epochs) that this commitment is relevant for. - Until this last date arrives, validators will not be able to increase their commission beyond M, - but can freely change their commission in the range [0,M] -
    • -
    -
    - - {/* Benefits */} -
    -

    Benefits

    -
      -
    • - Improved Validator Accountability: Attestation provides a clear metric for evaluating validator - performance. -
    • -
    • - Sustainable Validator Incentives: The potential for increased commission ensures continued - validator participation as network demands grow. -
    • -
    • - Increased Transparency: Commission commitments provide delegators with clear - expectations regarding future fees. -
    • -
    -
    - - {/* Timeline */} -
    -

    Timeline

    -
      -
    • - Q1 2025: Staking v2 deployment on testnet. -
    • -
    • - Q2 2025: Staking v2 deployment on Starknet mainnet. -
    • -
    -
    - - {/* Conclusion */} -
    -

    Conclusion

    -

    - Staking v2 represents a significant step towards a decentralized Starknet. We encourage all - community members to participate in the vote. Please vote For, Aginst or Abstain. -

    -
    - - {/* Discussion */} -
    -

    Discussion

    -
    -
    - - Comments are now closed. -
    -
    - - {/* Comments */} -
    - {comments.map(comment => ( -
    -
    -
    -
    -
    -
    {comment.address}
    -
    {comment.time}
    -
    -
    {comment.content}
    - -
    - - -
    -
    -
    -
    - ))} -
    -
    -
    - - {/* Sidebar - Voting Results */} -
    -
    -

    Final Results

    - - {/* For Votes */} -
    -
    - {proposal.votingResults.for.percentage}% FOR - {proposal.votingResults.for.amount} -
    -
    -
    -
    -
    - - {/* Against Votes */} -
    -
    - {proposal.votingResults.against.percentage}% AGAINST - {proposal.votingResults.against.amount} -
    -
    -
    -
    -
    - - {/* Abstain Votes */} -
    -
    - {proposal.votingResults.abstain.percentage}% ABSTAIN - {proposal.votingResults.abstain.amount} -
    -
    -
    -
    -
    - - {/* Total stats */} -
    -
    -
    {proposal.votingResults.totalVotingPower}
    -
    % of total voting power
    -
    -
    -
    {proposal.votingResults.totalVoters}
    -
    % of total voters
    -
    -
    - -
    - -
    - - {/* Votes List */} -

    Votes

    -
    - {votes.map((vote, index) => ( -
    -
    - -
    - {vote.address} - -
    -
    -
    - {vote.votes} - -
    -
    - ))} -
    -
    -
    -
    -
    -
    -
    - ); -} - -// Sidebar Item Component -const SidebarItem: React.FC<{ - icon: React.ReactNode; - text: string; - active: boolean; -}> = ({ icon, text, active }) => { - return ( -
    -
    - {icon} - {text} -
    -
    - ); -}; \ No newline at end of file diff --git a/app/governance/voting-proposals/page.tsx b/app/governance/voting-proposals/page.tsx deleted file mode 100644 index f8beb8b..0000000 --- a/app/governance/voting-proposals/page.tsx +++ /dev/null @@ -1,212 +0,0 @@ -import { - CheckSquare, - Coins, - Home, - MessageSquare, -} from "lucide-react"; -import React from "react"; - -// Types for our data -interface Proposal { - id: string; - title: string; - status: "CLOSED"; - endedTime: string; - commentCount: number; - progressPercentage: number; -} - -export default function GovernancePage() { - // Sample data for proposals - const proposals: Proposal[] = [ - { - id: "1", - title: "Staking on Starknet V2", - status: "CLOSED", - endedTime: "3 weeks ago", - commentCount: 43, - progressPercentage: 75, - }, - { - id: "2", - title: "Test Vote", - status: "CLOSED", - endedTime: "1 month ago", - commentCount: 30, - progressPercentage: 90, - }, - { - id: "3", - title: "Termination of Transaction Versions 0,1,2.", - status: "CLOSED", - endedTime: "5 months ago", - commentCount: 181, - progressPercentage: 80, - }, - { - id: "4", - title: "Staking on Starknet", - status: "CLOSED", - endedTime: "7 months ago", - commentCount: 306, - progressPercentage: 85, - }, - { - id: "5", - title: "[TEST] Staking on Starknet test vote", - status: "CLOSED", - endedTime: "7 months ago", - commentCount: 154, - progressPercentage: 88, - }, - { - id: "6", - title: "Staking on Starknet V2", - status: "CLOSED", - endedTime: "3 weeks ago", - commentCount: 43, - progressPercentage: 75, - }, - { - id: "7", - title: "Test Vote", - status: "CLOSED", - endedTime: "1 month ago", - commentCount: 30, - progressPercentage: 90, - }, - { - id: "8", - title: "Termination of Transaction Versions 0,1,2.", - status: "CLOSED", - endedTime: "5 months ago", - commentCount: 181, - progressPercentage: 80, - }, - { - id: "9", - title: "Staking on Starknet", - status: "CLOSED", - endedTime: "7 months ago", - commentCount: 306, - progressPercentage: 85, - }, - { - id: "10", - title: "[TEST] Staking on Starknet test vote", - status: "CLOSED", - endedTime: "7 months ago", - commentCount: 154, - progressPercentage: 88, - }, - ]; - - return ( -
    - {/* Sidebar */} -
    -
    -
    -
    - ⚡ -
    -
    -
    - Governance Hub -
    -
    -
    -
    - -
    -
    - -

    Home

    -
    -
    - -

    Manage vSTRK

    -
    -
    - -

    Voting Proposals

    -
    -
    -
    - - {/* Main Content */} -
    - {/* Header */} -
    -
    - - - 🔍 - -
    - -
    - -
    - {/* Proposals Section */} -
    -
    -
    -

    - Voting proposals -

    -

    - Starknet delegates vote to approve protocol upgrades on behalf of token holders, influencing the direction of the protocol. -

    -

    Learn more

    -
    -
    - -
    - {proposals.map((proposal) => ( -
    -
    -

    - {proposal.title} -

    -
    - -
    -
    -
    -
    - -
    - {proposal.status} -
    - -
    - Ended {proposal.endedTime} -
    - -
    - -

    {proposal.commentCount}

    -
    -
    -
    - ))} -
    -
    -
    -
    -
    - ); -} diff --git a/app/hooks/useRegistration.ts b/app/hooks/useRegistration.ts deleted file mode 100644 index 4fe21ae..0000000 --- a/app/hooks/useRegistration.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { useState } from 'react'; -import { useAccount as useStarknetAccount } from "@starknet-react/core"; -import { useAccount as useEthereumAccount, useSignMessage, useWriteContract } from "wagmi"; - -const BRIDGE_CONTRACT_ADDRESS = process.env.NEXT_PUBLIC_BRIDGE_CONTRACT_ADDRESS; - -const BRIDGE_ABI = [ - { - inputs: [ - { name: "signature", type: "bytes" }, - { name: "starknetPubKey", type: "uint256" } - ], - name: "registerUser", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - anonymous: false, - inputs: [ - { name: "user", type: "address", indexed: true }, - { name: "starknetPubKey", type: "uint256", indexed: false } - ], - name: "UserRegistered", - type: "event" - } -] as const; - -export const useRegistration = () => { - const [isRegistering, setIsRegistering] = useState(false); - const [error, setError] = useState(null); - - const { address: starknetAddress } = useStarknetAccount(); - const { address: ethereumAddress } = useEthereumAccount(); - const { signMessageAsync } = useSignMessage(); - - const { data: hash, writeContract } = useWriteContract(); - - - - const registerUser = async () => { - if (!starknetAddress || !ethereumAddress) { - setError("Please connect both Ethereum and Starknet wallets"); - return; - } - - try { - setIsRegistering(true); - setError(null); - - // 1. Get Starknet public key - const starknetPubKey = BigInt(starknetAddress); - - // 2. Create message to sign - const message = `Register Starknet wallet ${starknetAddress} for Ethereum wallet ${ethereumAddress}`; - - // 3. Sign with Ethereum wallet - const signature = await signMessageAsync({ message }); - - writeContract ({ - address: `0x${BRIDGE_CONTRACT_ADDRESS}`, - abi: BRIDGE_ABI, - functionName: 'registerUser', - args: [`0x${signature}`, starknetPubKey], - }); - - // 4. Call bridge contract - const tx = hash; - - - // 6. Register in database - const dbResponse = await fetch('/api/users', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - eth_address: ethereumAddress, - starknet_address: starknetAddress - }), - }); - - if (!dbResponse.ok) { - throw new Error('Failed to register in database'); - } - - return tx; - } catch (err) { - console.error('Registration error:', err); - setError(err instanceof Error ? err.message : "Failed to register"); - throw err; - } finally { - setIsRegistering(false); - } - }; - - return { - registerUser, - isRegistering, - error, - isReady: Boolean(starknetAddress && ethereumAddress) - }; -}; \ No newline at end of file diff --git a/app/hooks/useWalletState.ts b/app/hooks/useWalletState.ts deleted file mode 100644 index 7482f63..0000000 --- a/app/hooks/useWalletState.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { useAccount as useStarknetAccount, useDisconnect as useStarknetDisconnect } from '@starknet-react/core'; -import { useAccount as useEthereumAccount, useDisconnect as useEthereumDisconnect } from 'wagmi'; - -export const useWalletState = () => { - const { address: starknetAddress, isConnected: isStarknetConnected } = useStarknetAccount(); - const { address: ethereumAddress, isConnected: isEthereumConnected } = useEthereumAccount(); - const { disconnect: disconnectStarknet } = useStarknetDisconnect(); - const { disconnect: disconnectEthereum } = useEthereumDisconnect(); - - const disconnectAll = () => { - if (isStarknetConnected) disconnectStarknet(); - if (isEthereumConnected) disconnectEthereum(); - }; - - const getDisplayAddress = () => { - if (starknetAddress && ethereumAddress) { - return `${starknetAddress.substring(0, 6)}...${starknetAddress.slice(-4)}`; - } - if (starknetAddress) { - return `${starknetAddress.substring(0, 6)}...${starknetAddress.slice(-4)}`; - } - if (ethereumAddress) { - return `${ethereumAddress.substring(0, 6)}...${ethereumAddress.slice(-4)}`; - } - return "Connect Wallet"; - }; - - return { - starknetAddress, - ethereumAddress, - isStarknetConnected, - isEthereumConnected, - disconnectAll, - getDisplayAddress, - disconnectEthereum, - disconnectStarknet, - isAnyWalletConnected: isStarknetConnected || isEthereumConnected, - isAllConnected: isStarknetConnected && isEthereumConnected - }; -}; \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index 6a7cb25..e69de29 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,106 +0,0 @@ -"use client"; -import { usePathname } from "next/navigation"; -import { Geist, Geist_Mono, Manrope, Roboto_Serif } from "next/font/google"; -import "./globals.css"; -import Sidebar from "./components/Sidebar"; -import { ThemeProvider, useTheme } from "./ThemeContext"; -import Navbar from "./components/navbar"; -import NavigationBar from "./components/mobile-navigator"; -import { StarknetProvider } from "./components/Starknet-provider"; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { WagmiProvider } from 'wagmi' -import { config } from './config' - -// 2. Set up a React Query client. -const queryClient = new QueryClient() - - -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - -const manrope = Manrope({ - variable: "--font-manrope", - subsets: ["latin"], - weight: ["200", "300", "400", "500", "600", "700", "800"], -}); - -const robotoSerif = Roboto_Serif({ - variable: "--font-roboto-serif", - subsets: ["latin"], - weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"], -}); - -// export const metadata: Metadata = { -// title: "Create Next App", -// description: "Generated by create next app", -// }; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - const pathname = usePathname(); - const showSidebar = - pathname === "/dashboard" || pathname.startsWith("/dashboard/"); - - return ( - - - - - - - {children} - - - - - - - ); -} - -function LayoutContent({ - children, - showSidebar, -}: { - children: React.ReactNode; - showSidebar: boolean; -}) { - const { isDarkMode, toggleDarkMode } = useTheme(); - - return ( - <> - {showSidebar && ( - - )} -
    - {showSidebar && } -
    -
    - {children} -
    - {showSidebar && } -
    -
    - - ); -} diff --git a/app/lock-summary/page.tsx b/app/lock-summary/page.tsx deleted file mode 100644 index 5bf45eb..0000000 --- a/app/lock-summary/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import LockSummary from "../components/lock-summary"; - -export default function Page() { - return ( -
    - - -
    - ); -} diff --git a/app/page.tsx b/app/page.tsx index 4b2828c..6969bad 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,24 +1,9 @@ -"use client"; -import AboutUs from "./components/about"; -import FAQ from "./components/FAQ"; -import Footer from "./components/footer"; -import Header from "./components/header"; -import HomeNav from "./components/HomeNav"; -import HowItWorks from "./components/how-it-works"; -import Testimonial from "./components/testimonial"; - -export default function Home() { +const App = () => { return ( -
    - -
    -
    - - - - -
    -
    -
    - {/* First Row - Chart and Color/Token Representation */} +
    + {/* First Row - Chart and Legend */}
    {/* Left Column - Donut Chart with Lock Icon */}
    @@ -51,23 +43,22 @@ export default function AssetPieChart() { - {/* Lock Icon in Center */}
    - +
    - {/* Right Column - Color and Token Representation */} -
    + {/* Right Column - Legend */} +
    {assetData.map((asset, index) => ( -
    +
    - + {asset.name}
    @@ -75,25 +66,21 @@ export default function AssetPieChart() {
    - {/* Second Row - Token, Price, and Percentage */} -
    + {/* Second Row - Asset Details */} +
    {assetData.map((asset, index) => ( -
    +
    - + {asset.name}
    -
    -
    -
    - ${asset.price.toFixed(2)} -
    +
    +
    + ${asset.value.toLocaleString()}
    -
    -
    - {asset.percentage.toFixed(1)}% -
    +
    + {asset.percentage}%
    @@ -102,4 +89,4 @@ export default function AssetPieChart() {
    ); -} \ No newline at end of file +} \ No newline at end of file diff --git a/app/dapp/components/analytics/ChartCard.tsx b/app/dapp/components/analytics/ChartCard.tsx index e306f7d..5d05e45 100644 --- a/app/dapp/components/analytics/ChartCard.tsx +++ b/app/dapp/components/analytics/ChartCard.tsx @@ -1,13 +1,21 @@ -"use client" +"use client"; -import type React from "react" -import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid } from "recharts" +import type React from "react"; +import { + LineChart, + Line, + XAxis, + YAxis, + Tooltip, + ResponsiveContainer, + CartesianGrid, +} from "recharts"; interface ChartCardProps { - selectedChart: "tvl" | "volume" | "price" - onChartChange: (chart: "tvl" | "volume" | "price") => void - theme: string - currentPrice?: string; + selectedChart: "tvl" | "volume" | "price"; + onChartChange: (chart: "tvl" | "volume" | "price") => void; + theme: string; + currentPrice?: string; priceChange?: string; } @@ -34,11 +42,16 @@ function SmallLogo({ className, ...props }: React.SVGProps) { - + - ) + ); } // Mock data for different chart types with the exact dates and values @@ -49,8 +62,8 @@ const chartData = { { time: "Jan 27", value: 10000 }, { time: "Jan 28", value: 5000 }, { time: "Jan 29", value: 1000 }, - { time: "Jan 30", value: 0 }, - { time: "Jan 31", value: 50000 }, + { time: "Jan 30", value: 1000 }, + { time: "Jan 31", value: 150000 }, { time: "Feb 1", value: 150000 }, ], volume: [ @@ -59,7 +72,7 @@ const chartData = { { time: "Jan 27", value: 10000 }, { time: "Jan 28", value: 5000 }, { time: "Jan 29", value: 1000 }, - { time: "Jan 30", value: 0 }, + { time: "Jan 30", value: 1000 }, { time: "Jan 31", value: 50000 }, { time: "Feb 1", value: 150000 }, ], @@ -73,7 +86,7 @@ const chartData = { { time: "Jan 31", value: 50000 }, { time: "Feb 1", value: 150000 }, ], -} +}; const chartConfig = { tvl: { @@ -91,32 +104,45 @@ const chartConfig = { color: "#ffc658", format: (value: number) => `$${(value / 1000).toFixed(0)}K`, }, -} +}; -export default function ChartCard({ selectedChart, onChartChange, theme, currentPrice, priceChange }: ChartCardProps) { - const lineColor = theme === 'dark' ? '#fff' : '#000'; - console.log('ChartCard theme:', theme, 'lineColor:', lineColor); - const axisAndGridColor = '#888'; +export default function ChartCard({ + selectedChart, + onChartChange, + theme, + currentPrice, + priceChange, +}: ChartCardProps) { + const lineColor = theme === "dark" ? "#fff" : "#000"; + console.log("ChartCard theme:", theme, "lineColor:", lineColor); + const axisAndGridColor = theme === "dark" ? "#444" : "#e5e5e5"; + const textColor = theme === "dark" ? "#999" : "#999"; - const currentData = chartData[selectedChart] - const config = chartConfig[selectedChart] + const currentData = chartData[selectedChart]; + const config = chartConfig[selectedChart]; return (
    -
    +
    -

    ZeroXBridge (xZB)

    +

    + ZeroXBridge (xZB) +

    -

    {currentPrice || "$1.1392"}

    - {priceChange || "+2.38%"} +

    + {currentPrice || "$1.1392"} +

    + + {priceChange || "+2.38%"} +
    -
    +
    {(["tvl", "volume", "price"] as const).map((chart) => (
    -
    +
    - - + + { - if (value === 0) return "0" - if (value >= 100000) return `$${(value / 1000).toFixed(0)}K` - if (value >= 1000) return `$${(value / 1000).toFixed(0)}K` - return `$${value}` + if (value === 0) return "0"; + if (value >= 100000) return `$${(value / 1000).toFixed(0)}K`; + if (value >= 1000) return `$${(value / 1000).toFixed(0)}K`; + return `$${value}`; + }} + domain={['dataMin', 'dataMax']} + tickCount={6} + /> + [config.format(value), config.label]} + labelStyle={{ color: theme === "dark" ? "#fff" : "#000" }} + contentStyle={{ + backgroundColor: theme === "dark" ? "#1a1a1a" : "#fff", + border: `1px solid ${theme === "dark" ? "#333" : "#e5e5e5"}`, + borderRadius: "8px", + fontSize: "12px" }} - ticks={[0, 1000, 5000, 10000, 100000, 250000]} /> - config.format(value)} />
    - ) + ); } \ No newline at end of file diff --git a/app/dapp/components/analytics/StatsOverview.tsx b/app/dapp/components/analytics/StatsOverview.tsx index 12d279b..de7f029 100644 --- a/app/dapp/components/analytics/StatsOverview.tsx +++ b/app/dapp/components/analytics/StatsOverview.tsx @@ -1,10 +1,9 @@ "use client"; - interface Stat { id: string; - title: string; - value: string; + title: string; + value: string; } interface StatsOverviewProps { @@ -14,24 +13,29 @@ interface StatsOverviewProps { export default function StatsOverview({ stats }: StatsOverviewProps) { return (
    - {stats.map((stat) => ( -
    -
    -

    - {stat.title} -

    -

    - {stat.value} -

    -
    -
    + {stats.map((stat) => ( +
    +
    +

    + {stat.title} +

    +

    + {stat.value} +

    +
    +
    ))}
    ); -} \ No newline at end of file +} From ca5278813ad69df4eabd8f37284b95d8b4e8ebe8 Mon Sep 17 00:00:00 2001 From: Yakshit Agarwal <153830716+YakshitAgarwal@users.noreply.github.com> Date: Wed, 20 Aug 2025 01:02:34 +0530 Subject: [PATCH 25/58] Lock tokens page responsive (#162) * Lock tokens page responsive * Changes done --- app/dapp/components/lock-tokens.tsx | 132 +++++++++--------- app/dapp/components/token-select-dropdown.tsx | 30 ++-- .../components/ui/ConnectWalletButton.tsx | 70 +++++----- app/dapp/lock-tokens/page.tsx | 8 +- 4 files changed, 125 insertions(+), 115 deletions(-) diff --git a/app/dapp/components/lock-tokens.tsx b/app/dapp/components/lock-tokens.tsx index 6455074..8063257 100644 --- a/app/dapp/components/lock-tokens.tsx +++ b/app/dapp/components/lock-tokens.tsx @@ -1,53 +1,53 @@ -'use client'; +"use client"; -import { useState } from 'react'; -import { Menu, Info } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { Card, CardContent } from '@/components/ui/card'; -import { TokenSelectDropdown } from '@/app/dapp/components/token-select-dropdown'; -import { SuccessModal } from '@/app/dapp/components/success-modal'; -import type { Token, LockTransaction } from '@/types/token'; -import { ConnectWalletButton } from './ui/ConnectWalletButton'; -import { useWallet } from '@/app/hooks'; +import { useState } from "react"; +import { Menu, Info } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Card, CardContent } from "@/components/ui/card"; +import { TokenSelectDropdown } from "@/app/dapp/components/token-select-dropdown"; +import { SuccessModal } from "@/app/dapp/components/success-modal"; +import type { Token, LockTransaction } from "@/types/token"; +import { ConnectWalletButton } from "./ui/ConnectWalletButton"; +import { useWallet } from "@/app/hooks"; // Mock token data const mockTokens: Token[] = [ { - symbol: 'ETH', - name: 'Ethereum', - icon: '⟠', + symbol: "ETH", + name: "Ethereum", + icon: "⟠", price: 3193.21, liquidity: 1391195483.0, xzbRate: 1.29, - riskLevel: 'Low Risk', + riskLevel: "Low Risk", balance: 391.12, }, { - symbol: 'BTC', - name: 'Bitcoin', - icon: '₿', + symbol: "BTC", + name: "Bitcoin", + icon: "₿", price: 45000.0, liquidity: 2500000000.0, xzbRate: 1.15, - riskLevel: 'Low Risk', + riskLevel: "Low Risk", balance: 2.5, }, { - symbol: 'USDC', - name: 'USD Coin', - icon: '$', + symbol: "USDC", + name: "USD Coin", + icon: "$", price: 1.0, liquidity: 500000000.0, xzbRate: 0.95, - riskLevel: 'High Risk', + riskLevel: "High Risk", balance: 10000.0, }, ]; const TokenLockInterface = () => { const [selectedToken, setSelectedToken] = useState(null); - const [amount, setAmount] = useState(''); + const [amount, setAmount] = useState(""); const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false); const [lastTransaction, setLastTransaction] = useState(null); @@ -73,21 +73,21 @@ const TokenLockInterface = () => { amount: numAmount, token: selectedToken, xzbReceived, - timestamp: new Date().toLocaleString('en-US', { - day: '2-digit', - month: 'long', - year: 'numeric', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', + timestamp: new Date().toLocaleString("en-US", { + day: "2-digit", + month: "long", + year: "numeric", + hour: "2-digit", + minute: "2-digit", + second: "2-digit", hour12: true, }), - txHash: '0x' + Math.random().toString(16).substr(2, 64), + txHash: "0x" + Math.random().toString(16).substr(2, 64), }; setLastTransaction(transaction); setIsSuccessModalOpen(true); - setAmount(''); + setAmount(""); } }; @@ -95,31 +95,31 @@ const TokenLockInterface = () => { if (selectedToken && amount) { return (Number.parseFloat(amount) * selectedToken.xzbRate).toFixed(0); } - return '0'; + return "0"; }; return (
    -
    +
    -
    +
    - +
    { tokens={mockTokens} /> -
    -
    +
    +
    setAmount(e.target.value)} - placeholder='0.00' + placeholder="0.00" className={`!text-4xl no-spinner font-light border-none outline-none shadow-none focus:outline-none focus-visible:outline-none ring-0 focus:ring-0 p-0 h-12 !bg-transparent dark:text-[#FFF] dark:placeholder-gray-500 text-[#878787] placeholder-gray-400`} disabled={!isConnected || !selectedToken} /> @@ -156,11 +156,11 @@ const TokenLockInterface = () => {
    - Available Balance: - + Available Balance: + {selectedToken ? `${selectedToken.balance} ${selectedToken.symbol}` - : '-- xZB'} + : "-- xZB"}
    @@ -168,8 +168,8 @@ const TokenLockInterface = () => {
    -
    -
    +
    +
    Token Price: @@ -178,11 +178,11 @@ const TokenLockInterface = () => { > {selectedToken ? `$${selectedToken.price.toLocaleString()}` - : '$--'} + : "$--"}
    -
    +
    Current Liquidity @@ -191,23 +191,23 @@ const TokenLockInterface = () => { > {selectedToken ? `$${selectedToken.liquidity.toLocaleString()}` - : '$--'} + : "$--"}
    -
    +
    xZB Token Rate: - {selectedToken ? `$${selectedToken.xzbRate}` : '$--'} + {selectedToken ? `$${selectedToken.xzbRate}` : "$--"}
    {selectedToken && amount && ( -
    +
    {"You'll receive:"} @@ -222,19 +222,19 @@ const TokenLockInterface = () => {
    -
    +

    When you lock {selectedToken.symbol} tokens, you receive xZB - tokens which can be burnt to release your locked{' '} + tokens which can be burnt to release your locked{" "} {selectedToken.symbol}.

    )} -
    +
    {isConnected ? ( ) : ( )} diff --git a/app/dapp/components/token-select-dropdown.tsx b/app/dapp/components/token-select-dropdown.tsx index 94b1fac..c3bb25e 100644 --- a/app/dapp/components/token-select-dropdown.tsx +++ b/app/dapp/components/token-select-dropdown.tsx @@ -26,12 +26,14 @@ export function TokenSelectDropdown({ + className={`w-64 dark:bg-gray-800 dark:border-gray-700 bg-white border-gray-200`} + > {tokens.map((token) => ( onTokenSelect(token)} - className={`flex items-center gap-3 p-3 dark:text-white hover:bg-gray-50 text-gray-900`}> + className={`flex items-center gap-3 p-3 dark:text-white hover:bg-gray-50 text-gray-900`} + >
    + className={`w-8 h-8 rounded-full flex items-center justify-center dark:bg-gray-600 bg-gray-800`} + > {token.symbol.slice(0, 2)} @@ -106,7 +115,8 @@ export function TokenSelectDropdown({ token.riskLevel === "High Risk" ? "text-[#B23232] dark:bg-[#FF60600F] bg-[#FF60600F] p-1 rounded-sm text-sm" : "text-[#32B289] dark:bg-[#C9FFEE0F] bg-[#C9FFEE5C] p-1 rounded-sm text-sm" - }> + } + > {token.riskLevel}
    diff --git a/app/dapp/components/ui/ConnectWalletButton.tsx b/app/dapp/components/ui/ConnectWalletButton.tsx index ef5bd9a..91d3f22 100644 --- a/app/dapp/components/ui/ConnectWalletButton.tsx +++ b/app/dapp/components/ui/ConnectWalletButton.tsx @@ -1,13 +1,13 @@ -'use client'; +"use client"; -import { BrokenLink } from '@/svg/BrokenLink'; -import { Spinner } from '@/svg/Spinner'; -import WalletIcon from '@/svg/WalletIcon'; -import { GradientDirection, GradientWrapperPrimary } from './Gradients'; -import { useThemeContext } from '@/app/hooks/context'; -import { useEffect, useMemo } from 'react'; -import { toast } from 'sonner'; -import { useWallet } from '@/app/hooks/useWallet'; +import { BrokenLink } from "@/svg/BrokenLink"; +import { Spinner } from "@/svg/Spinner"; +import WalletIcon from "@/svg/WalletIcon"; +import { GradientDirection, GradientWrapperPrimary } from "./Gradients"; +import { useThemeContext } from "@/app/hooks/context"; +import { useEffect, useMemo } from "react"; +import { toast } from "sonner"; +import { useWallet } from "@/app/hooks/useWallet"; interface ConnectWalletButtonProps { full?: boolean; @@ -30,7 +30,7 @@ interface ConnectWalletButtonProps { export const ConnectWalletButton = ({ full, - className = '', + className = "", withGradient = true, gradientDirection, thin = false, @@ -66,8 +66,6 @@ export const ConnectWalletButton = ({ if (resolvedError) toast.error(`Connection error: ${resolvedError}`); }, [resolvedError]); - - const handleClick = () => { // Use provided action if any; otherwise open the wallet modal from the hook const fallback = wallet?.openWalletModal; @@ -76,36 +74,36 @@ export const ConnectWalletButton = ({ }; const getPaddingAndRoundness = () => { - if (thin) return 'px-3 py-1 rounded-[6px]'; - if (full) return 'py-4 rounded-[8px]'; - return 'py-2 rounded-[8px]'; + if (thin) return "px-3 py-1 rounded-[6px]"; + if (full) return "py-4 rounded-[8px]"; + return "py-2 rounded-[8px]"; }; const baseClasses = `flex items-center justify-center px-3 ${getPaddingAndRoundness()} text-primary-text border border-wallet-border transition-all duration-200 hover:opacity-80 active:opacity-60 ${ - full ? 'w-full' : '' + full ? "w-full" : "" } ${className}`; const getButtonContent = () => { if (resolvedIsLoading) { return ( -
    +
    - Connecting... + Connecting...
    ); } if (resolvedIsConnected) { return ( -
    -
    +
    +
    - + {resolvedWalletAddress}
    {showBrokenLink && ( -
    +
    )} @@ -114,9 +112,11 @@ export const ConnectWalletButton = ({ } return ( -
    +
    - Connect Wallet + + Connect Wallet +
    ); }; @@ -124,18 +124,18 @@ export const ConnectWalletButton = ({ const ButtonContent = ( @@ -143,10 +143,10 @@ export const ConnectWalletButton = ({ return withGradient ? ( {ButtonContent} diff --git a/app/dapp/lock-tokens/page.tsx b/app/dapp/lock-tokens/page.tsx index 854741e..3de5143 100644 --- a/app/dapp/lock-tokens/page.tsx +++ b/app/dapp/lock-tokens/page.tsx @@ -1,12 +1,12 @@ -'use client'; -import TokenLockInterface from '@/app/dapp/components/lock-tokens'; +"use client"; +import TokenLockInterface from "@/app/dapp/components/lock-tokens"; const TokenLockPage = () => { return (
    -
    +
    From 36c7416dc0e708f5d3a4b199c6a5086889dd1441 Mon Sep 17 00:00:00 2001 From: Isaac Onyemaechi Ugwu Date: Wed, 20 Aug 2025 17:17:15 +0100 Subject: [PATCH 26/58] added the proloader to the dapp (#179) * added the proloader to the dapp * little fix --- app/dapp/coming-soon/page.tsx | 1 - app/dapp/components/ui/Preloader.tsx | 177 +++++++++++++++++++++++++++ app/dapp/layout.tsx | 4 +- app/dapp/page.tsx | 23 +++- app/page.tsx | 29 +++-- public/preloader-background.svg | 33 +++++ 6 files changed, 254 insertions(+), 13 deletions(-) create mode 100644 app/dapp/components/ui/Preloader.tsx create mode 100644 public/preloader-background.svg diff --git a/app/dapp/coming-soon/page.tsx b/app/dapp/coming-soon/page.tsx index 25a7e98..d206614 100644 --- a/app/dapp/coming-soon/page.tsx +++ b/app/dapp/coming-soon/page.tsx @@ -1,5 +1,4 @@ import Image from "next/image"; -import { MoveRight } from "lucide-react"; // if the data isn't depending on any prop in the component, it should be outside its // render method so we avoid re-computing it again on every render. diff --git a/app/dapp/components/ui/Preloader.tsx b/app/dapp/components/ui/Preloader.tsx new file mode 100644 index 0000000..26bdbab --- /dev/null +++ b/app/dapp/components/ui/Preloader.tsx @@ -0,0 +1,177 @@ +"use client"; + +import { useEffect, useState, useCallback } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { useTheme } from "next-themes"; + +interface PreloaderProps { + onComplete: () => void; +} + +export default function Preloader({ onComplete }: PreloaderProps) { + const [progress, setProgress] = useState(0); + const [animationPhase, setAnimationPhase] = useState<"loading" | "exiting">("loading"); + const [logoRotation, setLogoRotation] = useState(0); + const [logoScale, setLogoScale] = useState(1); + const { theme } = useTheme(); + + const handleComplete = useCallback(() => { + onComplete(); + }, [onComplete]); + + useEffect(() => { + const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; + + if (prefersReducedMotion) { + setProgress(100); + const timer = setTimeout(() => { + handleComplete(); + }, 1000); + return () => clearTimeout(timer); + } + + const animateLogoRotation = (newRotation: number, isLastRotation = false) => { + if (isLastRotation) { + // Final rotation: -25 degrees then back to 0 + setLogoRotation(-25); + setLogoScale(1.3); + setTimeout(() => { + setLogoRotation(0); + setLogoScale(1); + }, 300); + } else { + setLogoRotation(newRotation); + setLogoScale(1.3); + setTimeout(() => setLogoScale(1), 200); + } + }; + + const progressStages = [ + { progress: 30, delay: 1000 }, + { progress: 89, delay: 1000 }, + { progress: 100, delay: 1500 } + ]; + + const timeoutIds: NodeJS.Timeout[] = []; + let totalDelay = 0; + + progressStages.forEach((stage, index) => { + totalDelay += stage.delay; + const timeoutId = setTimeout(() => { + setProgress(stage.progress); + const isLastRotation = stage.progress === 100; + animateLogoRotation((index + 1) * 90, isLastRotation); + + if (stage.progress === 100) { + setTimeout(() => { + setAnimationPhase("exiting"); + setTimeout(() => handleComplete(), 300); + }, 800); + } + }, totalDelay); + timeoutIds.push(timeoutId); + }); + + return () => { + timeoutIds.forEach(clearTimeout); + }; + }, [handleComplete]); + + + const logoColor = theme === "dark" ? "#FFFFFF" : "#ffffff"; + + return ( + +
    + + + + ); +} \ No newline at end of file diff --git a/app/dapp/layout.tsx b/app/dapp/layout.tsx index a17b18d..76ced01 100644 --- a/app/dapp/layout.tsx +++ b/app/dapp/layout.tsx @@ -7,7 +7,7 @@ import { config } from "../config"; import { Toaster } from "sonner"; import { usePathname } from "next/navigation"; -function layout({ +function Layout({ children, }: Readonly<{ children: React.ReactNode; @@ -38,4 +38,4 @@ function layout({ ); } -export default layout; +export default Layout; diff --git a/app/dapp/page.tsx b/app/dapp/page.tsx index 4a8bf09..7d7be12 100644 --- a/app/dapp/page.tsx +++ b/app/dapp/page.tsx @@ -1,7 +1,24 @@ -import { redirect } from "next/navigation"; +"use client"; -const Page = async () => { - redirect("/dapp/dashboard"); +import React, { useState } from "react"; +import { useRouter } from "next/navigation"; +import Preloader from "./components/ui/Preloader"; + +const Page = () => { + const [showPreloader] = useState(true); + const navigate = useRouter(); + + if (showPreloader) { + return ( + { + navigate.push('/dapp/dashboard'); + }} + /> + ); + } + + return null; }; export default Page; diff --git a/app/page.tsx b/app/page.tsx index 3a77636..97cb2ba 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,9 +1,24 @@ -const App = () => { - return ( -
    -

    Welcome to the app

    -
    - ); +"use client"; + +import React, { useState } from "react"; +import { useRouter } from "next/navigation"; +import Preloader from "./dapp/components/ui/Preloader"; + +const Page = () => { + const [showPreloader] = useState(true); + const navigate = useRouter(); + + if (showPreloader) { + return ( + { + navigate.push('/dapp/dashboard'); + }} + /> + ); + } + + return null; }; -export default App; +export default Page; diff --git a/public/preloader-background.svg b/public/preloader-background.svg new file mode 100644 index 0000000..1a19f4c --- /dev/null +++ b/public/preloader-background.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 6c74fa91b1613eeb53452b7cb4432a41b8757754 Mon Sep 17 00:00:00 2001 From: Ugo-X Date: Thu, 21 Aug 2025 10:32:10 +0100 Subject: [PATCH 27/58] governance --- app/dapp/governance/page.tsx | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/dapp/governance/page.tsx diff --git a/app/dapp/governance/page.tsx b/app/dapp/governance/page.tsx new file mode 100644 index 0000000..420e11c --- /dev/null +++ b/app/dapp/governance/page.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const page = () => { + return
    page
    ; +}; + +export default page; From 98d28bfa6edad3c1540796e1c7d3ad2a4c68e864 Mon Sep 17 00:00:00 2001 From: Jay <111138366+Jayrodri088@users.noreply.github.com> Date: Thu, 21 Aug 2025 17:57:08 +0100 Subject: [PATCH 28/58] Add skeleton/shimmer states to the Swap page using mocked loading (#196) * feat: add skeleton loading states to swap page components * removed skeleton for button --- app/dapp/swap/components/SwapFromInput.tsx | 14 +- app/dapp/swap/components/SwapToInput.tsx | 5 +- .../swap/components/TokenDropDownMenu.tsx | 92 ++++--- app/dapp/swap/page.tsx | 257 +++++++++++++----- 4 files changed, 254 insertions(+), 114 deletions(-) diff --git a/app/dapp/swap/components/SwapFromInput.tsx b/app/dapp/swap/components/SwapFromInput.tsx index 931fc80..481934b 100644 --- a/app/dapp/swap/components/SwapFromInput.tsx +++ b/app/dapp/swap/components/SwapFromInput.tsx @@ -1,7 +1,6 @@ + import React from "react"; import { TokenSelectDropdown } from "./TokenDropDownMenu"; - -// Dummy token type data import { Token } from "@/types/tokens"; import { tokens_swap as tokens } from "@/utils/data"; import Image from "next/image"; @@ -13,6 +12,7 @@ interface SwapFromInputProps { setAmount: (amount: string) => void; balance?: string; isConnected: boolean; + isLoading?: boolean; } const numberRegex = /^[0-9]*[.,]?[0-9]*$/; @@ -24,6 +24,7 @@ function SwapFromInput({ setAmount, balance, isConnected, + isLoading = false, }: SwapFromInputProps) { return (
    item.name !== token.name)} + isLoading={isLoading} />
    { @@ -73,8 +75,8 @@ function SwapFromInput({ @@ -92,4 +94,4 @@ function SwapFromInput({ ); } -export default SwapFromInput; +export default SwapFromInput; \ No newline at end of file diff --git a/app/dapp/swap/components/SwapToInput.tsx b/app/dapp/swap/components/SwapToInput.tsx index 490253e..0518673 100644 --- a/app/dapp/swap/components/SwapToInput.tsx +++ b/app/dapp/swap/components/SwapToInput.tsx @@ -9,6 +9,7 @@ interface SwapToInputProps { setToken: (token: Token) => void; amount: string; isConnected: boolean; + isLoading?: boolean; } function SwapToInput({ @@ -16,6 +17,7 @@ function SwapToInput({ setToken, amount, isConnected, + isLoading = false, }: SwapToInputProps) { return (
    item.name !== token.name)} + isLoading={isLoading} />
    @@ -66,4 +69,4 @@ function SwapToInput({ ); } -export default SwapToInput; +export default SwapToInput; \ No newline at end of file diff --git a/app/dapp/swap/components/TokenDropDownMenu.tsx b/app/dapp/swap/components/TokenDropDownMenu.tsx index a78c277..e90c68e 100644 --- a/app/dapp/swap/components/TokenDropDownMenu.tsx +++ b/app/dapp/swap/components/TokenDropDownMenu.tsx @@ -8,64 +8,84 @@ import { } from "../../components/ui/dropdown-menu"; import Image from "next/image"; import { useThemeContext } from "@/app/hooks/context"; - -// interface Token { -// logo: string; -// name: string; -// symbol: string; -// currentPrice: number; -// } - import { Token } from "@/types/tokens"; interface TokenSelectDropdownProps { onTokenSelect: (token: Token) => void; tokens: Token[]; + isLoading?: boolean; +} + +function TokenSkeleton() { + return ( +
    +
    +
    +
    +
    +
    +
    + ); } export function TokenSelectDropdown({ onTokenSelect, tokens, + isLoading = false, }: TokenSelectDropdownProps) { const { isDark } = useThemeContext(); + return ( - - {tokens.map((token) => ( - onTokenSelect(token)} - className={`flex items-center gap-2 cursor-pointer`} - > -
    - token logo -
    -
    -
    {token.name}
    -
    - {token.symbol} + {isLoading ? ( + <> + {Array.from({ length: 5 }).map((_, index) => ( +
    + +
    + ))} + + ) : ( + tokens.map((token) => ( + onTokenSelect(token)} + className={`flex items-center gap-2 cursor-pointer`} + > +
    + token logo
    -
    - - ))} +
    +
    {token.name}
    +
    + {token.symbol} +
    +
    + + )) + )} ); -} +} \ No newline at end of file diff --git a/app/dapp/swap/page.tsx b/app/dapp/swap/page.tsx index 81e422e..16947f0 100644 --- a/app/dapp/swap/page.tsx +++ b/app/dapp/swap/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import { Menu } from "lucide-react"; import SwapFromInput from "./components/SwapFromInput"; import SwapToInput from "./components/SwapToInput"; @@ -12,7 +12,96 @@ import { SwapSuccessModal } from "./components/SwapSuccessModal"; import { ConnectWalletButton } from "../components/ui/ConnectWalletButton"; import { useWallet } from "@/app/hooks"; +// Skeleton Components +function SwapFromInputSkeleton() { + return ( +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + ); +} + +function SwapToInputSkeleton() { + return ( +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + ); +} + +function SwapQuoteDetailsSkeleton() { + return ( +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + ); +} + +// function SwapButtonSkeleton() { +// return ( +//
    +// ); +// } + export default function SwapPage() { + const [isLoading, setIsLoading] = useState(true); const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false); const [fromToken, setFromToken] = useState(tokens[0]); const [toToken, setToToken] = useState(tokens[1]); @@ -26,6 +115,14 @@ export default function SwapPage() { const { isConnected, openWalletModal } = useWallet(); + useEffect(() => { + const timer = setTimeout(() => { + setIsLoading(false); + }, 2000); + + return () => clearTimeout(timer); + }, []); + function handleToggle() { const temp = fromToken; const currentAmountInput = toAmount; @@ -38,7 +135,7 @@ export default function SwapPage() { return (
    - - + + {isLoading ? ( + <> + + + + ) : ( + <> + + + + )}
    -
    - {[ - [ - "Price", - `${fromAmount} ${fromToken.symbol} = ${( - (fromToken.currentPrice * Number(fromAmount)) / - toToken.currentPrice - ).toFixed(2)} ${toToken.symbol}`, - ], - ["Frontend Fee:", "$1.23"], - ["You'd receive:", "$3492.10"], - ] - .filter(([label]) => isConnected || label !== "You'd receive:") - .map(([label, value], i) => { - const fallbackMap: Record = { - Price: "-- USDT per ETH", - "Frontend Fee:": "$0", - }; - - const displayValue = isConnected - ? value - : fallbackMap[label] || "--"; - - return ( -
    - - {label} - - - {displayValue} - -
    - ); - })} -
    - - {isConnected ? ( - + {isLoading ? ( + <> + + ) : ( - + <> +
    + {[ + [ + "Price", + `${fromAmount} ${fromToken.symbol} = ${( + (fromToken.currentPrice * Number(fromAmount)) / + toToken.currentPrice + ).toFixed(2)} ${toToken.symbol}`, + ], + ["Frontend Fee:", "$1.23"], + ["You'd receive:", "$3492.10"], + ] + .filter(([label]) => isConnected || label !== "You'd receive:") + .map(([label, value], i) => { + const fallbackMap: Record = { + Price: "-- USDT per ETH", + "Frontend Fee:": "$0", + }; + + const displayValue = isConnected + ? value + : fallbackMap[label] || "--"; + + return ( +
    + + {label} + + + {displayValue} + +
    + ); + })} +
    + + {isConnected ? ( + + ) : ( + + )} + )}
    @@ -145,4 +260,4 @@ export default function SwapPage() { />
    ); -} +} \ No newline at end of file From 5ab08ff63b196cb263eadef8a202326a57840a69 Mon Sep 17 00:00:00 2001 From: Ochulor Freedom <154595610+FreddyJ23@users.noreply.github.com> Date: Fri, 22 Aug 2025 00:01:31 +0100 Subject: [PATCH 29/58] =?UTF-8?q?Fix-185=20Add=20Mock=20Loading=20Skeleton?= =?UTF-8?q?s=20=E2=80=93=20Claim/Burn=20(#207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/dapp/claim-burn/components/info.tsx | 33 ++++-- app/dapp/claim-burn/page.tsx | 138 ++++++++++++++---------- app/dapp/components/Skeleton.tsx | 15 +++ 3 files changed, 122 insertions(+), 64 deletions(-) create mode 100644 app/dapp/components/Skeleton.tsx diff --git a/app/dapp/claim-burn/components/info.tsx b/app/dapp/claim-burn/components/info.tsx index a362c90..bf27b3b 100644 --- a/app/dapp/claim-burn/components/info.tsx +++ b/app/dapp/claim-burn/components/info.tsx @@ -1,21 +1,38 @@ +import { Skeleton } from '../../components/Skeleton'; + interface InfoRowProps { label: string; - value: string; + value: React.ReactNode; isDark: boolean; valueFontWeight?: string; + loading: boolean; } -export const InfoRow = ({ label, value, isDark, valueFontWeight }: InfoRowProps) => ( +export const InfoRow = ({ + label, + loading, + value, + isDark, + valueFontWeight, +}: InfoRowProps) => (
    {label} - - {value} - + {loading ? ( + + ) : ( + + {value} + + )}
    ); diff --git a/app/dapp/claim-burn/page.tsx b/app/dapp/claim-burn/page.tsx index 65e8a5e..f66f809 100644 --- a/app/dapp/claim-burn/page.tsx +++ b/app/dapp/claim-burn/page.tsx @@ -1,23 +1,23 @@ -"use client"; - -import { useWallet } from "@/app/hooks/useWallet"; -import { useMemo, useState } from "react"; -import { SuccessModal } from "./components/success"; -import { ConnectWalletButton } from "../components/ui/ConnectWalletButton"; -import Image from "next/image"; -import { ClaimBurnTab } from "./components/tab"; -import { Geist_Mono, Inter } from "next/font/google"; -import { Hamburger } from "@/svg/Hamburger"; -import { Info } from "@/svg/Info"; -import { useThemeContext } from "@/app/hooks/context"; -import { InfoRow } from "./components/info"; +'use client'; + +import { useWallet } from '@/app/hooks/useWallet'; +import { useEffect, useMemo, useState } from 'react'; +import { SuccessModal } from './components/success'; +import { ConnectWalletButton } from '../components/ui/ConnectWalletButton'; +import Image from 'next/image'; +import { ClaimBurnTab } from './components/tab'; +import { Geist_Mono, Inter } from 'next/font/google'; +import { Hamburger } from '@/svg/Hamburger'; +import { Info } from '@/svg/Info'; +import { useThemeContext } from '@/app/hooks/context'; +import { InfoRow } from './components/info'; const geistMono = Geist_Mono({ - subsets: ["latin"], + subsets: ['latin'], }); const inter = Inter({ - subsets: ["latin"], + subsets: ['latin'], }); type BurnClaimData = { @@ -31,28 +31,29 @@ type BurnClaimData = { export default function ClaimBurnPage() { const { isDark } = useThemeContext(); const { isConnected, openWalletModal } = useWallet(); - const [activeTab, setActiveTab] = useState("claim"); - const [amount, setAmount] = useState(""); + const [activeTab, setActiveTab] = useState('claim'); + const [amount, setAmount] = useState(''); const [showSuccessModal, setShowSuccessModal] = useState(false); + const [loading, setLoading] = useState(true); const CLAIM_BURN_DATA: Record = useMemo( () => ({ claim: { available: isConnected ? 3939 : 0, - value: isConnected ? "$3394.13" : "--", - price: isConnected ? "$0.123" : "--", - fee: "$0", - displayAmount: isConnected ? "3094.00" : "0.00", + value: isConnected ? '$3394.13' : '--', + price: isConnected ? '$0.123' : '--', + fee: '$0', + displayAmount: isConnected ? '3094.00' : '0.00', }, burn: { available: isConnected ? 3939 : 0, - value: isConnected ? "$3394.13" : "--", - price: isConnected ? "$0.123" : "--", - fee: "$0", - displayAmount: isConnected ? "3094.00" : "0.00", + value: isConnected ? '$3394.13' : '--', + price: isConnected ? '$0.123' : '--', + fee: '$0', + displayAmount: isConnected ? '3094.00' : '0.00', }, }), - [isConnected], + [isConnected] ); const currentData = CLAIM_BURN_DATA[activeTab]; @@ -65,14 +66,19 @@ export default function ClaimBurnPage() { if (isConnected && amount) setShowSuccessModal(true); }; - const isActionable = !!(amount && amount !== "0" && amount !== "0.00"); + const isActionable = !!(amount && amount !== '0' && amount !== '0.00'); const claimBurnBtnClasses = isActionable ? isDark - ? "bg-white text-[#515151] hover:opacity-80" - : "bg-black text-white hover:opacity-80" + ? 'bg-white text-[#515151] hover:opacity-80' + : 'bg-black text-white hover:opacity-80' : isDark - ? "bg-[#2e2e2e] text-[#515151] cursor-not-allowed" - : "bg-[#f0f0f0] text-[#c4c4c4] cursor-not-allowed"; + ? 'bg-[#2e2e2e] text-[#515151] cursor-not-allowed' + : 'bg-[#f0f0f0] text-[#c4c4c4] cursor-not-allowed'; + + useEffect(() => { + const timer = setTimeout(() => setLoading(false), 2000); + return () => clearTimeout(timer); + }, []); return ( <> @@ -82,7 +88,7 @@ export default function ClaimBurnPage() {
    @@ -92,18 +98,18 @@ export default function ClaimBurnPage() {
    ZeroXBridge Logo

    - {activeTab === "claim" ? "Claim" : "Burn"} + {activeTab === 'claim' ? 'Claim' : 'Burn'}

    xZB

    @@ -167,35 +184,44 @@ export default function ClaimBurnPage() { label="Price:" value={`${currentData.price} xZB per ETH`} isDark={isDark} + loading={loading} /> + - {activeTab === "burn" && isConnected && amount && ( + + {activeTab === 'burn' && isConnected && amount && ( )}
    - {activeTab === "burn" && ( + {activeTab === 'burn' && (

    - {activeTab === "claim" ? "Claim xZB" : "Burn xZB"} + {activeTab === 'claim' ? 'Claim xZB' : 'Burn xZB'} )}

    diff --git a/app/dapp/components/Skeleton.tsx b/app/dapp/components/Skeleton.tsx new file mode 100644 index 0000000..176769a --- /dev/null +++ b/app/dapp/components/Skeleton.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import clsx from 'clsx'; + +interface SkeletonProps extends React.HTMLAttributes { + className?: string; +} + +export const Skeleton: React.FC = ({ className, ...props }) => { + return ( +
    + ); +}; From e91bac97ed80b8331f7d803ea51e3f58d783dc07 Mon Sep 17 00:00:00 2001 From: Raymond Joseph <162983930+raymondjoseph02@users.noreply.github.com> Date: Fri, 22 Aug 2025 00:11:20 +0100 Subject: [PATCH 30/58] fix conflict error (#203) --- .../dapp/governance/learn-overview.tsx | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 app/components/dapp/governance/learn-overview.tsx diff --git a/app/components/dapp/governance/learn-overview.tsx b/app/components/dapp/governance/learn-overview.tsx new file mode 100644 index 0000000..5983ad4 --- /dev/null +++ b/app/components/dapp/governance/learn-overview.tsx @@ -0,0 +1,101 @@ +import { ArrowUpRight, BookOpen } from "@/public/icons/svg/general"; +import { ArrowRight } from "lucide-react"; +import Link from "next/link"; +const resources = [ + { + title: "Starknet’s progressive governance", + description: + "A decentralized network that strives to evolve over time needs to have progressively evolving decentralized governance mechanisms to support protocol upgrades.", + link: "#", + }, + { + title: "How to delegate voting power", + description: + "If you are a STRK token holder, you can select a delegate to vote in your place for protocol changes.", + link: "#", + }, +]; +export const LearnOverview = () => { + return ( +
    +
    +
    +

    + +

    + Learn +

    +

    +

    + Starknet Governance overview +

    +
    +
    +
    +

    + Overview +

    +

    + Starknet is a permissionless decentralized Layer 2 (L2) validity + rollup, built to enable Ethereum to scale by using cryptographic + protocols called STARKs, without compromising Ethereum’s core + principles of decentralization, transparency, inclusivity, and + security. +

    +
    + +
    +
    +
    +
    + {resources.map((item, index) => ( + + ))} +
    +
    + ); +}; +interface OverviewCardProps { + title: string; + description: string; + link: string; +} +export const OverviewCard = ({ + title, + description, + link, +}: OverviewCardProps) => { + return ( + +
    +
    +

    {title}

    +

    + {description} +

    +
    +
    +

    + Learn more +

    + + + +
    +
    + + ); +}; From c0ff7724d87998a22789be4f9b33d19138b3026e Mon Sep 17 00:00:00 2001 From: Atunwa Vincent <125933139+Sirvincee@users.noreply.github.com> Date: Fri, 22 Aug 2025 00:48:50 +0100 Subject: [PATCH 31/58] =?UTF-8?q?Fix-184:=20Add=20Mock=20Loading=20Skeleto?= =?UTF-8?q?ns=20=E2=80=93=20Dashboard=20(#208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/dapp/dashboard/page.tsx | 167 ++++++++++++++++++++++++------------ 1 file changed, 114 insertions(+), 53 deletions(-) diff --git a/app/dapp/dashboard/page.tsx b/app/dapp/dashboard/page.tsx index 32fd9ca..e1fb784 100644 --- a/app/dapp/dashboard/page.tsx +++ b/app/dapp/dashboard/page.tsx @@ -1,11 +1,18 @@ "use client"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { WalletCard, ClaimCard } from "./components/card"; import { DashboardChart, TVLChart, AssetChart } from "./components/chart"; import { SearchIcon, XIcon } from "lucide-react"; import { useThemeContext } from "@/app/hooks/context"; import { AssetsMenu } from "./components/asset-menu"; import { ChartTabs } from "./components/chart-tab"; +import { Skeleton } from "../components/Skeleton"; +import { useCryptoData } from "@/app/hooks/swr"; + + + + + const assets = [ { name: "Bitcoin", symbol: "btc", icon: "/bitcoin.svg", id: "bitcoin" }, @@ -23,16 +30,29 @@ const assets = [ }, ]; + export default function DashboardPage() { const { isDark } = useThemeContext(); const [currentAsset, setCurrentAsset] = useState(assets[0]); const [showSearch, setShowSearch] = useState(false); + const [loading, setLoading] = useState(true); + const { data, isLoading } = useCryptoData(currentAsset.id); + const onAssetSelect = (id: string) => { const found = assets.find((asset) => asset.id === id); if (found) setCurrentAsset(found); }; + + useEffect(() => { + const timer = setTimeout(() => setLoading(false), 1000); + return () => clearTimeout(timer); + }, []); + + + + return (
    + +
    - - + {loading ? ( + <> + + + + ) : ( + <> + + + + )}
    -
    + + {loading ? (<> + + + + + + ) : (
    }, { label: "Total Value Locked", content: }, ]} /> -
    +
    )} -
    -
    -
    - - -
    - - -
    - {/* This one is for mobiles which slides from the top when the search icon is clicked */} - - - {showSearch && ( -
    - - */} + {isLoading ? ( + <> + + + + + ) : ( + <> +
    +
    + + +
    + - + + + {showSearch && ( +
    + + + +
    + )}
    - )} + +
    - -
    -
    + + )}
    + + + + + {/*
    */}
    ); -} +} \ No newline at end of file From 95b389fb782b27cf6c0ff48600b5618ef63b0625 Mon Sep 17 00:00:00 2001 From: martin machiebe <127976766+martinvibes@users.noreply.github.com> Date: Fri, 22 Aug 2025 10:29:06 +0100 Subject: [PATCH 32/58] feat: add internationalization support with i18next (#198) * feat: Implement internationalization support with i18next integration * updates * fix resposniveness * updates --------- Co-authored-by: martinvibes --- app/components/LanguageSwitcher.tsx | 63 ++++ .../dapp/governance/learn-overview.tsx | 6 +- app/components/testimonial.tsx | 202 +++++++++++++ app/contexts/LanguageContext.tsx | 67 +++++ app/dapp/coming-soon/page.tsx | 161 +++++----- app/dapp/components/analytics/ChartCard.tsx | 59 ++-- app/dapp/components/analytics/EmptyState.tsx | 22 +- app/dapp/components/claim-burn/index.tsx | 87 ++++-- app/dapp/components/layout/Footer.tsx | 21 +- app/dapp/components/layout/Sidebar.tsx | 50 +++- app/dapp/components/layout/Topbar.tsx | 20 +- app/dapp/components/lock-tokens.tsx | 26 +- app/dapp/components/success-modal.tsx | 36 ++- app/dapp/components/token-select-dropdown.tsx | 9 +- .../components/ui/ConnectWalletButton.tsx | 21 +- app/dapp/dashboard/page.tsx | 95 +++--- app/i18n-client.ts | 27 ++ app/i18n.ts | 3 + app/layout.tsx | 5 +- app/locales/en/common.json | 280 ++++++++++++++++++ app/locales/fr/common.json | 280 ++++++++++++++++++ package.json | 2 + 22 files changed, 1293 insertions(+), 249 deletions(-) create mode 100644 app/components/LanguageSwitcher.tsx create mode 100644 app/components/testimonial.tsx create mode 100644 app/contexts/LanguageContext.tsx create mode 100644 app/i18n-client.ts create mode 100644 app/i18n.ts create mode 100644 app/locales/en/common.json create mode 100644 app/locales/fr/common.json diff --git a/app/components/LanguageSwitcher.tsx b/app/components/LanguageSwitcher.tsx new file mode 100644 index 0000000..a2cc6d3 --- /dev/null +++ b/app/components/LanguageSwitcher.tsx @@ -0,0 +1,63 @@ +"use client"; + +import React from "react"; +import { useLanguage } from "../contexts/LanguageContext"; +import { useTranslation } from "react-i18next"; +import { Globe } from "lucide-react"; +import { useThemeContext } from "../context/theme-provider"; +import "../i18n-client"; + +interface LanguageSwitcherProps { + className?: string; + size?: "sm" | "md" | "lg"; + showText?: boolean; +} + +const LanguageSwitcher: React.FC = ({ + className = "", + size = "md", + showText = true, +}) => { + const { t } = useTranslation(); + const { currentLanguage, changeLanguage, isLoading } = useLanguage(); + const { isDark } = useThemeContext(); + + const handleLanguageChange = async () => { + const newLanguage = currentLanguage === "en" ? "fr" : "en"; + await changeLanguage(newLanguage); + }; + + const sizeClasses = { + sm: "px-2 py-1 text-xs", + md: "px-3 py-2 text-sm", + lg: "px-4 py-3 text-base", + }; + + const iconSizes = { + sm: 14, + md: 16, + lg: 18, + }; + + return ( + + ); +}; + +export default LanguageSwitcher; diff --git a/app/components/dapp/governance/learn-overview.tsx b/app/components/dapp/governance/learn-overview.tsx index 5983ad4..b9b014d 100644 --- a/app/components/dapp/governance/learn-overview.tsx +++ b/app/components/dapp/governance/learn-overview.tsx @@ -1,5 +1,5 @@ -import { ArrowUpRight, BookOpen } from "@/public/icons/svg/general"; -import { ArrowRight } from "lucide-react"; +// import { ArrowUpRight, BookOpen } from "@/public/icons/svg/general"; +import { ArrowRight, BookOpen } from "lucide-react"; import Link from "next/link"; const resources = [ { @@ -92,7 +92,7 @@ export const OverviewCard = ({ Learn more

    - +
    diff --git a/app/components/testimonial.tsx b/app/components/testimonial.tsx new file mode 100644 index 0000000..fa3242c --- /dev/null +++ b/app/components/testimonial.tsx @@ -0,0 +1,202 @@ +"use client"; + +import { useState, useEffect } from "react"; +import Image from "next/image"; +import GlowingProtractorSVG from "../../public/bitcoin.svg"; +import { useTranslation } from "react-i18next"; + +import { motion } from "framer-motion"; + +interface Testimonial { + id: number; + content: string; + author: { + name: string; + image: string; + }; +} + +// Move testimonials inside the component where t is available + +export default function Testimonial() { + const [currentSlide, setCurrentSlide] = useState(0); + const { t } = useTranslation(); + + const testimonials: Testimonial[] = [ + { + id: 1, + content: t("testimonial.content"), + author: { + name: t("testimonial.author"), + image: "/images/testimonial-card-profile.png", + }, + }, + { + id: 2, + content: t("testimonial.content"), + author: { + name: t("testimonial.author"), + image: "/images/testimonial-card-profile.png", + }, + }, + { + id: 3, + content: t("testimonial.content"), + author: { + name: t("testimonial.author"), + image: "/images/testimonial-card-profile.png", + }, + }, + ]; + + useEffect(() => { + const interval = setInterval(() => { + setCurrentSlide((prevSlide) => (prevSlide + 1) % testimonials.length); + }, 5000); + + return () => clearInterval(interval); + }, [testimonials.length]); + + const handleManualNavigation = (index: number) => { + setCurrentSlide(index); + }; + + return ( +
    + {/* Background Glow Effect */} +
    + Glow Effect +
    + + {/* Main Container */} +
    + {/* Header */} +
    +

    + {t("testimonial.title")} +

    +

    + {t("testimonial.subtitle")} +

    +
    + + {/* Glowing SVG Lines */} +
    + +
    + + {/* Testimonial Cards */} +
    +
    + {testimonials.map((testimonial, index) => { + const offset = + (index - currentSlide + testimonials.length) % + testimonials.length; + let translateX = "0%"; + let zIndex = 0; + let opacity = 1; + let visibilityClass = "block"; // Default visible + + if (offset === 0) { + zIndex = 3; + } else if (offset === 1 || offset === testimonials.length - 1) { + translateX = offset === 1 ? "105%" : "-105%"; + zIndex = 2; + opacity = 0.7; + } else { + translateX = offset === 2 ? "210%" : "-210%"; + zIndex = 1; + opacity = 0.4; + } + + // Hide side cards on mobile + if (offset !== 0) { + visibilityClass = "hidden sm:block"; + } + + return ( + + quotes icon +
    + {testimonial.content} +
    +
    + {testimonial.author.name} + + {testimonial.author.name} + +
    +
    + ); + })} +
    +
    + + {/* Navigation Lines */} +
    + {testimonials.map((_, index) => ( + handleManualNavigation(index)} + className={`w-8 md:w-12 h-[2px] bg-gray-700`} + whileHover={{ scale: 1.1 }} + whileTap={{ scale: 0.9 }} + > + + + ))} +
    +
    +
    + ); +} diff --git a/app/contexts/LanguageContext.tsx b/app/contexts/LanguageContext.tsx new file mode 100644 index 0000000..f52fe7a --- /dev/null +++ b/app/contexts/LanguageContext.tsx @@ -0,0 +1,67 @@ +"use client"; + +import React, { createContext, useContext, useEffect, useState } from "react"; +import i18n from "../i18n-client"; + +interface LanguageContextType { + currentLanguage: string; + changeLanguage: (language: string) => Promise; + isLoading: boolean; +} + +const LanguageContext = createContext( + undefined +); + +export const useLanguage = () => { + const context = useContext(LanguageContext); + if (context === undefined) { + throw new Error("useLanguage must be used within a LanguageProvider"); + } + return context; +}; + +interface LanguageProviderProps { + children: React.ReactNode; +} + +export const LanguageProvider: React.FC = ({ + children, +}) => { + const [currentLanguage, setCurrentLanguage] = useState("en"); + const [isLoading, setIsLoading] = useState(false); + + const changeLanguage = async (language: string) => { + setIsLoading(true); + try { + await i18n.changeLanguage(language); + setCurrentLanguage(language); + if (typeof window !== "undefined") { + localStorage.setItem("language", language); + } + } catch (error) { + console.error("Error changing language:", error); + } finally { + setIsLoading(false); + } + }; + + // Initialize language from localStorage on mount + useEffect(() => { + if (typeof window !== "undefined") { + const savedLanguage = localStorage.getItem("language"); + if (savedLanguage && ["en", "fr"].includes(savedLanguage)) { + setCurrentLanguage(savedLanguage); + i18n.changeLanguage(savedLanguage); + } + } + }, []); + + return ( + + {children} + + ); +}; diff --git a/app/dapp/coming-soon/page.tsx b/app/dapp/coming-soon/page.tsx index d206614..b51a7ed 100644 --- a/app/dapp/coming-soon/page.tsx +++ b/app/dapp/coming-soon/page.tsx @@ -1,96 +1,95 @@ -import Image from "next/image"; +"use client"; -// if the data isn't depending on any prop in the component, it should be outside its -// render method so we avoid re-computing it again on every render. -const data = [ - { - title: "Seamless Wallet Integrations", - description: - "xZB will soon be natively accessible through popular Starknet wallets allowing users to instantly connect, hold, and deploy their xZB in DeFi — without extra setup or manual imports.", - img: ( - img - ), - }, - { - title: "Governance DAO & Token Whitelist Voting", - description: - "ZeroXBridge will enable the community to vote on which assets get whitelisted and help shape key protocol decisions — ensuring decentralization and user-driven evolution.", - img: ( - img - ), - }, - { - title: "Account Abstraction Support", - description: - "xZB will soon be natively accessible through popular Starknet wallets allowing users to instantly connect, hold, and deploy their xZB in DeFi — without extra setup or manual imports.", - img: ( - img - ), - }, - { - title: "Staking + APY for Liquidity Providers", - description: - "ZeroXBridge will enable users to earn passive yield by staking or locking assets, rewarding participation and driving deeper liquidity in the ecosystem.", - img: ( - img - ), - }, - { - title: "Paymaster Integration", - description: - "ZeroXBridge will let users interact with the app without needing ETH for gas, removing friction and simplifying onboarding for new Starknet users.", - img: ( - img - ), - }, -]; +import Image from "next/image"; +import { useTranslation } from "react-i18next"; +import "../../i18n-client"; const ComingSoon = () => { + const { t } = useTranslation(); + + const data = [ + { + title: t("comingSoon.seamlessWallet.title"), + description: t("comingSoon.seamlessWallet.description"), + img: ( + img + ), + }, + { + title: t("comingSoon.governanceDAO.title"), + description: t("comingSoon.governanceDAO.description"), + img: ( + img + ), + }, + { + title: t("comingSoon.accountAbstraction.title"), + description: t("comingSoon.accountAbstraction.description"), + img: ( + img + ), + }, + { + title: t("comingSoon.stakingAPY.title"), + description: t("comingSoon.stakingAPY.description"), + img: ( + img + ), + }, + { + title: t("comingSoon.paymasterIntegration.title"), + description: t("comingSoon.paymasterIntegration.description"), + img: ( + img + ), + }, + ]; + return ( -
    -
    +
    +
    {data.map((item) => (
    -
    +
    {item.title}
    -
    +
    {item.description}
    -
    +
    {item.img}
    diff --git a/app/dapp/components/analytics/ChartCard.tsx b/app/dapp/components/analytics/ChartCard.tsx index 5d05e45..2dc8ab3 100644 --- a/app/dapp/components/analytics/ChartCard.tsx +++ b/app/dapp/components/analytics/ChartCard.tsx @@ -10,6 +10,8 @@ import { ResponsiveContainer, CartesianGrid, } from "recharts"; +import { useTranslation } from "react-i18next"; +import "../../../i18n-client"; // Initialize i18n on client side interface ChartCardProps { selectedChart: "tvl" | "volume" | "price"; @@ -88,24 +90,6 @@ const chartData = { ], }; -const chartConfig = { - tvl: { - label: "TVL", - color: "#8884d8", - format: (value: number) => `$${(value / 1000).toFixed(0)}K`, - }, - volume: { - label: "Volume", - color: "#82ca9d", - format: (value: number) => `$${(value / 1000).toFixed(0)}K`, - }, - price: { - label: "Price", - color: "#ffc658", - format: (value: number) => `$${(value / 1000).toFixed(0)}K`, - }, -}; - export default function ChartCard({ selectedChart, onChartChange, @@ -113,6 +97,26 @@ export default function ChartCard({ currentPrice, priceChange, }: ChartCardProps) { + const { t } = useTranslation(); + + const chartConfig = { + tvl: { + label: t("analytics.tvl"), + color: "#8884d8", + format: (value: number) => `$${(value / 1000).toFixed(0)}K`, + }, + volume: { + label: t("analytics.volume"), + color: "#82ca9d", + format: (value: number) => `$${(value / 1000).toFixed(0)}K`, + }, + price: { + label: t("analytics.price"), + color: "#ffc658", + format: (value: number) => `$${(value / 1000).toFixed(0)}K`, + }, + }; + const lineColor = theme === "dark" ? "#fff" : "#000"; console.log("ChartCard theme:", theme, "lineColor:", lineColor); const axisAndGridColor = theme === "dark" ? "#444" : "#e5e5e5"; @@ -160,8 +164,8 @@ export default function ChartCard({
    - = 1000) return `$${(value / 1000).toFixed(0)}K`; return `$${value}`; }} - domain={['dataMin', 'dataMax']} + domain={["dataMin", "dataMax"]} tickCount={6} /> - [config.format(value), config.label]} + [ + config.format(value), + config.label, + ]} labelStyle={{ color: theme === "dark" ? "#fff" : "#000" }} contentStyle={{ backgroundColor: theme === "dark" ? "#1a1a1a" : "#fff", border: `1px solid ${theme === "dark" ? "#333" : "#e5e5e5"}`, borderRadius: "8px", - fontSize: "12px" + fontSize: "12px", }} /> @@ -229,4 +236,4 @@ export default function ChartCard({
    ); -} \ No newline at end of file +} diff --git a/app/dapp/components/analytics/EmptyState.tsx b/app/dapp/components/analytics/EmptyState.tsx index 4136520..7762190 100644 --- a/app/dapp/components/analytics/EmptyState.tsx +++ b/app/dapp/components/analytics/EmptyState.tsx @@ -1,16 +1,22 @@ "use client"; import { PieChartIcon } from "lucide-react"; -import {ConnectWalletButton} from "../ui/ConnectWalletButton"; +import { ConnectWalletButton } from "../ui/ConnectWalletButton"; +import { useTranslation } from "react-i18next"; +import "../../../i18n-client"; // Initialize i18n on client side export default function EmptyState() { + const { t } = useTranslation(); return (
    {/* Page Header */}
    -

    Analytics

    +

    + {t("navigation.analytics")} +

    - Connect your wallet to view real-time statistics and market insights + {t("wallet.connect")} {t("common.amount")} {t("analytics.tvl")}{" "} + {t("analytics.totalValueLocked")}

    @@ -20,13 +26,15 @@ export default function EmptyState() {
    - +

    - Connect Your Wallet + {t("wallet.connect")}

    - To view analytics, charts, and real-time statistics, please connect your wallet first. + {t("analytics.tvl")} {t("analytics.totalValueLocked")}{" "} + {t("analytics.lockedAssets")} {t("analytics.xzbBalance")}{" "} + {t("analytics.change24h")}

    @@ -35,4 +43,4 @@ export default function EmptyState() {
    ); -} \ No newline at end of file +} diff --git a/app/dapp/components/claim-burn/index.tsx b/app/dapp/components/claim-burn/index.tsx index 95ed1e4..55d95fb 100644 --- a/app/dapp/components/claim-burn/index.tsx +++ b/app/dapp/components/claim-burn/index.tsx @@ -10,6 +10,8 @@ import { Geist_Mono, Inter } from "next/font/google"; import { Hamburger } from "@/svg/Hamburger"; import { Info } from "@/svg/Info"; import { useThemeContext } from "@/app/hooks/context"; +import { useTranslation } from "react-i18next"; +import "../../../i18n-client"; // Initialize i18n on client side const geistMono = Geist_Mono({ subsets: ["latin"], @@ -30,11 +32,11 @@ type BurnClaimData = { const ClaimBurn = () => { const { isDark } = useThemeContext(); const { isConnected } = useWallet(); + const { t } = useTranslation(); const [activeTab, setActiveTab] = useState("claim"); const [amount, setAmount] = useState(""); const [showSuccessModal, setShowSuccessModal] = useState(false); - const CLAIM_BURN_DATA: Record = useMemo( () => ({ claim: { @@ -52,7 +54,7 @@ const ClaimBurn = () => { displayAmount: isConnected ? "3094.00" : "0.00", }, }), - [isConnected], + [isConnected] ); const currentData = CLAIM_BURN_DATA[activeTab]; @@ -71,8 +73,8 @@ const ClaimBurn = () => { ? "bg-white text-[#515151] hover:opacity-80" : "bg-black text-white hover:opacity-80" : isDark - ? "bg-[#2e2e2e] text-[#515151] cursor-not-allowed" - : "bg-[#f0f0f0] text-[#c4c4c4] cursor-not-allowed"; + ? "bg-[#2e2e2e] text-[#515151] cursor-not-allowed" + : "bg-[#f0f0f0] text-[#c4c4c4] cursor-not-allowed"; return ( <> @@ -80,16 +82,28 @@ const ClaimBurn = () => {
    @@ -107,19 +121,25 @@ const ClaimBurn = () => {

    - {activeTab === "claim" ? "Claim" : "Burn"} + {activeTab === "claim" + ? t("claimBurn.claimXZB") + : t("claimBurn.burnXZB")}

    xZB

    setAmount(e.target.value)} disabled={!isConnected} @@ -132,22 +152,30 @@ const ClaimBurn = () => {
    {
    @@ -174,14 +202,14 @@ const ClaimBurn = () => { activeTab === "claim" ? currentData.fee : isConnected && amount - ? "3%" - : "--%" + ? "3%" + : "--%" } isDark={isDark} /> {activeTab === "burn" && isConnected && amount && ( { {activeTab === "burn" && (

    - Burning xZB tokens releases your locked USDC/USDT/ETH - tokens from the contract. + {t("claimBurn.burnFirstWarning")}

    )} @@ -211,7 +242,9 @@ const ClaimBurn = () => { disabled={!isActionable} className={`w-full py-4 rounded-4xl font-bold text-sm transition-colors ${claimBurnBtnClasses} ${inter.className}`} > - {activeTab === "claim" ? "Claim xZB" : "Burn xZB"} + {activeTab === "claim" + ? t("claimBurn.claimXZB") + : t("claimBurn.burnXZB")} )}
    @@ -239,12 +272,16 @@ interface InfoRowProps { const InfoRow = ({ label, value, isDark, valueFontWeight }: InfoRowProps) => (
    {label} {value} diff --git a/app/dapp/components/layout/Footer.tsx b/app/dapp/components/layout/Footer.tsx index 7a0c874..e89cdb7 100644 --- a/app/dapp/components/layout/Footer.tsx +++ b/app/dapp/components/layout/Footer.tsx @@ -1,20 +1,23 @@ import { MoveRight } from "lucide-react"; +import { useTranslation } from "react-i18next"; +import "../../../i18n-client"; export const ComingSoonFooter = () => { + const { t } = useTranslation(); return ( -