From 8934cc610f192a7a9e9aac59457b6c2e8d5ebbb4 Mon Sep 17 00:00:00 2001 From: muhammed sinan Date: Fri, 27 Jun 2025 10:46:35 +0530 Subject: [PATCH 1/2] refactor: added auth hooks for handling sign and signup logics --- apps/web/src/app/(auth)/login/page.tsx | 214 ++++++++------------ apps/web/src/app/(auth)/signup/page.tsx | 257 ++++++++++-------------- apps/web/src/hooks/auth/useLogin.ts | 60 ++++++ apps/web/src/hooks/auth/useSignUp.ts | 65 ++++++ 4 files changed, 322 insertions(+), 274 deletions(-) create mode 100644 apps/web/src/hooks/auth/useLogin.ts create mode 100644 apps/web/src/hooks/auth/useSignUp.ts diff --git a/apps/web/src/app/(auth)/login/page.tsx b/apps/web/src/app/(auth)/login/page.tsx index 755784f..3e9478e 100644 --- a/apps/web/src/app/(auth)/login/page.tsx +++ b/apps/web/src/app/(auth)/login/page.tsx @@ -1,7 +1,6 @@ "use client"; import { useRouter } from "next/navigation"; -import { signIn } from "@opencut/auth/client"; import { Button } from "@/components/ui/button"; import { Card, @@ -10,7 +9,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { Suspense, useState } from "react"; +import { Suspense } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; @@ -18,121 +17,22 @@ import Link from "next/link"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { ArrowLeft, Loader2 } from "lucide-react"; import { GoogleIcon } from "@/components/icons"; - -function LoginForm() { - const router = useRouter(); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const [error, setError] = useState(null); - const [isEmailLoading, setIsEmailLoading] = useState(false); - const [isGoogleLoading, setIsGoogleLoading] = useState(false); - - const handleLogin = async () => { - setError(null); - setIsEmailLoading(true); - - const { error } = await signIn.email({ - email, - password, - }); - - if (error) { - setError(error.message || "An unexpected error occurred."); - setIsEmailLoading(false); - return; - } - - router.push("/editor"); - }; - - const handleGoogleLogin = async () => { - setError(null); - setIsGoogleLoading(true); - - try { - await signIn.social({ - provider: "google", - callbackURL: "/editor", - }); - } catch (error) { - setError("Failed to sign in with Google. Please try again."); - setIsGoogleLoading(false); - } - }; - - const isAnyLoading = isEmailLoading || isGoogleLoading; - - return ( -
- {error && ( - - Error - {error} - - )} - - -
-
- -
-
- - Or continue with - -
-
-
-
- - setEmail(e.target.value)} - disabled={isAnyLoading} - className="h-11" - /> -
-
- - setPassword(e.target.value)} - disabled={isAnyLoading} - className="h-11" - /> -
- -
-
- ); -} +import { useLogin } from "@/hooks/auth/useLogin"; export default function LoginPage() { const router = useRouter(); + const { + email, + setEmail, + password, + setPassword, + error, + isAnyLoading, + isEmailLoading, + isGoogleLoading, + handleLogin, + handleGoogleLogin, + } = useLogin(); return (
@@ -158,19 +58,83 @@ export default function LoginPage() {
} > - +
+ {error && ( + + Error + {error} + + )} + + +
+
+ +
+
+ + Or continue with + +
+
+
+
+ + setEmail(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
+ + setPassword(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+ +
+
+
+ Don't have an account?{" "} + + Sign up + +
-
- Don't have an account?{" "} - - Sign up - -
); -} +} \ No newline at end of file diff --git a/apps/web/src/app/(auth)/signup/page.tsx b/apps/web/src/app/(auth)/signup/page.tsx index 1c98b9e..e099e6d 100644 --- a/apps/web/src/app/(auth)/signup/page.tsx +++ b/apps/web/src/app/(auth)/signup/page.tsx @@ -1,7 +1,6 @@ "use client"; import { useRouter } from "next/navigation"; -import { signUp, signIn } from "@opencut/auth/client"; import { Button } from "@/components/ui/button"; import { Card, @@ -10,151 +9,32 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { Suspense, useState } from "react"; +import { Suspense } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; import Link from "next/link"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { Loader2, ArrowLeft } from "lucide-react"; +import { ArrowLeft, Loader2 } from "lucide-react"; import { GoogleIcon } from "@/components/icons"; - -function SignUpForm() { - const router = useRouter(); - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const [error, setError] = useState(null); - const [isEmailLoading, setIsEmailLoading] = useState(false); - const [isGoogleLoading, setIsGoogleLoading] = useState(false); - - const handleSignUp = async () => { - setError(null); - setIsEmailLoading(true); - - const { error } = await signUp.email({ - name, - email, - password, - }); - - if (error) { - setError(error.message || "An unexpected error occurred."); - setIsEmailLoading(false); - return; - } - - router.push("/login"); - }; - - const handleGoogleSignUp = async () => { - setError(null); - setIsGoogleLoading(true); - - try { - await signIn.social({ - provider: "google", - }); - - router.push("/editor"); - } catch (error) { - setError("Failed to sign up with Google. Please try again."); - setIsGoogleLoading(false); - } - }; - - const isAnyLoading = isEmailLoading || isGoogleLoading; - - return ( -
- {error && ( - - Error - {error} - - )} - - - -
-
- -
-
- - Or continue with - -
-
- -
-
- - setName(e.target.value)} - disabled={isAnyLoading} - className="h-11" - /> -
-
- - setEmail(e.target.value)} - disabled={isAnyLoading} - className="h-11" - /> -
-
- - setPassword(e.target.value)} - disabled={isAnyLoading} - className="h-11" - /> -
- -
-
- ); -} +import { useSignUp } from "@/hooks/auth/useSignUp"; export default function SignUpPage() { const router = useRouter(); + const { + name, + setName, + email, + setEmail, + password, + setPassword, + error, + isAnyLoading, + isEmailLoading, + isGoogleLoading, + handleSignUp, + handleGoogleSignUp, + } = useSignUp(); return (
@@ -165,7 +45,6 @@ export default function SignUpPage() { > Back - @@ -183,19 +62,99 @@ export default function SignUpPage() {
} > - +
+ {error && ( + + Error + {error} + + )} + +
+
+ +
+
+ + Or continue with + +
+
+
+
+ + setName(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
+ + setEmail(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
+ + setPassword(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+ +
+
+
+ Already have an account?{" "} + + Sign in + +
-
- Already have an account?{" "} - - Sign in - -
); -} +} \ No newline at end of file diff --git a/apps/web/src/hooks/auth/useLogin.ts b/apps/web/src/hooks/auth/useLogin.ts new file mode 100644 index 0000000..3737deb --- /dev/null +++ b/apps/web/src/hooks/auth/useLogin.ts @@ -0,0 +1,60 @@ +import { useCallback, useState } from "react"; +import { useRouter } from "next/navigation"; +import { signIn } from "@opencut/auth/client"; + +export function useLogin() { + const router = useRouter(); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(null); + const [isEmailLoading, setIsEmailLoading] = useState(false); + const [isGoogleLoading, setIsGoogleLoading] = useState(false); + + const handleLogin = useCallback(async () => { + setError(null); + setIsEmailLoading(true); + + const { error } = await signIn.email({ + email, + password, + }); + + if (error) { + setError(error.message || "An unexpected error occurred."); + setIsEmailLoading(false); + return; + } + + router.push("/editor"); + }, [router, email, password]); + + const handleGoogleLogin = async () => { + setError(null); + setIsGoogleLoading(true); + + try { + await signIn.social({ + provider: "google", + callbackURL: "/editor", + }); + } catch (error) { + setError("Failed to sign in with Google. Please try again."); + setIsGoogleLoading(false); + } + }; + + const isAnyLoading = isEmailLoading || isGoogleLoading; + + return { + email, + setEmail, + password, + setPassword, + error, + isEmailLoading, + isGoogleLoading, + isAnyLoading, + handleLogin, + handleGoogleLogin, + }; +} diff --git a/apps/web/src/hooks/auth/useSignUp.ts b/apps/web/src/hooks/auth/useSignUp.ts new file mode 100644 index 0000000..4cd2850 --- /dev/null +++ b/apps/web/src/hooks/auth/useSignUp.ts @@ -0,0 +1,65 @@ +import { useState, useCallback } from "react"; +import { useRouter } from "next/navigation"; +import { signUp, signIn } from "@opencut/auth/client"; + +export function useSignUp() { + const router = useRouter(); + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(null); + const [isEmailLoading, setIsEmailLoading] = useState(false); + const [isGoogleLoading, setIsGoogleLoading] = useState(false); + + const handleSignUp = useCallback(async () => { + setError(null); + setIsEmailLoading(true); + + const { error } = await signUp.email({ + name, + email, + password, + }); + + if (error) { + setError(error.message || "An unexpected error occurred."); + setIsEmailLoading(false); + return; + } + + router.push("/login"); + }, [name, email, password, router]); + + const handleGoogleSignUp = useCallback(async () => { + setError(null); + setIsGoogleLoading(true); + + try { + await signIn.social({ + provider: "google", + }); + + router.push("/editor"); + } catch (error) { + setError("Failed to sign up with Google. Please try again."); + setIsGoogleLoading(false); + } + }, [router]); + + const isAnyLoading = isEmailLoading || isGoogleLoading; + + return { + name, + setName, + email, + setEmail, + password, + setPassword, + error, + isEmailLoading, + isGoogleLoading, + isAnyLoading, + handleSignUp, + handleGoogleSignUp, + }; +} \ No newline at end of file From 901d0baafdaaa1dd133cb59621acdd35c78885a5 Mon Sep 17 00:00:00 2001 From: muhammed sinan Date: Fri, 27 Jun 2025 10:58:21 +0530 Subject: [PATCH 2/2] added memoization --- apps/web/src/app/(auth)/login/page.tsx | 8 +++++--- apps/web/src/app/(auth)/signup/page.tsx | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/web/src/app/(auth)/login/page.tsx b/apps/web/src/app/(auth)/login/page.tsx index 3e9478e..ec79bd7 100644 --- a/apps/web/src/app/(auth)/login/page.tsx +++ b/apps/web/src/app/(auth)/login/page.tsx @@ -9,7 +9,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { Suspense } from "react"; +import { memo, Suspense } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; @@ -19,7 +19,7 @@ import { ArrowLeft, Loader2 } from "lucide-react"; import { GoogleIcon } from "@/components/icons"; import { useLogin } from "@/hooks/auth/useLogin"; -export default function LoginPage() { +const LoginPage = () => { const router = useRouter(); const { email, @@ -137,4 +137,6 @@ export default function LoginPage() { ); -} \ No newline at end of file +} + +export default memo(LoginPage); diff --git a/apps/web/src/app/(auth)/signup/page.tsx b/apps/web/src/app/(auth)/signup/page.tsx index e099e6d..e970521 100644 --- a/apps/web/src/app/(auth)/signup/page.tsx +++ b/apps/web/src/app/(auth)/signup/page.tsx @@ -9,7 +9,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { Suspense } from "react"; +import { memo, Suspense } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; @@ -19,7 +19,7 @@ import { ArrowLeft, Loader2 } from "lucide-react"; import { GoogleIcon } from "@/components/icons"; import { useSignUp } from "@/hooks/auth/useSignUp"; -export default function SignUpPage() { +const SignUpPage = () => { const router = useRouter(); const { name, @@ -157,4 +157,6 @@ export default function SignUpPage() { ); -} \ No newline at end of file +} + +export default memo(SignUpPage);