diff --git a/.env b/.env deleted file mode 100644 index f52c411..0000000 --- a/.env +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/app/(auth)/(signin)/page.tsx b/src/app/(auth)/(signup)/page.tsx similarity index 50% rename from src/app/(auth)/(signin)/page.tsx rename to src/app/(auth)/(signup)/page.tsx index 454a06f..90a1ce9 100644 --- a/src/app/(auth)/(signin)/page.tsx +++ b/src/app/(auth)/(signup)/page.tsx @@ -1,29 +1,49 @@ import { Metadata } from "next"; import Link from "next/link"; -import UserAuthForm from "@/components/forms/user-auth-form"; import { buttonVariants } from "@/components/ui/button"; import { cn } from "@/lib/utils"; +import Image from "next/image"; +import SignUpForm from "@/components/forms/signup-form"; export const metadata: Metadata = { - title: "Sign In | Skilld", - description: "Sign In to start your journey with Skilld.", + title: "Sign Up | Skilld", + description: "Sign Up to start your journey with Skilld.", }; export default function AuthenticationPage() { return (
- Login + Sign In
-
+ + Skilld Logo + Skilld Logo + + {/*
Skilld -
+
*/}

@@ -57,28 +77,36 @@ export default function AuthenticationPage() {

Create an account

-

- Enter your email below to create your account + {/*

+ Enter your email and password below to create your account +

*/} +
+ +
+

+ Already have an account?{" "} + + Sign In + +

+

+ By clicking continue, you agree to our{" "} + + Terms of Service + {" "} + and{" "} + + Privacy Policy + + .

- -

- By clicking continue, you agree to our{" "} - - Terms of Service - {" "} - and{" "} - - Privacy Policy - - . -

diff --git a/src/app/(auth)/signin/page.tsx b/src/app/(auth)/signin/page.tsx new file mode 100644 index 0000000..78f8108 --- /dev/null +++ b/src/app/(auth)/signin/page.tsx @@ -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 ( +
+ + Sign Up + +
+
+ + Skilld Logo + Skilld Logo + + {/*
+ + + + Skilld +
*/} +
+
+

+ “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!.” +

+ {/*
Ak
*/} +
+
+
+
+
+
+

+ Sign In To Your Account +

+ {/*

+ Enter your email and password below to create your account +

*/} +
+ +
+

+ Don't have an account?{" "} + + Sign Up + +

+ {/*

+ By clicking continue, you agree to our{" "} + + Terms of Service + {" "} + and{" "} + + Privacy Policy + + . +

*/} +
+
+
+
+ ); +} diff --git a/src/app/(dashboard)/dashboard/(quiz)/layout.tsx b/src/app/(dashboard)/dashboard/(quiz)/layout.tsx index e255bdb..200d0f7 100644 --- a/src/app/(dashboard)/dashboard/(quiz)/layout.tsx +++ b/src/app/(dashboard)/dashboard/(quiz)/layout.tsx @@ -1,7 +1,9 @@ import Header from "@/components/layout/header"; import Sidebar from "@/components/layout/sidebar"; import StoreProvider from "@/lib/store-provider"; +import { createClient } from "@/utils/supabase/server"; import type { Metadata } from "next"; +import { redirect } from "next/navigation"; export const metadata: Metadata = { 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!", }; -export default function DashboardLayout({ +export default async function DashboardLayout({ children, }: { children: React.ReactNode; }) { + + const supabase = createClient(); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return redirect("/signin"); + } + return ( <> diff --git a/src/app/(dashboard)/dashboard/(task)/layout.tsx b/src/app/(dashboard)/dashboard/(task)/layout.tsx index 0ad1363..9b94443 100644 --- a/src/app/(dashboard)/dashboard/(task)/layout.tsx +++ b/src/app/(dashboard)/dashboard/(task)/layout.tsx @@ -1,13 +1,25 @@ import { Metadata } from "next"; import React from "react"; import Header from "@/components/task/header"; +import { createClient } from "@/utils/supabase/server"; +import { redirect } from "next/navigation"; export const metadata: Metadata = { title: "Task | 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 (
diff --git a/src/components/forms/signin-form.tsx b/src/components/forms/signin-form.tsx new file mode 100644 index 0000000..a8e0364 --- /dev/null +++ b/src/components/forms/signin-form.tsx @@ -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; + +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({ + 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 ( + <> +
+ + ( + + Email + + + + + + )} + /> + ( + + Password + + + + + + )} + /> + + + + +
+
+ +
+
+ + Or continue with + +
+
+ + + ); +} diff --git a/src/components/forms/user-auth-form.tsx b/src/components/forms/signup-form.tsx similarity index 91% rename from src/components/forms/user-auth-form.tsx rename to src/components/forms/signup-form.tsx index accb9ae..1dcb255 100644 --- a/src/components/forms/user-auth-form.tsx +++ b/src/components/forms/signup-form.tsx @@ -16,6 +16,7 @@ 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" }), @@ -26,11 +27,14 @@ const formSchema = z.object({ type UserFormValue = z.infer; -export default function UserAuthForm() { +export default function SignUpForm() { 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", // }; @@ -42,6 +46,8 @@ export default function UserAuthForm() { const onSubmit = async ({ email, password }: UserFormValue) => { console.log(email, password); const supabase = createClient(); + + setLoading(true); const { data, error } = await supabase.auth.signUp({ email, password, @@ -56,9 +62,15 @@ export default function UserAuthForm() { // callbackUrl: callbackUrl ?? "/dashboard", // }); - if (!error) { - router.push("/dashboard"); + setLoading(false); + + if (error) { + toast({ variant: "destructive", title: error.message }); + + return; } + + router.push("/dashboard"); }; return ( @@ -106,7 +118,7 @@ export default function UserAuthForm() { /> diff --git a/src/components/google-auth-button.tsx b/src/components/google-auth-button.tsx index 2a03da1..3baa922 100644 --- a/src/components/google-auth-button.tsx +++ b/src/components/google-auth-button.tsx @@ -17,6 +17,8 @@ export default function GoogleSignInButton() { redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`, }, }); + + console.log(error); }; return ( diff --git a/src/components/icons.tsx b/src/components/icons.tsx index 4149d8d..5720300 100644 --- a/src/components/icons.tsx +++ b/src/components/icons.tsx @@ -30,6 +30,8 @@ import { User2Icon, UserX2Icon, X, + Upload, + BookCheck, } from "lucide-react"; export type Icon = LucideIcon; @@ -61,7 +63,9 @@ export const Icons = { sun: SunMedium, moon: Moon, laptop: Laptop, + upload: Upload, shieldQuestion: ShieldQuestion, + bookCheck: BookCheck, gitHub: ({ ...props }: LucideProps) => (
- Skilld Logo - Skilld Logo - + Skilld Logo + Skilld Logo +
-
- +
+
diff --git a/src/components/layout/sidebar.tsx b/src/components/layout/sidebar.tsx index e642c3d..2b22483 100644 --- a/src/components/layout/sidebar.tsx +++ b/src/components/layout/sidebar.tsx @@ -10,9 +10,9 @@ export default function Sidebar() {
-

+ {/*

Overview -

+ */}
diff --git a/src/components/layout/user-nav.tsx b/src/components/layout/user-nav.tsx index edab0af..0d13be5 100644 --- a/src/components/layout/user-nav.tsx +++ b/src/components/layout/user-nav.tsx @@ -12,15 +12,22 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { createClient } from "@/utils/supabase/client"; +import Link from "next/link"; import { useRouter } from "next/navigation"; -export function UserNav() { +export function UserNav({ + email, + avatarUrl, +}: { + email: string; + avatarUrl: string; +}) { const router = useRouter(); return ( @@ -30,29 +37,29 @@ export function UserNav() {

John Doe

- john@doe.com + {email}

- Profile + Profile ⇧⌘P - + {/* Billing ⌘B - - + */} + {/* Settings ⌘S - - New Team + */} + {/* New Team */} - { const supabase = createClient(); const { error } = await supabase.auth.signOut(); diff --git a/src/constants/data.ts b/src/constants/data.ts index aa04287..a6fa028 100644 --- a/src/constants/data.ts +++ b/src/constants/data.ts @@ -23,9 +23,9 @@ export const HEADING_LINK_ANCHOR = `before:content-['#'] before:absolute before: export const navItems: NavItem[] = [ { - title: "Dashboard", + title: "Upload CV", href: "/dashboard", - icon: "dashboard", + icon: "upload", label: "Dashboard", }, { @@ -37,7 +37,7 @@ export const navItems: NavItem[] = [ { title: "Your Task", href: "/dashboard/task/react/1", - icon: "shieldQuestion", + icon: "bookCheck", label: "Your Task", },