feat(get session and push to protected route)

This commit is contained in:
vergiLgood1 2025-02-20 02:26:47 +07:00
parent 99781de44c
commit 7c58a7e46c
7 changed files with 105 additions and 58 deletions

View File

@ -0,0 +1,39 @@
"use server";
import { createClient } from "@/utils/supabase/server";
export const checkSession = async () => {
const supabase = await createClient();
try {
const {
data: { session },
error,
} = await supabase.auth.getSession();
if (error) {
return {
success: false,
error: error.message,
};
}
if (session) {
return {
success: true,
session,
redirectTo: "/protected/dashboard", // or your preferred authenticated route
};
}
return {
success: false,
message: "No active session",
};
} catch (error) {
return {
success: false,
error: "An unexpected error occurred",
};
}
};

View File

@ -1,9 +1,17 @@
import { checkSession } from "@/actions/auth/session";
import { redirect } from "next/navigation";
export default async function Layout({ export default async function Layout({
children, children,
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {
return ( const sessionResult = await checkSession();
<div className="max-w-full gap-12 items-start">{children}</div>
); // If there's an active session, redirect to dashboard
if (sessionResult.success && sessionResult.redirectTo) {
redirect(sessionResult.redirectTo);
}
return <div className="max-w-full gap-12 items-start">{children}</div>;
} }

View File

@ -1,5 +1,4 @@
import { FormMessage, Message } from "@/components/form-message"; import { FormMessage, Message } from "@/components/form-message";
import { LoginForm } from "@/components/auth/login-form";
import { SubmitButton } from "@/components/submit-button"; import { SubmitButton } from "@/components/submit-button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";

View File

@ -31,6 +31,7 @@ export default function RootLayout({
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
return ( return (
<html lang="en" className={geistSans.className} suppressHydrationWarning> <html lang="en" className={geistSans.className} suppressHydrationWarning>
<body className="bg-background text-foreground"> <body className="bg-background text-foreground">

View File

@ -1,16 +1,29 @@
import { cn } from "@/lib/utils"; "use client";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Github, Lock } from "lucide-react"; import { Github, Lock } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { SubmitButton } from "../submit-button"; import { SubmitButton } from "../submit-button";
import { signInAction } from "@/actions/auth/sign-in";
import { FormField } from "../form-field";
import { useSignInForm } from "@/src/infrastructure/hooks/use-signin";
export function LoginForm2({ export function LoginForm2({
className, className,
...props ...props
}: React.ComponentPropsWithoutRef<"form">) { }: React.ComponentPropsWithoutRef<"form">) {
const {
formData,
errors,
isSubmitting,
setFormData,
handleChange,
handleSelectChange,
handleSubmit,
} = useSignInForm();
return ( return (
<div> <div>
<div className="flex-1 flex items-center justify-center px-6"> <div className="flex-1 flex items-center justify-center px-6">
@ -35,6 +48,7 @@ export function LoginForm2({
variant="outline" variant="outline"
className="w-full bg-[#1C1C1C] text-white border-gray-800 hover:bg-[#2C2C2C] hover:border-gray-700" className="w-full bg-[#1C1C1C] text-white border-gray-800 hover:bg-[#2C2C2C] hover:border-gray-700"
size="lg" size="lg"
disabled={isSubmitting}
> >
<Lock className="mr-2 h-5 w-5" /> <Lock className="mr-2 h-5 w-5" />
Continue with SSO Continue with SSO
@ -50,51 +64,35 @@ export function LoginForm2({
</div> </div>
</div> </div>
<form className="space-y-4" {...props}> <form onSubmit={handleSubmit} className="space-y-4" {...props}>
<div className="space-y-2"> <FormField
<Label htmlFor="email" className="text-sm text-gray-300"> label="Email"
Email input={
</Label>
<Input <Input
id="email" id="email"
type="email" type="email"
name="email" name="email"
placeholder="you@example.com" placeholder="you@example.com"
className="bg-[#1C1C1C] border-gray-800 text-white placeholder:text-gray-500 focus:border-emerald-600 focus:ring-emerald-600" className={`bg-[#1C1C1C] border-gray-800 text-white placeholder:text-gray-500 focus:border-emerald-600 focus:ring-emerald-600 ${
required errors.email ? "border-red-500" : ""
}`}
value={formData.email}
onChange={handleChange}
disabled={isSubmitting}
/> />
<Link }
error={errors.email}
/>
{/* <Link
href="email-recovery" href="email-recovery"
className="flex items-end justify-end text-xs text-gray-400 hover:text-emerald-500" className="flex items-end justify-end text-xs text-gray-400 hover:text-emerald-500"
> >
Forgot Email? Forgot Email?
</Link>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
{/* <Label htmlFor="password" className="text-sm text-gray-300">
Password
</Label> */}
{/* <Link
href="#"
className="text-xs text-gray-400 hover:text-gray-300"
>
Forgot Email?
</Link> */} </Link> */}
</div>
{/* <Input
id="password"
type="password"
className="bg-[#1C1C1C] border-gray-800 text-white focus:border-emerald-600 focus:ring-emerald-600"
required
/> */}
</div>
<SubmitButton <SubmitButton
className="w-full bg-emerald-600 hover:bg-emerald-700 text-white" className="w-full bg-emerald-600 hover:bg-emerald-700 text-white"
size="lg" size="lg"
pendingText="Signing In..." pendingText="Signing In..."
formAction={signInAction}
> >
Sign In Sign In
</SubmitButton> </SubmitButton>

View File

@ -27,23 +27,23 @@ export const selectContactUsSchema = z.object({
name: z.string(), name: z.string(),
email: z.string(), email: z.string(),
phone: z.string(), phone: z.string(),
message_type: z.string(), typeMessage: z.string(),
message_type_label: z.string(), message_type_label: z.string(),
message: z.string(), message: z.string(),
status: z.nativeEnum(statusEnum), status: z.nativeEnum(statusEnum),
created_at: z.string(), createdAt: z.string(),
updated_at: z.string(), updatedAt: z.string(),
}); });
export type ContactUs = z.infer<typeof selectContactUsSchema>; export type ContactUs = z.infer<typeof selectContactUsSchema>;
// Schema for form input // Schema for form input
export const insertContactUsSchema = z.object({ export const insertContactUsSchema = selectContactUsSchema.pick({
name: z.string(), name: true,
email: z.string(), email: true,
phone: z.string(), phone: true,
typeMessage: z.string(), typeMessage: true,
message: z.string(), message: true,
}); });
export type ContactUsInsert = z.infer<typeof insertContactUsSchema>; export type ContactUsInsert = z.infer<typeof insertContactUsSchema>;

View File

@ -41,7 +41,9 @@ export const updateSession = async (request: NextRequest) => {
// protected routes // protected routes
if (request.nextUrl.pathname === "/" && !user.error) { if (request.nextUrl.pathname === "/" && !user.error) {
return NextResponse.redirect(new URL("/protected", request.url)); return NextResponse.redirect(
new URL("/protected/dashboard", request.url)
);
} }
if (request.nextUrl.pathname.startsWith("/protected") && user.error) { if (request.nextUrl.pathname.startsWith("/protected") && user.error) {