From 242ea2185eaf45dcfe7f2bc9afaeaf30f8e8d22a Mon Sep 17 00:00:00 2001 From: Dudi Zimberknopf Date: Wed, 10 Apr 2024 15:37:09 +0300 Subject: [PATCH 1/7] get params from query --- app/login/page.tsx | 173 +++++++++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 68 deletions(-) diff --git a/app/login/page.tsx b/app/login/page.tsx index 029b410d..10855117 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -1,81 +1,118 @@ -'use client' +"use client"; -import { Label } from "@/components/ui/label" -import { Input } from "@/components/ui/input" -import { Button } from "@/components/ui/button" -import { SignInOptions, SignInResponse, signIn } from "next-auth/react" -import { FormEvent, useRef, useState } from "react" -import { useRouter } from "next/navigation" +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { SignInOptions, SignInResponse, signIn } from "next-auth/react"; +import { FormEvent, useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; -const DEFAULT_HOST = 'localhost'; -const DEFAULT_PORT = '6379'; +const DEFAULT_HOST = "localhost"; +const DEFAULT_PORT = "6379"; export default function Page() { + const router = useRouter(); + const [error, setError] = useState(false); - const router = useRouter() - const [error, setError] = useState(false) + const url = new URL(window.location.href); - const host = useRef(null); - const port = useRef(null); - const username = useRef(null); - const password = useRef(null); + const [host, setHost] = useState(DEFAULT_HOST); + const [port, setPort] = useState(DEFAULT_PORT); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); - const onSubmit = (e: FormEvent) => { - e.preventDefault(); + useEffect(() => { + // Get initial data from query params + const hostParam = url.searchParams.get("host"); + const portParam = url.searchParams.get("port"); + const usernameParam = url.searchParams.get("username"); - const params: SignInOptions = { - redirect: false, - host: host.current?.value ?? DEFAULT_HOST, - port: port.current?.value ?? DEFAULT_PORT, - } - if (username.current) { - params.username = username.current.value; - } - if (password.current) { - params.password = password.current.value; - } + setHost(hostParam ?? DEFAULT_HOST); + setPort(portParam ?? DEFAULT_PORT); + setUsername(usernameParam ?? ""); + }, [url.searchParams]); - signIn( - "credentials", - params - ).then((res?: SignInResponse) => { - if (res && res.error) { - setError(true) - } else { - router.push('/graph'); - } + const onSubmit = (e: FormEvent) => { + e.preventDefault(); - }) + const params: SignInOptions = { + redirect: false, + host: host ?? DEFAULT_HOST, + port: port ?? DEFAULT_PORT, }; + if (username) { + params.username = username; + } + if (password) { + params.password = password; + } - return ( -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- {error && -
-

Wrong credentials

-
- } -
+ signIn("credentials", params).then((res?: SignInResponse) => { + if (res && res.error) { + setError(true); + } else { + router.push("/graph"); + } + }); + }; + + return ( +
+
+
+ + setHost(e.target.value)} + value={host} + /> +
+
+ + setPort(e.target.value)} + value={port} + /> +
+
+ + setUsername(e.target.value)} + value={username} + /> +
+
+ + setPassword(e.target.value)} + value={password} + /> +
+
+
- ) -} \ No newline at end of file + {error && ( +
+

Wrong credentials

+
+ )} +
+
+ ); +} From dbc1a23e30b86a56e6403fc8d71138f8a73d0932 Mon Sep 17 00:00:00 2001 From: Dudi Zimberknopf Date: Wed, 10 Apr 2024 15:50:18 +0300 Subject: [PATCH 2/7] check if "window" is not undefined --- app/login/page.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/login/page.tsx b/app/login/page.tsx index 10855117..6aa0890d 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -14,15 +14,18 @@ export default function Page() { const router = useRouter(); const [error, setError] = useState(false); - const url = new URL(window.location.href); - const [host, setHost] = useState(DEFAULT_HOST); const [port, setPort] = useState(DEFAULT_PORT); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); useEffect(() => { - // Get initial data from query params + if (typeof window === "undefined") { + return; + } + + const url = new URL(window.location.href); + const hostParam = url.searchParams.get("host"); const portParam = url.searchParams.get("port"); const usernameParam = url.searchParams.get("username"); @@ -30,7 +33,7 @@ export default function Page() { setHost(hostParam ?? DEFAULT_HOST); setPort(portParam ?? DEFAULT_PORT); setUsername(usernameParam ?? ""); - }, [url.searchParams]); + }, []); const onSubmit = (e: FormEvent) => { e.preventDefault(); From afe9956c13b72a431c1ef7df1439cff77069f761 Mon Sep 17 00:00:00 2001 From: Dudi Zimberknopf Date: Wed, 10 Apr 2024 22:54:00 +0300 Subject: [PATCH 3/7] get query params in a more "react" way --- app/login/page.tsx | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/app/login/page.tsx b/app/login/page.tsx index 6aa0890d..90b8aeb0 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -4,8 +4,8 @@ import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { SignInOptions, SignInResponse, signIn } from "next-auth/react"; -import { FormEvent, useEffect, useState } from "react"; -import { useRouter } from "next/navigation"; +import { FormEvent, use, useEffect, useState } from "react"; +import { useRouter, useSearchParams } from "next/navigation"; const DEFAULT_HOST = "localhost"; const DEFAULT_PORT = "6379"; @@ -19,21 +19,17 @@ export default function Page() { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); - useEffect(() => { - if (typeof window === "undefined") { - return; - } + const searchParams = useSearchParams(); - const url = new URL(window.location.href); - - const hostParam = url.searchParams.get("host"); - const portParam = url.searchParams.get("port"); - const usernameParam = url.searchParams.get("username"); + useEffect(() => { + const hostParam = searchParams.get("host"); + const portParam = searchParams.get("port"); + const usernameParam = searchParams.get("username"); setHost(hostParam ?? DEFAULT_HOST); setPort(portParam ?? DEFAULT_PORT); setUsername(usernameParam ?? ""); - }, []); + }, [searchParams]); const onSubmit = (e: FormEvent) => { e.preventDefault(); From d75bf1f20043a94e9d9ede21b5cad5fd9a165375 Mon Sep 17 00:00:00 2001 From: Dudi Zimberknopf Date: Wed, 10 Apr 2024 22:58:36 +0300 Subject: [PATCH 4/7] remove unused var --- app/login/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/login/page.tsx b/app/login/page.tsx index 90b8aeb0..1f352e15 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -4,7 +4,7 @@ import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { SignInOptions, SignInResponse, signIn } from "next-auth/react"; -import { FormEvent, use, useEffect, useState } from "react"; +import { FormEvent, useEffect, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; const DEFAULT_HOST = "localhost"; From 56750d8ba83cafc89caa2e77d971058311a823f9 Mon Sep 17 00:00:00 2001 From: Dudi Zimberknopf Date: Wed, 10 Apr 2024 23:04:30 +0300 Subject: [PATCH 5/7] add `suspense` for `useSearchParams` --- app/layout.tsx | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/app/layout.tsx b/app/layout.tsx index 262cc365..655398d0 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,30 +1,33 @@ -import './globals.css' -import type { Metadata } from 'next' -import { Inter } from 'next/font/google' -import { Toaster } from '@/components/ui/toaster' -import { cn } from '@/lib/utils' -import NextAuthProvider from './providers' +import "./globals.css"; +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import { Toaster } from "@/components/ui/toaster"; +import { cn } from "@/lib/utils"; +import { Suspense } from "react"; +import NextAuthProvider from "./providers"; -const inter = Inter({ subsets: ['latin'] }) +const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { - title: 'FalkorDB Browser', - description: 'FalkorDB Browser is a web-based UI for FalkorDB.', -} + title: "FalkorDB Browser", + description: "FalkorDB Browser is a web-based UI for FalkorDB.", +}; export default function RootLayout({ children, }: { - children: React.ReactNode + children: React.ReactNode; }) { - // Setting suppressHydrationWarning on html tag to prevent warning + // Setting suppressHydrationWarning on html tag to prevent warning // caused by mismatched client/server content caused by next-themes return ( - {children} - + + {children} + + - ) + ); } From 266726bc86c3d6c780000c9b17e4ab33f4ea7085 Mon Sep 17 00:00:00 2001 From: Dudi Zimberknopf Date: Thu, 11 Apr 2024 09:39:14 +0300 Subject: [PATCH 6/7] refactor our suspense only to the login form component --- app/components/LoginForm.tsx | 115 +++++++++++++++++++++++++++++++++++ app/layout.tsx | 5 +- app/login/page.tsx | 115 ++--------------------------------- 3 files changed, 121 insertions(+), 114 deletions(-) create mode 100644 app/components/LoginForm.tsx diff --git a/app/components/LoginForm.tsx b/app/components/LoginForm.tsx new file mode 100644 index 00000000..9079e9a9 --- /dev/null +++ b/app/components/LoginForm.tsx @@ -0,0 +1,115 @@ +"use client"; + +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { SignInOptions, SignInResponse, signIn } from "next-auth/react"; +import { FormEvent, useEffect, useState } from "react"; +import { useRouter, useSearchParams } from "next/navigation"; + +const DEFAULT_HOST = "localhost"; +const DEFAULT_PORT = "6379"; + +export default function LoginForm() { + const router = useRouter(); + const [error, setError] = useState(false); + + const [host, setHost] = useState(DEFAULT_HOST); + const [port, setPort] = useState(DEFAULT_PORT); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + + const searchParams = useSearchParams(); + + useEffect(() => { + const hostParam = searchParams.get("host"); + const portParam = searchParams.get("port"); + const usernameParam = searchParams.get("username"); + + setHost(hostParam ?? DEFAULT_HOST); + setPort(portParam ?? DEFAULT_PORT); + setUsername(usernameParam ?? ""); + }, [searchParams]); + + const onSubmit = (e: FormEvent) => { + e.preventDefault(); + + const params: SignInOptions = { + redirect: false, + host: host ?? DEFAULT_HOST, + port: port ?? DEFAULT_PORT, + }; + if (username) { + params.username = username; + } + if (password) { + params.password = password; + } + + signIn("credentials", params).then((res?: SignInResponse) => { + if (res && res.error) { + setError(true); + } else { + router.push("/graph"); + } + }); + }; + + return ( +
+
+ + setHost(e.target.value)} + value={host} + /> +
+
+ + setPort(e.target.value)} + value={port} + /> +
+
+ + setUsername(e.target.value)} + value={username} + /> +
+
+ + setPassword(e.target.value)} + value={password} + /> +
+
+ +
+ {error && ( +
+

Wrong credentials

+
+ )} +
+ ); +} diff --git a/app/layout.tsx b/app/layout.tsx index 655398d0..42454066 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -3,7 +3,6 @@ import type { Metadata } from "next"; import { Inter } from "next/font/google"; import { Toaster } from "@/components/ui/toaster"; import { cn } from "@/lib/utils"; -import { Suspense } from "react"; import NextAuthProvider from "./providers"; const inter = Inter({ subsets: ["latin"] }); @@ -23,9 +22,7 @@ export default function RootLayout({ return ( - - {children} - + {children} diff --git a/app/login/page.tsx b/app/login/page.tsx index 1f352e15..7852cd78 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -1,117 +1,12 @@ -"use client"; - -import { Label } from "@/components/ui/label"; -import { Input } from "@/components/ui/input"; -import { Button } from "@/components/ui/button"; -import { SignInOptions, SignInResponse, signIn } from "next-auth/react"; -import { FormEvent, useEffect, useState } from "react"; -import { useRouter, useSearchParams } from "next/navigation"; - -const DEFAULT_HOST = "localhost"; -const DEFAULT_PORT = "6379"; +import { Suspense } from "react"; +import LoginForm from "../components/LoginForm"; export default function Page() { - const router = useRouter(); - const [error, setError] = useState(false); - - const [host, setHost] = useState(DEFAULT_HOST); - const [port, setPort] = useState(DEFAULT_PORT); - const [username, setUsername] = useState(""); - const [password, setPassword] = useState(""); - - const searchParams = useSearchParams(); - - useEffect(() => { - const hostParam = searchParams.get("host"); - const portParam = searchParams.get("port"); - const usernameParam = searchParams.get("username"); - - setHost(hostParam ?? DEFAULT_HOST); - setPort(portParam ?? DEFAULT_PORT); - setUsername(usernameParam ?? ""); - }, [searchParams]); - - const onSubmit = (e: FormEvent) => { - e.preventDefault(); - - const params: SignInOptions = { - redirect: false, - host: host ?? DEFAULT_HOST, - port: port ?? DEFAULT_PORT, - }; - if (username) { - params.username = username; - } - if (password) { - params.password = password; - } - - signIn("credentials", params).then((res?: SignInResponse) => { - if (res && res.error) { - setError(true); - } else { - router.push("/graph"); - } - }); - }; - return (
-
-
- - setHost(e.target.value)} - value={host} - /> -
-
- - setPort(e.target.value)} - value={port} - /> -
-
- - setUsername(e.target.value)} - value={username} - /> -
-
- - setPassword(e.target.value)} - value={password} - /> -
-
- -
- {error && ( -
-

Wrong credentials

-
- )} -
+ + +
); } From 72889943afbc45446b2e888aed985be62e9a98e1 Mon Sep 17 00:00:00 2001 From: Dudi Zimberknopf Date: Thu, 11 Apr 2024 09:44:29 +0300 Subject: [PATCH 7/7] add `decodeURIComponent` --- app/components/LoginForm.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/components/LoginForm.tsx b/app/components/LoginForm.tsx index 9079e9a9..8d663b20 100644 --- a/app/components/LoginForm.tsx +++ b/app/components/LoginForm.tsx @@ -26,9 +26,9 @@ export default function LoginForm() { const portParam = searchParams.get("port"); const usernameParam = searchParams.get("username"); - setHost(hostParam ?? DEFAULT_HOST); - setPort(portParam ?? DEFAULT_PORT); - setUsername(usernameParam ?? ""); + setHost(decodeURIComponent(hostParam ?? DEFAULT_HOST)); + setPort(decodeURIComponent(portParam ?? DEFAULT_PORT)); + setUsername(decodeURIComponent(usernameParam ?? "")); }, [searchParams]); const onSubmit = (e: FormEvent) => {