page.tsx (9299B)
1 "use client" 2 3 import { useCallback, useEffect, useState } from "react" 4 import Link from "next/link" 5 import { Shield, ArrowRight, Loader2, X } from "lucide-react" 6 import { Button } from "@/components/ui/button" 7 import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" 8 import { Input } from "@/components/ui/input" 9 import { Label } from "@/components/ui/label" 10 import { useSession } from "@/contexts/session-context" 11 import RedirectionPageClient from "@/components/redirect-workaround" 12 13 export default function RegisterPage() { 14 const { isLoading, register, discoveryStatus, homeserverUrl, discoverHomeserver, user } = useSession(); 15 const [loginLoading, setLoginLoading] = useState(isLoading) 16 const [matrixId, setMatrixId] = useState("") 17 const [step, setStep] = useState<"initial" | "login" | "error">("initial") 18 const [password, setPassword] = useState("") 19 const [errorMessage, setErrorMessage] = useState("") 20 21 useEffect(() => { 22 console.log("Discovery status changed:", discoveryStatus) 23 if (discoveryStatus === "loading") { 24 setLoginLoading(true) 25 } else if (discoveryStatus === "error") { 26 setErrorMessage("Failed to discover homeserver. Please check your Matrix ID format.") 27 setLoginLoading(false) 28 } else if (discoveryStatus === "success") { 29 setErrorMessage("") 30 setLoginLoading(false) 31 } 32 }, [discoveryStatus]) 33 34 const startMatrixAuth = useCallback(() => { 35 if (!matrixId) return 36 setLoginLoading(true) 37 discoverHomeserver(matrixId).then(() => { 38 setStep("login") 39 }).catch((err) => { 40 console.error("Error discovering homeserver:", err) 41 setErrorMessage("Please check your Matrix ID format. It should be like @username:matrix.org") 42 setStep("error") 43 setLoginLoading(false) 44 }); 45 }, [matrixId, discoverHomeserver]); 46 47 const handleSubmit = useCallback(async (e: React.FormEvent) => { 48 e.preventDefault() 49 setErrorMessage("") 50 51 try { 52 await register(matrixId, password) 53 } catch (err) { 54 console.error("Login failed:", err) 55 setErrorMessage("Login failed. Please check your credentials.") 56 } 57 }, [register, matrixId, password]) 58 59 if (user) { 60 return <RedirectionPageClient redirectUrl="/dashboard" replace /> 61 } 62 63 return ( 64 <div className="flex min-h-screen flex-col bg-black text-white"> 65 <header className="border-b border-gray-800 bg-black py-4"> 66 <div className="container flex items-center justify-between px-4 md:px-6"> 67 <Link href="/" className="flex items-center gap-2"> 68 <Shield className="h-6 w-6 text-purple-400" /> 69 <span className="text-xl font-bold tracking-tighter">Draupnir4All</span> 70 </Link> 71 </div> 72 </header> 73 <main className="flex-1 flex items-center justify-center p-4"> 74 <Card className="w-full max-w-md border-gray-800 bg-gray-950"> 75 <CardHeader> 76 <CardTitle className="text-2xl">Register with Matrix</CardTitle> 77 <CardDescription className="text-gray-400"> 78 Use your Matrix account to register for Draupnir4All 79 </CardDescription> 80 </CardHeader> 81 <CardContent className="space-y-4"> 82 {step === "initial" && ( 83 <div className="space-y-4"> 84 <div className="space-y-2"> 85 <Label htmlFor="matrix-id">Matrix ID</Label> 86 <Input 87 id="matrix-id" 88 placeholder="@username:matrix.org" 89 className="bg-gray-900 border-gray-800" 90 value={matrixId} 91 onChange={(e) => setMatrixId(e.target.value)} 92 /> 93 <p className="text-xs text-gray-400">Enter your Matrix ID to begin the authentication process</p> 94 </div> 95 </div> 96 )} 97 98 {step === "login" && ( 99 <form onSubmit={handleSubmit} className="space-y-4"> 100 <div className="space-y-2"> 101 <div className="flex items-center justify-between"> 102 <Label htmlFor="matrix-username">Matrix ID</Label> 103 <Button type="button" variant="ghost" size="sm" className="h-6 px-2 text-gray-400" onClick={() => setStep("initial")}> 104 <X className="h-4 w-4" /> 105 </Button> 106 </div> 107 <div className="flex items-center gap-2 rounded-md bg-gray-900 px-3 py-2 text-sm"> 108 <span>{matrixId}</span> 109 </div> 110 111 {discoveryStatus === "loading" && ( 112 <div className="flex items-center gap-2 text-xs text-gray-400"> 113 <Loader2 className="h-3 w-3 animate-spin" /> 114 Discovering homeserver... 115 </div> 116 )} 117 118 {discoveryStatus === "success" && homeserverUrl && ( 119 <p className="text-xs text-gray-400">Authenticating with {homeserverUrl.replace(/^https?:\/\//, "")}</p> 120 )} 121 122 {discoveryStatus === "error" && ( 123 <p className="text-xs text-red-400">Failed to discover homeserver. Please check your Matrix ID and ensure it's format is "@localpart:example.com".</p> 124 )} 125 </div> 126 127 {discoveryStatus === "success" && ( 128 <div className="space-y-2"> 129 <Label htmlFor="matrix-password">Password</Label> 130 <Input 131 id="matrix-password" 132 type="password" 133 placeholder="Enter your Matrix password" 134 className="bg-gray-900 border-gray-800" 135 value={password} 136 onChange={(e) => setPassword(e.target.value)} 137 required 138 /> 139 </div> 140 )} 141 142 <div className="flex gap-2"> 143 <Button 144 type="submit" 145 className="flex-1 bg-purple-600 text-white hover:bg-purple-700" 146 disabled={isLoading || !password || discoveryStatus !== "success"} 147 > 148 {isLoading ? ( 149 <> 150 <Loader2 className="mr-2 h-4 w-4 animate-spin" /> 151 Authenticating... 152 </> 153 ) : ( 154 "Log in" 155 )} 156 </Button> 157 <Button 158 type="button" 159 variant="outline" 160 className="border-gray-700 text-gray-400 hover:bg-gray-900 hover:text-gray-300" 161 onClick={() => { 162 setStep("initial") 163 setMatrixId("") 164 setPassword("") 165 }} 166 disabled={isLoading} 167 > 168 Cancel 169 </Button> 170 </div> 171 172 <p className="text-xs text-gray-400 text-center"> 173 Your credentials are sent directly to your Matrix homeserver. Draupnir4All only receives a verification token. 174 </p> 175 </form> 176 )} 177 178 {((isLoading || loginLoading) && discoveryStatus !== "loading") && ( 179 <div className="flex flex-col items-center justify-center py-6 space-y-4"> 180 <Loader2 className="h-8 w-8 animate-spin text-purple-400" /> 181 <p className="text-gray-300">Registering your account...</p> 182 <p className="text-xs text-gray-400">Setting up your Draupnir4All account</p> 183 </div> 184 )} 185 186 {((isLoading || loginLoading) && discoveryStatus === "loading") && ( 187 <div className="flex flex-col items-center justify-center py-6 space-y-4"> 188 <Loader2 className="h-8 w-8 animate-spin text-purple-400" /> 189 <p className="text-gray-300">Discovering the Homeserver URL...</p> 190 </div> 191 )} 192 193 {step === "error" && ( 194 <div className="rounded-md bg-red-900/20 border border-red-800 p-4 text-center"> 195 <p className="text-red-300 font-medium">Registration Failed</p> 196 <p className="text-sm text-red-200 mt-1">{errorMessage}</p> 197 <Button 198 variant="outline" 199 className="mt-4 border-red-500 text-red-400 hover:bg-red-950 hover:text-red-300" 200 onClick={() => setStep("initial")} 201 > 202 Try Again 203 </Button> 204 </div> 205 )} 206 </CardContent> 207 <CardFooter> 208 {step === "initial" && ( 209 <Button 210 className="w-full bg-purple-600 text-white hover:bg-purple-700" 211 onClick={startMatrixAuth} 212 disabled={!matrixId} 213 > 214 Continue 215 <ArrowRight className="ml-2 h-4 w-4" /> 216 </Button> 217 )} 218 </CardFooter> 219 </Card> 220 </main> 221 </div> 222 ) 223 }