Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions src/components/CreateWalletModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import React, { useEffect, useRef, useState } from "react";
import { X, CheckCircle, AlertCircle } from "lucide-react";
import { useWallet } from "@/providers/WalletProvider";

type ModalState = "idle" | "connecting" | "connected" | "error";

Expand All @@ -12,14 +13,13 @@ interface Props {

export default function CreateWalletModal({ open, onClose }: Props) {
const [state, setState] = useState<ModalState>("idle");
const [method, setMethod] = useState<string | null>(null);
const backdropRef = useRef<HTMLDivElement | null>(null);
const { connect, error } = useWallet();

// reset when opened
useEffect(() => {
if (open) {
setState("idle");
setMethod(null);
}
}, [open]);

Expand All @@ -38,15 +38,10 @@ export default function CreateWalletModal({ open, onClose }: Props) {
if (e.target === backdropRef.current) onClose();
}

function simulateConnect(wallet: string) {
setMethod(wallet);
async function handleConnect() {
setState("connecting");
// fake async
setTimeout(() => {
// deterministic success for Freighter, random for Albedo
if (wallet === "Freighter") setState("connected");
else setState(Math.random() > 0.4 ? "connected" : "error");
}, 1200);
const connected = await connect();
setState(connected ? "connected" : "error");
}

return (
Expand All @@ -70,16 +65,11 @@ export default function CreateWalletModal({ open, onClose }: Props) {
<div className="mt-6 space-y-3">
{/* Default / Options */}
{state === "idle" && (
<div className="space-y-3">
<button onClick={() => simulateConnect("Freighter")} className="w-full flex items-center justify-between px-4 py-3 bg-gradient-to-r from-[#4B0082] to-[#1E90FF] text-white border border-white/10 rounded-lg hover:opacity-90 transition-opacity">
<div>
<button onClick={() => void handleConnect()} className="w-full flex items-center justify-between px-4 py-3 bg-gradient-to-r from-[#4B0082] to-[#1E90FF] text-white border border-white/10 rounded-lg hover:opacity-90 transition-opacity">
<span>Freighter</span>
<span className="text-xs text-white/90">Recommended</span>
</button>

<button onClick={() => simulateConnect("Albedo")} className="w-full flex items-center justify-between px-4 py-3 bg-gradient-to-r from-[#1a1a2e] to-[#16213e] text-white border border-white/10 rounded-lg hover:opacity-90 transition-opacity">
<span>Albedo</span>
<span className="text-xs text-white/90">Secure</span>
</button>
</div>
)}

Expand All @@ -90,7 +80,7 @@ export default function CreateWalletModal({ open, onClose }: Props) {
<div className="w-3 h-3 rounded-full bg-white/60 animate-bounce" />
</div>
<div>
<div className="text-sm">Connecting to {method}…</div>
<div className="text-sm">Connecting to Freighter…</div>
<div className="text-xs text-muted-foreground">Please approve the connection in your wallet.</div>
</div>
</div>
Expand All @@ -102,7 +92,7 @@ export default function CreateWalletModal({ open, onClose }: Props) {
<CheckCircle className="w-8 h-8 text-green-400" />
<div>
<div className="text-sm">Connected</div>
<div className="text-xs text-muted-foreground">{method} is now connected.</div>
<div className="text-xs text-muted-foreground">Freighter is now connected.</div>
</div>
</div>
)}
Expand All @@ -113,13 +103,23 @@ export default function CreateWalletModal({ open, onClose }: Props) {
<AlertCircle className="w-8 h-8 text-red-400" />
<div>
<div className="text-sm">Connection failed</div>
<div className="text-xs text-muted-foreground">Unable to connect to {method}. Try another wallet.</div>
<div className="text-xs text-muted-foreground">
{error ?? "Unable to connect to Freighter. Please try again."}
</div>
</div>
</div>
)}
</div>

<div className="mt-6 flex justify-end">
{state === "error" && (
<button
onClick={() => void handleConnect()}
className="mr-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg"
>
Try again
</button>
)}
<button onClick={onClose} className="px-4 py-2 bg-white/5 rounded-lg">Close</button>
</div>
</div>
Expand Down
82 changes: 74 additions & 8 deletions src/components/home/layout/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,23 @@ import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { ThemeToggle } from '@/components/ui/theme-toggle';
import CreateWalletModal from '@/components/CreateWalletModal';
import { useWallet } from '@/providers/WalletProvider';

function shortenAddress(address: string): string {
return `${address.slice(0, 4)}…${address.slice(-4)}`;
}

export default function NavBar() {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [walletOpen, setWalletOpen] = useState(false);
const pathname = usePathname();
const pathname = usePathname() ?? "";
const {
address,
network,
isLoading,
isWrongNetwork,
disconnect,
} = useWallet();

// Hide navbar on auth routes
const authRoutes = ['/login', '/sign-in', '/sign-up'];
Expand All @@ -21,7 +33,17 @@ export default function NavBar() {
const isLandingPage = pathname === '/';

return (
<div className="w-full h-[78px] flex items-center text-foreground overflow-x-hidden"
<>
{address && isWrongNetwork && (
<div
role="alert"
className="w-full border-b border-red-500/50 bg-red-900/80 px-4 py-2 text-center text-sm font-medium text-red-200"
>
Freighter Wallet is set to {network}. Please switch to TESTNET in
Freighter extension settings.
</div>
)}
<div className="w-full h-[78px] flex items-center text-foreground overflow-x-hidden"
style={{
backgroundColor: "var(--background)",
backgroundImage: "var(--bg-full-pattern)",
Expand Down Expand Up @@ -84,10 +106,32 @@ export default function NavBar() {
</>
) : (
<>
<button onClick={() => setWalletOpen(true)} className="flex items-center space-x-2 px-4 h-10 text-sm font-medium bg-[#FA7F2B] rounded-lg hover:bg-[#e67425] transition-colors cursor-pointer whitespace-nowrap">
<Wallet className="w-5 h-5 text-foreground" />
<span>Connect Wallet</span>
<button
onClick={() => {
if (!address) setWalletOpen(true);
}}
disabled={isLoading}
className="flex items-center space-x-2 px-4 h-10 text-sm font-medium bg-[#FA7F2B] rounded-lg hover:bg-[#e67425] transition-colors cursor-pointer whitespace-nowrap disabled:cursor-not-allowed disabled:opacity-60"
title={address ?? "Connect Freighter wallet"}
>
<Wallet className="w-5 h-5 text-foreground" />
<span className={address ? "font-mono" : undefined}>
{address
? shortenAddress(address)
: isLoading
? "Connecting…"
: "Connect Wallet"}
</span>
</button>

{address && (
<button
onClick={disconnect}
className="text-xs text-muted-foreground transition-colors hover:text-foreground"
>
Disconnect
</button>
)}

<button className="p-2 bg-card border border-border rounded-lg hover:bg-[#251241] transition-colors">
<Bell className="w-5 h-5 text-foreground" />
Expand Down Expand Up @@ -153,10 +197,31 @@ export default function NavBar() {
</>
) : (
<div className="pt-4 border-t border-border space-y-4">
<button onClick={() => setWalletOpen(true)} className="w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm bg-[#FA7F2B] rounded-lg">
<img src="/wallet-icon.png" alt="wallet" className="w-5 h-5 invert" />
<span>Connect Wallet</span>
<button
onClick={() => {
if (!address) setWalletOpen(true);
}}
disabled={isLoading}
className="w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm bg-[#FA7F2B] rounded-lg disabled:cursor-not-allowed disabled:opacity-60"
title={address ?? "Connect Freighter wallet"}
>
<Wallet className="w-5 h-5" />
<span className={address ? "font-mono" : undefined}>
{address
? shortenAddress(address)
: isLoading
? "Connecting…"
: "Connect Wallet"}
</span>
</button>
{address && (
<button
onClick={disconnect}
className="w-full text-center text-xs text-muted-foreground transition-colors hover:text-foreground"
>
Disconnect
</button>
)}
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<img src="/avatar.png" alt="Profile" className="w-10 h-10 rounded-full border-2 border-[#FA7F2B]" />
Expand All @@ -173,5 +238,6 @@ export default function NavBar() {
</nav>
<CreateWalletModal open={walletOpen} onClose={() => setWalletOpen(false)} />
</div>
</>
);
}
14 changes: 9 additions & 5 deletions src/components/layout/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,19 @@ const DISPLAY_CURRENCIES: DisplayCurrency[] = ["XLM", "USD", "EUR", "GBP", "JPY"

export default function Navbar() {
const [mobileOpen, setMobileOpen] = useState(false);
const { address, network } = useWallet();
const { address, network, isWrongNetwork } = useWallet();
const { selectedCurrency, setSelectedCurrency, convert } = useCurrency();

return (
<>
{/* Network mismatch alert banner */}
{address && network !== null && network !== "TESTNET" && (
<div className="w-full bg-red-900/80 border-b border-red-500/50 py-2 px-4 text-center text-sm font-medium text-red-200">
Freighter Wallet is set to {network}. Please switch to TESTNET in Freighter extension settings.
{address && isWrongNetwork && (
<div
role="alert"
className="w-full bg-red-900/80 border-b border-red-500/50 py-2 px-4 text-center text-sm font-medium text-red-200"
>
Freighter Wallet is set to {network}. Please switch to TESTNET in
Freighter extension settings.
</div>
)}
<header className="sticky top-0 z-30 border-b border-zinc-800/60 bg-zinc-950/80 backdrop-blur-md">
Expand Down Expand Up @@ -280,4 +284,4 @@ export default function Navbar() {
</header>
</>
);
}
}
Loading
Loading