Implement frontend auth and user features - WIP

This commit is contained in:
Philipinho
2023-08-27 21:38:59 +01:00
parent 3e7c2de9a4
commit 54a748ced7
30 changed files with 765 additions and 6 deletions

View File

@ -0,0 +1,7 @@
interface AuthLayoutProps {
children: React.ReactNode
}
export default function AuthLayout({ children }: AuthLayoutProps) {
return <div className="min-h-screen">{children}</div>
}

View File

@ -0,0 +1,49 @@
"use client"
import Link from "next/link";
import { cn } from "@/lib/utils";
import { buttonVariants } from "@/components/ui/button";
import { Icons } from "@/components/icons";
import { ChevronLeftIcon } from "@radix-ui/react-icons";
import { LoginForm } from "@/features/auth/components/login-form";
import LegalTerms from "@/features/auth/components/legal-terms";
export default function LoginPage() {
return (
<div className="container flex h-screen w-screen flex-col items-center justify-center">
<Link
href="/"
className={cn(
buttonVariants({ variant: "ghost" }),
"absolute left-4 top-4 md:left-8 md:top-8")}>
<>
<ChevronLeftIcon className="mr-2 h-4 w-4" />Back
</>
</Link>
<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">
<Icons.logo className="mx-auto h-6 w-6" />
<h1 className="text-2xl font-semibold tracking-tight">
Welcome back
</h1>
<p className="text-sm text-muted-foreground">
Enter your email and password to continue
</p>
</div>
<LoginForm />
<p className="px-8 text-center text-sm text-muted-foreground">
<Link
href="/signup"
className="hover:text-brand underline underline-offset-4">
Don&apos;t have an account? Sign Up
</Link>
</p>
<LegalTerms />
</div>
</div>
);
}

View File

@ -0,0 +1,52 @@
"use client"
import Link from "next/link";
import { cn } from "@/lib/utils";
import { buttonVariants } from "@/components/ui/button";
import { Icons } from "@/components/icons";
import { ChevronLeftIcon } from "@radix-ui/react-icons";
import { SignUpForm } from "@/features/auth/components/sign-up-form";
import LegalTerms from "@/features/auth/components/legal-terms";
export default function SignUpPage() {
return (
<div className="container flex h-screen w-screen flex-col items-center justify-center">
<Link
href="/"
className={cn(
buttonVariants({ variant: "ghost" }),
"absolute left-4 top-4 md:left-8 md:top-8")}>
<>
<ChevronLeftIcon className="mr-2 h-4 w-4" />Back
</>
</Link>
<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">
<Icons.logo className="mx-auto h-6 w-6" />
<h1 className="text-2xl font-semibold tracking-tight">
Create an account
</h1>
<p className="text-sm text-muted-foreground">
Enter your name, email and password to signup
</p>
</div>
<SignUpForm />
<p className="px-8 text-center text-sm text-muted-foreground">
<Link
href="/login"
className="hover:text-brand underline underline-offset-4">
Already have an account? Sign In
</Link>
</p>
<LegalTerms />
</div>
</div>
);
}

View File

@ -0,0 +1,16 @@
"use client";
import { useAtom } from "jotai";
import { currentUserAtom } from "@/features/user/atoms/current-user-atom";
export default function Home() {
const [currentUser] = useAtom(currentUserAtom);
return (
<div className="w-full flex justify-center z-10 flex-shrink-0">
<div className={`w-[900px]`}>
Hello {currentUser && currentUser.user.name}!
</div>
</div>
);
}

View File

@ -0,0 +1,21 @@
"use client"
import dynamic from "next/dynamic";
import { UserProvider } from "@/features/user/user-provider";
const Shell = dynamic(() => import("./shell"), {
ssr: false,
});
export default function DashboardLayout({ children }: {
children: React.ReactNode
}) {
return (
<UserProvider>
<Shell>
{children}
</Shell>
</UserProvider>
);
}

View File

@ -0,0 +1,18 @@
"use client"
export default function Shell({ children }: {
children: React.ReactNode
}) {
return (
<div className="flex justify-start min-h-screen">
<div className="flex flex-col w-full overflow-hidden">
<main className="overflow-y-auto overscroll-none w-full p-8" style={{ height: "calc(100vh - 50px)" }}>
{children}
</main>
</div>
</div>
);
}

View File

@ -4,6 +4,7 @@ import { Inter } from 'next/font/google'
import { cn } from "@/lib/utils";
import { ThemeProvider } from "@/components/providers/theme-provider";
import { Toaster } from "@/components/ui/toaster";
import { TanstackProvider } from "@/components/providers/tanstack-provider";
const inter = Inter({ subsets: ['latin'] })
@ -12,6 +13,7 @@ export const metadata: Metadata = {
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: {
@ -22,8 +24,10 @@ export default function RootLayout({
<html lang="en" suppressHydrationWarning>
<body className={cn("min-h-screen bg-background antialiased", inter.className)}>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
<Toaster />
<TanstackProvider>
{children}
<Toaster />
</TanstackProvider>
</ThemeProvider>
</body>
</html>

View File

@ -8,10 +8,8 @@ export default function Home() {
Get started by editing&nbsp;
<code className="font-mono font-bold">src/app/page.tsx</code>
</p>
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
<div className="fixed bottom-0 left-z0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
<ThemeToggle />
</div>
</div>