-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3de683e
commit 173fa87
Showing
17 changed files
with
334 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,40 @@ | ||
'use server'; | ||
"use server"; | ||
|
||
import {revalidatePath} from 'next/cache'; | ||
import {redirect} from 'next/navigation'; | ||
import { revalidatePath } from "next/cache"; | ||
import { redirect } from "next/navigation"; | ||
|
||
import {createClient} from '@/lib/supabase/server'; | ||
import { createClient } from "@/lib/supabase/server"; | ||
|
||
export async function login(formData: FormData) { | ||
const supabase = createClient(); | ||
export type LoginActionState = { | ||
success: boolean | null; | ||
email?: string; | ||
password?: string; | ||
}; | ||
|
||
export async function login( | ||
_state: LoginActionState, | ||
formData: FormData | undefined = undefined, | ||
): Promise<LoginActionState> { | ||
const supabase = await createClient(); | ||
|
||
// type-casting here for convenience | ||
// in practice, you should validate your inputs | ||
const data = { | ||
email: formData.get('email') as string, | ||
password: formData.get('password') as string, | ||
email: formData?.get("email") as string, | ||
password: formData?.get("password") as string, | ||
}; | ||
|
||
console.log(data); | ||
|
||
const {error} = await supabase.auth.signInWithPassword(data); | ||
|
||
console.log(error); | ||
const { error } = await supabase.auth.signInWithPassword(data); | ||
|
||
if (error) { | ||
redirect('/login?error=invalid'); | ||
return { | ||
success: false, | ||
...data, | ||
}; | ||
} | ||
|
||
revalidatePath('/', 'layout'); | ||
revalidatePath("/", "layout"); | ||
redirect(`/login/complete`); | ||
|
||
return { | ||
success: true, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
'use client'; | ||
|
||
import {useActionState} from 'react'; | ||
|
||
import Link from 'next/link'; | ||
|
||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from '@/components/ui/card'; | ||
import {Input} from '@/components/ui/input'; | ||
import {Label} from '@/components/ui/label'; | ||
|
||
import {FFrLogo} from '@/components/ffr-logo'; | ||
import {SubmitButton} from '@/components/submit-button'; | ||
import {Alert} from '@/components/ui/alert'; | ||
|
||
import {login, type LoginActionState} from './actions'; | ||
|
||
export function LoginForm() { | ||
const [state, formAction] = useActionState<LoginActionState>(login, { | ||
success: null, | ||
}); | ||
|
||
return ( | ||
<div className="h-screen flex flex-col items-center justify-center"> | ||
<Link href="/"> | ||
<FFrLogo /> | ||
</Link> | ||
<form className="mt-12" action={formAction}> | ||
<Card className="w-full max-w-sm"> | ||
<CardHeader className="border-b mb-6"> | ||
<CardTitle className="text-2xl">Login</CardTitle> | ||
<CardDescription> | ||
Enter your email below to login to your account. | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent className="grid gap-6 my-3"> | ||
<div className="grid gap-2"> | ||
<Label htmlFor="email">Email</Label> | ||
<Input | ||
id="email" | ||
type="email" | ||
name="email" | ||
placeholder="[email protected]" | ||
required | ||
defaultValue={state.email} | ||
/> | ||
</div> | ||
<div className="grid gap-2"> | ||
<Label htmlFor="password">Password</Label> | ||
<Input | ||
id="password" | ||
type="password" | ||
name="password" | ||
required | ||
defaultValue={state.password} | ||
/> | ||
</div> | ||
<SubmitButton className="w-full">Login</SubmitButton> | ||
|
||
{state.success === false && ( | ||
<Alert variant="destructive"> | ||
There was an error logging in. Please try again. | ||
</Alert> | ||
)} | ||
</CardContent> | ||
<CardFooter className="text-center flex items-center justify-center text-muted-foreground text-xs border-t w-full py-4"> | ||
Need an account? | ||
<Link href="/signup" className="underline ml-1"> | ||
Sign Up | ||
</Link> | ||
</CardFooter> | ||
</Card> | ||
</form> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,12 @@ | ||
import {redirect} from 'next/navigation'; | ||
import Link from 'next/link'; | ||
|
||
import {Button} from '@/components/ui/button'; | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from '@/components/ui/card'; | ||
import {Input} from '@/components/ui/input'; | ||
import {Label} from '@/components/ui/label'; | ||
import {createClient} from '@/lib/supabase/server'; | ||
|
||
import {login} from './actions'; | ||
import {LoginForm} from './form'; | ||
|
||
export const metadata = { | ||
title: 'Login', | ||
}; | ||
|
||
type Props = { | ||
searchParams: Promise<{ | ||
|
@@ -23,53 +15,12 @@ type Props = { | |
}; | ||
|
||
export default async function Page(props: Props) { | ||
const client = createClient(); | ||
const client = await createClient(); | ||
const {data} = await client.auth.getSession(); | ||
|
||
if (data.session?.user && !(await props.searchParams).error) { | ||
redirect('/login/complete'); | ||
} | ||
|
||
return ( | ||
<div className="h-screen flex items-center justify-center"> | ||
<form> | ||
<Card className="w-full max-w-sm"> | ||
<CardHeader> | ||
<CardTitle className="text-2xl">Login</CardTitle> | ||
<CardDescription> | ||
Enter your email below to login to your account. | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent className="grid gap-4"> | ||
<div className="grid gap-2"> | ||
<Label htmlFor="email">Email</Label> | ||
<Input | ||
id="email" | ||
type="email" | ||
name="email" | ||
placeholder="[email protected]" | ||
required | ||
/> | ||
</div> | ||
<div className="grid gap-2"> | ||
<Label htmlFor="password">Password</Label> | ||
<Input id="password" type="password" name="password" required /> | ||
</div> | ||
</CardContent> | ||
<CardFooter className="flex flex-col items-center"> | ||
<Button formAction={login} className="w-full"> | ||
Sign in | ||
</Button> | ||
|
||
<div className="mt-4 text-center text-sm"> | ||
Need an account?{' '} | ||
<Link href="/signup" className="text-center text-sm underline"> | ||
Sign Up | ||
</Link> | ||
</div> | ||
</CardFooter> | ||
</Card> | ||
</form> | ||
</div> | ||
); | ||
return <LoginForm />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,53 @@ | ||
'use server'; | ||
"use server"; | ||
|
||
import {revalidatePath} from 'next/cache'; | ||
import {redirect} from 'next/navigation'; | ||
import { revalidatePath } from "next/cache"; | ||
import { redirect } from "next/navigation"; | ||
|
||
import {createClient} from '@/lib/supabase/server'; | ||
import { createClient } from "@/lib/supabase/server"; | ||
|
||
export async function signup(formData: FormData) { | ||
const supabase = createClient(); | ||
export type SignupActionState = { | ||
success: boolean | null; | ||
email?: string; | ||
password?: string; | ||
first_name?: string; | ||
last_name?: string; | ||
}; | ||
|
||
const {error} = await supabase.auth.signUp({ | ||
email: formData.get('email') as string, | ||
password: formData.get('password') as string, | ||
export async function signup( | ||
_state: SignupActionState, | ||
formData: FormData | undefined = undefined, | ||
) { | ||
const supabase = await createClient(); | ||
|
||
const first_name = formData?.get("first_name") as string; | ||
const last_name = formData?.get("last_name") as string; | ||
const email = formData?.get("email") as string; | ||
const password = formData?.get("password") as string; | ||
|
||
const { error } = await supabase.auth.signUp({ | ||
email, | ||
password, | ||
options: { | ||
data: { | ||
first_name: formData.get('first_name') as string, | ||
last_name: formData.get('last_name') as string, | ||
first_name, | ||
last_name, | ||
}, | ||
emailRedirectTo: 'http://localhost:3000/signup/confirm', | ||
} | ||
emailRedirectTo: "http://localhost:3000/signup/confirm", | ||
}, | ||
}); | ||
|
||
if (error) { | ||
console.log(error) | ||
redirect('/signup?error=fail'); | ||
console.log(error); | ||
|
||
return { | ||
success: false, | ||
first_name, | ||
last_name, | ||
email, | ||
password, | ||
}; | ||
} | ||
|
||
revalidatePath('/', 'layout'); | ||
redirect('/signup/complete'); | ||
revalidatePath("/", "layout"); | ||
redirect("/signup/complete"); | ||
} |
Oops, something went wrong.