draupnir4all-web

git clone git://archive.git.mtrnord.blog/MTRNord/draupnir4all-web.git
Log | Files | Refs | README | LICENSE

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&apos;s format is &quot;@localpart:example.com&quot;.</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 }