fix: google login redirect
This commit is contained in:
parent
d26c214047
commit
8a6a99a81b
20
.env
20
.env
|
@ -1,20 +0,0 @@
|
||||||
DATABASE_URL=mongodb+srv://freshbitemehedi:freshbitemehedi2810@project1.lispgny.mongodb.net/Skilld
|
|
||||||
|
|
||||||
UPLOADTHING_SECRET=sk_live_938397c2e99554ab0bc541ba01114334d2ed523a0dbb9988870bcfc05d6ad9df
|
|
||||||
UPLOADTHING_APP_ID=h07pj3xjyv
|
|
||||||
|
|
||||||
NEXTAUTH_URL=http://localhost:3000
|
|
||||||
NEXTAUTH_SECRET=2aqrEwXp57xY5dA6WN5akp3ceFDVg64Qu0Ufm/Dew8g=
|
|
||||||
|
|
||||||
# Go to github and setup the oauth configuration
|
|
||||||
# https://next-auth.js.org/providers/github#configuration
|
|
||||||
# https://github.com/settings/developers
|
|
||||||
|
|
||||||
GITHUB_ID=674c632636000fe44d40
|
|
||||||
GITHUB_SECRET=0ec0b70e902ae00021514e21427108275ef4244b
|
|
||||||
|
|
||||||
|
|
||||||
NEXT_PUBLIC_SUPABASE_URL=https://ckngsmtjumbnwksjutdo.supabase.co
|
|
||||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNrbmdzbXRqdW1ibndrc2p1dGRvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTAzNDIwNjMsImV4cCI6MjAyNTkxODA2M30.ZkykkQeBh8-Ej8_2KMdFPNelEF6jzAgb1Nqd64vwAvs
|
|
||||||
|
|
||||||
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
|
|
@ -1,29 +1,49 @@
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import UserAuthForm from "@/components/forms/user-auth-form";
|
|
||||||
import { buttonVariants } from "@/components/ui/button";
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import Image from "next/image";
|
||||||
|
import SignUpForm from "@/components/forms/signup-form";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Sign In | Skilld",
|
title: "Sign Up | Skilld",
|
||||||
description: "Sign In to start your journey with Skilld.",
|
description: "Sign Up to start your journey with Skilld.",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function AuthenticationPage() {
|
export default function AuthenticationPage() {
|
||||||
return (
|
return (
|
||||||
<div className="relative h-screen flex-col items-center justify-center md:grid lg:max-w-none lg:grid-cols-2 lg:px-0">
|
<div className="relative h-screen flex-col items-center justify-center md:grid lg:max-w-none lg:grid-cols-2 lg:px-0">
|
||||||
<Link
|
<Link
|
||||||
href="/examples/authentication"
|
href="/signin"
|
||||||
className={cn(
|
className={cn(
|
||||||
buttonVariants({ variant: "ghost" }),
|
buttonVariants({ variant: "ghost" }),
|
||||||
"absolute right-4 hidden top-4 md:right-8 md:top-8",
|
"absolute right-4 top-4 md:right-8 md:top-8 hidden",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
Login
|
Sign In
|
||||||
</Link>
|
</Link>
|
||||||
<div className="relative hidden h-full flex-col bg-secondary p-10 dark:border-r lg:flex">
|
<div className="relative hidden h-full flex-col bg-secondary p-10 dark:border-r lg:flex">
|
||||||
<div className="absolute inset-0 bg-secondary" />
|
<div className="absolute inset-0 bg-secondary" />
|
||||||
<div className="relative z-20 flex items-center text-lg font-medium">
|
<Link
|
||||||
|
href="/dashboard"
|
||||||
|
className="relative z-20 flex items-center text-lg font-medium"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/Skilld AI Logos/Skilld Logo-colour on black.png"
|
||||||
|
alt="Skilld Logo"
|
||||||
|
width={100}
|
||||||
|
height={30}
|
||||||
|
className="hidden dark:block h-[25px] w-[80px] md:w-[100px] md:h-[30px] object-contain"
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
src="/Skilld AI Logos/Skilld Logo-colour.png"
|
||||||
|
alt="Skilld Logo"
|
||||||
|
width={100}
|
||||||
|
height={30}
|
||||||
|
className="dark:hidden h-[25px] w-[80px] md:w-[100px] md:h-[30px] object-contain"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
{/* <div className="relative z-20 flex items-center text-lg font-medium">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
@ -37,7 +57,7 @@ export default function AuthenticationPage() {
|
||||||
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
||||||
</svg>
|
</svg>
|
||||||
Skilld
|
Skilld
|
||||||
</div>
|
</div> */}
|
||||||
<div className="relative z-20 mt-auto">
|
<div className="relative z-20 mt-auto">
|
||||||
<blockquote className="space-y-2">
|
<blockquote className="space-y-2">
|
||||||
<p className="text-lg text-muted-foreground">
|
<p className="text-lg text-muted-foreground">
|
||||||
|
@ -57,12 +77,19 @@ export default function AuthenticationPage() {
|
||||||
<h1 className="text-2xl font-semibold tracking-tight">
|
<h1 className="text-2xl font-semibold tracking-tight">
|
||||||
Create an account
|
Create an account
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-sm text-muted-foreground">
|
{/* <p className="text-sm text-muted-foreground">
|
||||||
Enter your email below to create your account
|
Enter your email and password below to create your account
|
||||||
</p>
|
</p> */}
|
||||||
</div>
|
</div>
|
||||||
<UserAuthForm />
|
<SignUpForm />
|
||||||
<p className="px-8 text-center text-sm text-muted-foreground">
|
<div>
|
||||||
|
<p className="text-center text-sm text-muted-foreground">
|
||||||
|
Already have an account?{" "}
|
||||||
|
<Link href="/signin" className="underline hover:text-primary">
|
||||||
|
Sign In
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
<p className="mt-2 text-center text-sm text-muted-foreground">
|
||||||
By clicking continue, you agree to our{" "}
|
By clicking continue, you agree to our{" "}
|
||||||
<Link
|
<Link
|
||||||
href="/terms"
|
href="/terms"
|
||||||
|
@ -82,5 +109,6 @@ export default function AuthenticationPage() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
import { Metadata } from "next";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import Image from "next/image";
|
||||||
|
import SignInForm from "@/components/forms/signin-form";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Sign In | Skilld",
|
||||||
|
description: "Sign In to restart your journey with Skilld.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function AuthenticationPage() {
|
||||||
|
return (
|
||||||
|
<div className="relative h-screen flex-col items-center justify-center md:grid lg:max-w-none lg:grid-cols-2 lg:px-0">
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className={cn(
|
||||||
|
buttonVariants({ variant: "ghost" }),
|
||||||
|
"absolute right-4 top-4 md:right-8 md:top-8 hidden",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Sign Up
|
||||||
|
</Link>
|
||||||
|
<div className="relative hidden h-full flex-col bg-secondary p-10 dark:border-r lg:flex">
|
||||||
|
<div className="absolute inset-0 bg-secondary" />
|
||||||
|
<Link
|
||||||
|
href="/dashboard"
|
||||||
|
className="relative z-20 flex items-center text-lg font-medium"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/Skilld AI Logos/Skilld Logo-colour on black.png"
|
||||||
|
alt="Skilld Logo"
|
||||||
|
width={100}
|
||||||
|
height={30}
|
||||||
|
className="hidden dark:block h-[25px] w-[80px] md:w-[100px] md:h-[30px] object-contain"
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
src="/Skilld AI Logos/Skilld Logo-colour.png"
|
||||||
|
alt="Skilld Logo"
|
||||||
|
width={100}
|
||||||
|
height={30}
|
||||||
|
className="dark:hidden h-[25px] w-[80px] md:w-[100px] md:h-[30px] object-contain"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
{/* <div className="relative z-20 flex items-center text-lg font-medium">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className="mr-2 h-6 w-6"
|
||||||
|
>
|
||||||
|
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
||||||
|
</svg>
|
||||||
|
Skilld
|
||||||
|
</div> */}
|
||||||
|
<div className="relative z-20 mt-auto">
|
||||||
|
<blockquote className="space-y-2">
|
||||||
|
<p className="text-lg text-muted-foreground">
|
||||||
|
“Empower your coding journey at Skilld. Access tutorials,
|
||||||
|
challenges, and expert-led courses to master programming languages
|
||||||
|
and tools. Join a supportive community for discussions and code
|
||||||
|
reviews. Elevate your skills and stay ahead in the tech world with
|
||||||
|
us!.”
|
||||||
|
</p>
|
||||||
|
{/* <footer className="text-sm">Ak</footer> */}
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="p-4 lg:p-8 h-full flex items-center">
|
||||||
|
<div className="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]">
|
||||||
|
<div className="flex flex-col space-y-2 text-center">
|
||||||
|
<h1 className="text-2xl font-semibold tracking-tight">
|
||||||
|
Sign In To Your Account
|
||||||
|
</h1>
|
||||||
|
{/* <p className="text-sm text-muted-foreground">
|
||||||
|
Enter your email and password below to create your account
|
||||||
|
</p> */}
|
||||||
|
</div>
|
||||||
|
<SignInForm />
|
||||||
|
<div>
|
||||||
|
<p className="text-center text-sm text-muted-foreground">
|
||||||
|
Don't have an account?{" "}
|
||||||
|
<Link href="/" className="underline hover:text-primary">
|
||||||
|
Sign Up
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
{/* <p className="mt-2 text-center text-sm text-muted-foreground">
|
||||||
|
By clicking continue, you agree to our{" "}
|
||||||
|
<Link
|
||||||
|
href="/terms"
|
||||||
|
className="underline underline-offset-4 hover:text-primary"
|
||||||
|
>
|
||||||
|
Terms of Service
|
||||||
|
</Link>{" "}
|
||||||
|
and{" "}
|
||||||
|
<Link
|
||||||
|
href="/privacy"
|
||||||
|
className="underline underline-offset-4 hover:text-primary"
|
||||||
|
>
|
||||||
|
Privacy Policy
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
import Header from "@/components/layout/header";
|
import Header from "@/components/layout/header";
|
||||||
import Sidebar from "@/components/layout/sidebar";
|
import Sidebar from "@/components/layout/sidebar";
|
||||||
import StoreProvider from "@/lib/store-provider";
|
import StoreProvider from "@/lib/store-provider";
|
||||||
|
import { createClient } from "@/utils/supabase/server";
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Dashboard | Skilld",
|
title: "Dashboard | Skilld",
|
||||||
|
@ -9,11 +11,22 @@ export const metadata: Metadata = {
|
||||||
"Empower your coding journey at Skilld. Access tutorials, challenges, and expert-led courses to master programming languages and tools. Join a supportive community for discussions and code reviews. Elevate your skills and stay ahead in the tech world with us!",
|
"Empower your coding journey at Skilld. Access tutorials, challenges, and expert-led courses to master programming languages and tools. Join a supportive community for discussions and code reviews. Elevate your skills and stay ahead in the tech world with us!",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DashboardLayout({
|
export default async function DashboardLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
|
const supabase = createClient();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { user },
|
||||||
|
} = await supabase.auth.getUser();
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return redirect("/signin");
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StoreProvider lastUpdate={new Date().getTime()}>
|
<StoreProvider lastUpdate={new Date().getTime()}>
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Header from "@/components/task/header";
|
import Header from "@/components/task/header";
|
||||||
|
import { createClient } from "@/utils/supabase/server";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Task | Skilld",
|
title: "Task | Skilld",
|
||||||
description: "Skilld",
|
description: "Skilld",
|
||||||
};
|
};
|
||||||
|
|
||||||
const Layout = ({ children }: { children: React.ReactNode }) => {
|
const Layout = async ({ children }: { children: React.ReactNode }) => {
|
||||||
|
const supabase = createClient();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { user },
|
||||||
|
} = await supabase.auth.getUser();
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return redirect("/signin");
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-rows-[53px_1fr] min-h-screen">
|
<div className="grid grid-rows-[53px_1fr] min-h-screen">
|
||||||
<Header />
|
<Header />
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
"use client";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import * as z from "zod";
|
||||||
|
import GoogleSignInButton from "../google-auth-button";
|
||||||
|
import { createClient } from "@/utils/supabase/client";
|
||||||
|
import { useToast } from "../ui/use-toast";
|
||||||
|
|
||||||
|
const formSchema = z.object({
|
||||||
|
email: z.string().email({ message: "Enter a valid email address" }),
|
||||||
|
password: z
|
||||||
|
.string()
|
||||||
|
.min(6, { message: "Password should be minimum 6 characters" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
type UserFormValue = z.infer<typeof formSchema>;
|
||||||
|
|
||||||
|
export default function SignInForm() {
|
||||||
|
const router = useRouter();
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const callbackUrl = searchParams.get("callbackUrl");
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const { toast } = useToast();
|
||||||
|
// const defaultValues = {
|
||||||
|
// email: "demo@gmail.com",
|
||||||
|
// };
|
||||||
|
const form = useForm<UserFormValue>({
|
||||||
|
resolver: zodResolver(formSchema),
|
||||||
|
// defaultValues,
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async ({ email, password }: UserFormValue) => {
|
||||||
|
console.log(email, password);
|
||||||
|
const supabase = createClient();
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
const { data, error } = await supabase.auth.signInWithPassword({
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
// options: {
|
||||||
|
// emailRedirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`,
|
||||||
|
// },
|
||||||
|
});
|
||||||
|
console.log(data);
|
||||||
|
console.log(error);
|
||||||
|
// signIn("credentials", {
|
||||||
|
// email: data.email,
|
||||||
|
// callbackUrl: callbackUrl ?? "/dashboard",
|
||||||
|
// });
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
toast({ variant: "destructive", title: error.message });
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
router.push("/dashboard");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="space-y-2 w-full"
|
||||||
|
>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="email"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Email</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="email"
|
||||||
|
placeholder="Enter your email..."
|
||||||
|
disabled={loading}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="password"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Password</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
placeholder="Enter your password..."
|
||||||
|
disabled={loading}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button disabled={loading} className="ml-auto w-full" type="submit">
|
||||||
|
{loading ? "Signing In..." : "Sign In"}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-0 flex items-center">
|
||||||
|
<span className="w-full border-t" />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex justify-center text-xs uppercase">
|
||||||
|
<span className="bg-background px-2 text-muted-foreground">
|
||||||
|
Or continue with
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<GoogleSignInButton />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import { useForm } from "react-hook-form";
|
||||||
import * as z from "zod";
|
import * as z from "zod";
|
||||||
import GoogleSignInButton from "../google-auth-button";
|
import GoogleSignInButton from "../google-auth-button";
|
||||||
import { createClient } from "@/utils/supabase/client";
|
import { createClient } from "@/utils/supabase/client";
|
||||||
|
import { useToast } from "../ui/use-toast";
|
||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
email: z.string().email({ message: "Enter a valid email address" }),
|
email: z.string().email({ message: "Enter a valid email address" }),
|
||||||
|
@ -26,11 +27,14 @@ const formSchema = z.object({
|
||||||
|
|
||||||
type UserFormValue = z.infer<typeof formSchema>;
|
type UserFormValue = z.infer<typeof formSchema>;
|
||||||
|
|
||||||
export default function UserAuthForm() {
|
export default function SignUpForm() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const callbackUrl = searchParams.get("callbackUrl");
|
const callbackUrl = searchParams.get("callbackUrl");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
// const defaultValues = {
|
// const defaultValues = {
|
||||||
// email: "demo@gmail.com",
|
// email: "demo@gmail.com",
|
||||||
// };
|
// };
|
||||||
|
@ -42,6 +46,8 @@ export default function UserAuthForm() {
|
||||||
const onSubmit = async ({ email, password }: UserFormValue) => {
|
const onSubmit = async ({ email, password }: UserFormValue) => {
|
||||||
console.log(email, password);
|
console.log(email, password);
|
||||||
const supabase = createClient();
|
const supabase = createClient();
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
const { data, error } = await supabase.auth.signUp({
|
const { data, error } = await supabase.auth.signUp({
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
|
@ -56,9 +62,15 @@ export default function UserAuthForm() {
|
||||||
// callbackUrl: callbackUrl ?? "/dashboard",
|
// callbackUrl: callbackUrl ?? "/dashboard",
|
||||||
// });
|
// });
|
||||||
|
|
||||||
if (!error) {
|
setLoading(false);
|
||||||
router.push("/dashboard");
|
|
||||||
|
if (error) {
|
||||||
|
toast({ variant: "destructive", title: error.message });
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router.push("/dashboard");
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -106,7 +118,7 @@ export default function UserAuthForm() {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button disabled={loading} className="ml-auto w-full" type="submit">
|
<Button disabled={loading} className="ml-auto w-full" type="submit">
|
||||||
Continue With Email
|
{loading ? "Signing Up..." : "Sign Up"}
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
|
@ -17,6 +17,8 @@ export default function GoogleSignInButton() {
|
||||||
redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`,
|
redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -30,6 +30,8 @@ import {
|
||||||
User2Icon,
|
User2Icon,
|
||||||
UserX2Icon,
|
UserX2Icon,
|
||||||
X,
|
X,
|
||||||
|
Upload,
|
||||||
|
BookCheck,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
export type Icon = LucideIcon;
|
export type Icon = LucideIcon;
|
||||||
|
@ -61,7 +63,9 @@ export const Icons = {
|
||||||
sun: SunMedium,
|
sun: SunMedium,
|
||||||
moon: Moon,
|
moon: Moon,
|
||||||
laptop: Laptop,
|
laptop: Laptop,
|
||||||
|
upload: Upload,
|
||||||
shieldQuestion: ShieldQuestion,
|
shieldQuestion: ShieldQuestion,
|
||||||
|
bookCheck: BookCheck,
|
||||||
gitHub: ({ ...props }: LucideProps) => (
|
gitHub: ({ ...props }: LucideProps) => (
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
|
|
@ -4,8 +4,21 @@ import { MobileSidebar } from "./mobile-sidebar";
|
||||||
import { UserNav } from "./user-nav";
|
import { UserNav } from "./user-nav";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { createClient } from "@/utils/supabase/server";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
export default async function Header() {
|
||||||
|
const supabase = createClient();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { user },
|
||||||
|
} = await supabase.auth.getUser();
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return redirect("/signin");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function Header() {
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed top-0 left-0 right-0 supports-backdrop-blur:bg-background/60 border-b bg-background/95 backdrop-blur z-20">
|
<div className="fixed top-0 left-0 right-0 supports-backdrop-blur:bg-background/60 border-b bg-background/95 backdrop-blur z-20">
|
||||||
<nav className="h-14 flex items-center justify-between px-4">
|
<nav className="h-14 flex items-center justify-between px-4">
|
||||||
|
@ -31,8 +44,11 @@ export default function Header() {
|
||||||
<MobileSidebar />
|
<MobileSidebar />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-4">
|
||||||
<UserNav />
|
<UserNav
|
||||||
|
email={user?.email || "example@gmail.com"}
|
||||||
|
avatarUrl={user?.user_metadata?.avatar_url || ""}
|
||||||
|
/>
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -10,9 +10,9 @@ export default function Sidebar() {
|
||||||
<div className="space-y-4 py-4">
|
<div className="space-y-4 py-4">
|
||||||
<div className="px-3 py-2">
|
<div className="px-3 py-2">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<h2 className="mb-2 px-4 text-xl font-semibold tracking-tight">
|
{/* <h2 className="mb-2 px-4 text-xl font-semibold tracking-tight">
|
||||||
Overview
|
Overview
|
||||||
</h2>
|
</h2> */}
|
||||||
<DashboardNav items={navItems} />
|
<DashboardNav items={navItems} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,15 +12,22 @@ import {
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { createClient } from "@/utils/supabase/client";
|
import { createClient } from "@/utils/supabase/client";
|
||||||
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
export function UserNav() {
|
export function UserNav({
|
||||||
|
email,
|
||||||
|
avatarUrl,
|
||||||
|
}: {
|
||||||
|
email: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button variant="ghost" className="relative h-8 w-8 rounded-full">
|
<Button variant="ghost" className="relative h-8 w-8 rounded-full">
|
||||||
<Avatar className="h-8 w-8">
|
<Avatar className="h-8 w-8">
|
||||||
<AvatarImage src={""} alt={""} />
|
<AvatarImage src={avatarUrl} alt={"User avatar"} />
|
||||||
<AvatarFallback>CN</AvatarFallback>
|
<AvatarFallback>CN</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -30,25 +37,25 @@ export function UserNav() {
|
||||||
<div className="flex flex-col space-y-1">
|
<div className="flex flex-col space-y-1">
|
||||||
<p className="text-sm font-medium leading-none">John Doe</p>
|
<p className="text-sm font-medium leading-none">John Doe</p>
|
||||||
<p className="text-xs leading-none text-muted-foreground">
|
<p className="text-xs leading-none text-muted-foreground">
|
||||||
john@doe.com
|
{email}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
Profile
|
<Link href="/dashboard/profile">Profile</Link>
|
||||||
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
|
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem>
|
{/* <DropdownMenuItem>
|
||||||
Billing
|
Billing
|
||||||
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
|
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem> */}
|
||||||
<DropdownMenuItem>
|
{/* <DropdownMenuItem>
|
||||||
Settings
|
Settings
|
||||||
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
|
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem> */}
|
||||||
<DropdownMenuItem>New Team</DropdownMenuItem>
|
{/* <DropdownMenuItem>New Team</DropdownMenuItem> */}
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
|
|
|
@ -23,9 +23,9 @@ export const HEADING_LINK_ANCHOR = `before:content-['#'] before:absolute before:
|
||||||
|
|
||||||
export const navItems: NavItem[] = [
|
export const navItems: NavItem[] = [
|
||||||
{
|
{
|
||||||
title: "Dashboard",
|
title: "Upload CV",
|
||||||
href: "/dashboard",
|
href: "/dashboard",
|
||||||
icon: "dashboard",
|
icon: "upload",
|
||||||
label: "Dashboard",
|
label: "Dashboard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@ export const navItems: NavItem[] = [
|
||||||
{
|
{
|
||||||
title: "Your Task",
|
title: "Your Task",
|
||||||
href: "/dashboard/task/react/1",
|
href: "/dashboard/task/react/1",
|
||||||
icon: "shieldQuestion",
|
icon: "bookCheck",
|
||||||
label: "Your Task",
|
label: "Your Task",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue