diff --git a/app/page.tsx b/app/page.tsx index f4d19f6..2be56ee 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -12,6 +12,7 @@ export default function Home() {
+ diff --git a/components/navbar.tsx b/components/navbar.tsx index e9ba224..6d85c74 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -1,128 +1,306 @@ -'use client' +// // 'use client' -import Link from 'next/link' -import { Button } from '@/components/ui/button' -import { Menu, X, Wallet } from 'lucide-react' -import { useState, useEffect } from 'react' -import Image from 'next/image' -import { ThemeToggle } from './ui/ThemeToggle' +// // import Link from 'next/link' +// // import { Button } from '@/components/ui/button' +// // import { Menu, X, Wallet } from 'lucide-react' +// // import { useState, useEffect } from 'react' +// // import Image from 'next/image' +// // import { ThemeToggle } from './ui/ThemeToggle' + +// // export function Navbar() { +// // const [mobileMenuOpen, setMobileMenuOpen] = useState(false) +// // const [address, setAddress] = useState(null) + +// // useEffect(() => { +// // const savedAddress = localStorage.getItem('stellar_wallet_address') +// // if (savedAddress && savedAddress !== address) { +// // // eslint-disable-next-line react-hooks/set-state-in-effect +// // setAddress(savedAddress) +// // } +// // }, [address]) + +// // const formatAddress = (addr: string) => { +// // if (!addr || addr.length <= 10) return addr; +// // return `${addr.substring(0, 5)}...${addr.substring(addr.length - 4)}` +// // } + +// // return ( +// // +// // ) +// // } + +// 'use client' + +// import Link from 'next/link' +// import { Button } from '@/components/ui/button' +// import { Menu, X } from 'lucide-react' +// import { useState } from 'react' +// import Image from 'next/image' +// import { ThemeToggle } from './ui/ThemeToggle' +// import { WalletConnect } from '@/components/wallet-connect' + +// export function Navbar() { +// const [mobileMenuOpen, setMobileMenuOpen] = useState(false) + +// return ( +// +// ) +// } + +"use client"; + +import Link from "next/link"; +import { Button } from "@/components/ui/button"; +import { Menu, X } from "lucide-react"; +import { useState } from "react"; +import Image from "next/image"; +import { ThemeToggle } from "./ui/ThemeToggle"; +import { WalletConnect } from "@/components/wallet-connect"; export function Navbar() { - const [mobileMenuOpen, setMobileMenuOpen] = useState(false) - const [address, setAddress] = useState(null) - - useEffect(() => { - const savedAddress = localStorage.getItem('stellar_wallet_address') - if (savedAddress && savedAddress !== address) { - // eslint-disable-next-line react-hooks/set-state-in-effect - setAddress(savedAddress) - } - }, [address]) - - const formatAddress = (addr: string) => { - if (!addr || addr.length <= 10) return addr; - return `${addr.substring(0, 5)}...${addr.substring(addr.length - 4)}` - } + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); return ( - ) -} + ); +} \ No newline at end of file diff --git a/components/wallet-connect.tsx b/components/wallet-connect.tsx new file mode 100644 index 0000000..6f71407 --- /dev/null +++ b/components/wallet-connect.tsx @@ -0,0 +1,402 @@ +// "use client"; + +// import { useState, useEffect, useCallback } from "react"; +// import { Button } from "@/components/ui/button"; +// import { Wallet, LogOut } from "lucide-react"; +// import { +// isConnected, +// requestAccess, +// getUserInfo, +// } from "@stellar/freighter-api"; +// type WalletState = { +// connected: boolean; +// publicKey: string | null; +// error: string | null; +// }; + +// export function WalletConnect() { +// const [wallet, setWallet] = useState({ +// connected: false, +// publicKey: null, +// error: null, +// }); +// const [loading, setLoading] = useState(false); + +// // Check if Freighter is available and already connected +// const checkConnection = useCallback(async () => { +// try { +// const connected = await isConnected(); +// if (connected) { +// const user = await getUserInfo(); +// setWallet({ +// connected: true, +// publicKey: user.publicKey, +// error: null, +// }); +// } +// } catch {} +// }, []); + +// useEffect(() => { +// checkConnection(); +// }, [checkConnection]); + +// const connect = async () => { +// setLoading(true); +// setWallet((prev) => ({ ...prev, error: null })); + +// try { +// await requestAccess(); +// const user = await getUserInfo(); + +// setWallet({ +// connected: true, +// publicKey: user.publicKey, +// error: null, +// }); +// } catch (err) { +// const message = +// err instanceof Error ? err.message : "Failed to connect wallet"; +// setWallet((prev) => ({ ...prev, error: message })); +// } finally { +// setLoading(false); +// } +// }; + + +// const disconnect = () => { +// localStorage.removeItem("stellar_wallet_address"); +// setWallet({ connected: false, publicKey: null, error: null }); +// }; + +// const truncateKey = (key: string): string => { +// if (key.length <= 10) return key; +// return `${key.slice(0, 5)}...${key.slice(-4)}`; +// }; + +// // Error state +// if (wallet.error) { +// return ( +//
+//

{wallet.error}

+//
+// +// +//
+//
+// ); +// } + +// // Connected state +// if (wallet.connected && wallet.publicKey) { +// return ( +//
+// +// {truncateKey(wallet.publicKey)} +// +// +//
+// ); +// } + +// // Disconnected state +// return ( +// +// ); +// } + +// "use client"; + +// import { useState, useEffect, useCallback } from "react"; +// import { Button } from "@/components/ui/button"; +// import { Wallet, LogOut } from "lucide-react"; +// import { +// isConnected, +// requestAccess, +// getUserInfo, +// } from "@stellar/freighter-api"; + +// type WalletState = { +// connected: boolean; +// publicKey: string | null; +// error: string | null; +// }; + +// export function WalletConnect() { +// const [wallet, setWallet] = useState({ +// connected: false, +// publicKey: null, +// error: null, +// }); +// const [loading, setLoading] = useState(false); + +// // Check connection on load +// const checkConnection = useCallback(async () => { +// try { +// const connected = await isConnected(); + +// if (connected) { +// const user = await getUserInfo(); +// setWallet({ +// connected: true, +// publicKey: user.publicKey, +// error: null, +// }); +// } +// } catch { +// // silent fail (user not connected yet) +// } +// }, []); + +// useEffect(() => { +// checkConnection(); +// }, [checkConnection]); + +// const connect = async () => { +// setLoading(true); +// setWallet((prev) => ({ ...prev, error: null })); + +// try { +// await requestAccess(); +// const user = await getUserInfo(); + +// setWallet({ +// connected: true, +// publicKey: user.publicKey, +// error: null, +// }); +// } catch (err) { +// const message = +// err instanceof Error ? err.message : "Failed to connect wallet"; + +// setWallet((prev) => ({ +// ...prev, +// error: message, +// })); +// } finally { +// setLoading(false); +// } +// }; + +// const disconnect = () => { +// setWallet({ +// connected: false, +// publicKey: null, +// error: null, +// }); +// }; + +// const truncateKey = (key: string) => { +// return `${key.slice(0, 5)}...${key.slice(-4)}`; +// }; + +// // 🔴 Error State +// if (wallet.error) { +// return ( +//
+//

+// {wallet.error} +//

+//
+// +// +//
+//
+// ); +// } + +// // 🟢 Connected State +// if (wallet.connected && wallet.publicKey) { +// return ( +//
+// +// {truncateKey(wallet.publicKey)} +// +// +//
+// ); +// } + +// // ⚪ Default (Disconnected) +// return ( +// +// ); +// }"use client"; + +import { useState, useEffect, useCallback } from "react"; +import { Button } from "@/components/ui/button"; +import { Wallet, LogOut } from "lucide-react"; +import { + isConnected, + requestAccess, + getAddress, +} from "@stellar/freighter-api"; + +type WalletState = { + connected: boolean; + publicKey: string | null; + error: string | null; +}; + +export function WalletConnect() { + const [wallet, setWallet] = useState({ + connected: false, + publicKey: null, + error: null, + }); + const [loading, setLoading] = useState(false); + + const checkConnection = useCallback(async () => { + try { + const connected = await isConnected(); + + if (connected) { + const { address, error } = await getAddress(); + + if (error || !address) return; + + setWallet({ + connected: true, + publicKey: address, + error: null, + }); + } + } catch { + // ignore + } + }, []); + + useEffect(() => { + checkConnection(); + }, [checkConnection]); + + const connect = async () => { + setLoading(true); + setWallet((prev) => ({ ...prev, error: null })); + + try { + await requestAccess(); + + const { address, error } = await getAddress(); + + if (error || !address) { + throw new Error(error || "Failed to retrieve wallet address"); + } + + setWallet({ + connected: true, + publicKey: address, + error: null, + }); + } catch (err) { + const message = + err instanceof Error ? err.message : "Failed to connect wallet"; + + setWallet((prev) => ({ + ...prev, + error: message, + })); + } finally { + setLoading(false); + } + }; + + const disconnect = () => { + setWallet({ + connected: false, + publicKey: null, + error: null, + }); + }; + + const truncateKey = (key: string) => + `${key.slice(0, 5)}...${key.slice(-4)}`; + + if (wallet.error) { + return ( +
+

+ {wallet.error} +

+
+ + +
+
+ ); + } + + if (wallet.connected && wallet.publicKey) { + return ( +
+ + {truncateKey(wallet.publicKey)} + + +
+ ); + } + + return ( + + ); +} \ No newline at end of file