From d10ee3541a6a6acd96e4a234120998e8bf1829e6 Mon Sep 17 00:00:00 2001 From: Illya Gerasymchuk Date: Fri, 6 Dec 2024 23:32:58 +0000 Subject: [PATCH 1/2] feat: implement authentication page --- src/app/auth/page.tsx | 251 ++++++++++++++++++++++++++---------------- src/middleware.ts | 1 - 2 files changed, 158 insertions(+), 94 deletions(-) diff --git a/src/app/auth/page.tsx b/src/app/auth/page.tsx index a0930d9..eed9649 100644 --- a/src/app/auth/page.tsx +++ b/src/app/auth/page.tsx @@ -1,115 +1,174 @@ 'use client'; -import { Suspense, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { Loader2, AlertCircle, CheckCircle2 } from "lucide-react"; import { useAuth } from '@/contexts/AuthContext'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { ExternalLinkIcon, DiscordLogoIcon, ChatBubbleIcon } from "@radix-ui/react-icons"; +import { Wallet, Loader2 } from 'lucide-react'; +import { WalletConnector } from '@/components/web3/WalletConnector'; +import { WalletConnectorDialog } from '@/components/web3/WalletConnectorDialog'; +import { WalletAuthDialog } from '@/components/web3/WalletAuthDialog'; +import { useWallet } from '@/contexts/WalletContext'; -function AuthContent() { - const router = useRouter(); - const searchParams = useSearchParams(); - const { refresh } = useAuth(); - const token = searchParams?.get('token'); - const from = searchParams?.get('from') || '/'; - const message = searchParams?.get('message'); - const [error, setError] = useState(null); - const [success, setSuccess] = useState(false); - const [isLoading, setIsLoading] = useState(false); +function DiscordAuthDialog({ open, onOpenChange }: { open: boolean; onOpenChange: (open: boolean) => void }) { + return ( + + + + Authenticate with Discord + + To authenticate with Discord, please follow these steps: + + +
+
    +
  1. Join our Discord server if you haven’t already
  2. +
  3. Navigate to the authentication channel
  4. +
  5. Click the “🔐 Login To MEF” button in the login dashboard
  6. +
+ +
+
+
+ ); +} - useEffect(() => { - if (!token) { - if (message) { - setError(message); - } else { - setError("No authentication token provided"); - } - return; - } +function AuthenticationOptions() { + const [showDiscordDialog, setShowDiscordDialog] = useState(false); + const [showWalletDialog, setShowWalletDialog] = useState(false); + const { state } = useWallet(); - async function authenticate() { - setIsLoading(true); - setError(null); - try { - const res = await fetch('/api/auth/exchange', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ initialToken: token }), - credentials: 'include', - }); - - if (!res.ok) { - const data = await res.json(); - throw new Error(data.error || 'Authentication failed'); - } - - await refresh(); - - setSuccess(true); - // Small delay to show success message - setTimeout(() => { - router.push(from); - }, 1000); - } catch (err) { - setError(err instanceof Error ? err.message : 'Authentication failed'); - } finally { - setIsLoading(false); - } + const handleWalletAuth = () => { + if (state.wallet) { + // If wallet is already connected, show auth dialog directly + setShowWalletDialog(true); + } else { + // If no wallet connected, show connector dialog first + setShowWalletConnector(true); } + }; + + const [showWalletConnector, setShowWalletConnector] = useState(false); - authenticate(); - }, [token, from, router, message, refresh]); + // Watch for wallet connection state changes + useEffect(() => { + if (state.wallet && showWalletConnector) { + // When wallet gets connected, close connector and show auth dialog + setShowWalletConnector(false); + setShowWalletDialog(true); + } + }, [state.wallet, showWalletConnector]); return ( - Authentication + Welcome to MEF - {isLoading ? "Please wait while we authenticate your session..." : - success ? "Authentication successful!" : - "Secure authentication required"} + Choose how you’d like to authenticate to continue - {isLoading && ( -
- -

Authenticating...

-
- )} - - {error && ( - - - Authentication Error - {error} - - )} - - {success && ( - + + + + + + + + + + Choose your preferred authentication method. You’ll be able to link multiple methods later. + + + + + + + +
); } export default function AuthPage() { - return ( -
- { + let mounted = true; + + const redirect = () => { + if (mounted && !isLoading && user) { + router.push('/'); + } + }; + + redirect(); + + return () => { + mounted = false; + }; + }, [user, isLoading, router]); + + if (isLoading) { + return ( +
Loading... @@ -119,11 +178,17 @@ export default function AuthPage() { - }> - Loading...
}> - -
- +
+ ); + } + + if (user) { + return null; // Will redirect in useEffect + } + + return ( +
+
); } \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts index 16c08c2..6e07701 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -257,7 +257,6 @@ function generateUnauthorizedResponse(routeType: RouteType, request: NextRequest const url = new URL("/auth", request.url); url.searchParams.set("from", request.nextUrl.pathname); - url.searchParams.set("message", "Please log in to continue"); return NextResponse.redirect(url); } From 7d50262ef82d3381cf2717974b3f6ecd6502e612 Mon Sep 17 00:00:00 2001 From: Illya Gerasymchuk Date: Fri, 6 Dec 2024 23:37:47 +0000 Subject: [PATCH 2/2] chore: bump verstion to 0.1.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f4909c6..e29afd4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pgt-web-app", - "version": "0.1.11", + "version": "0.1.12", "private": true, "type": "module", "scripts": {