Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Starter code #25

Open
wants to merge 31 commits into
base: starter-code
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "gray",
"cssVariables": false
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
6,730 changes: 6,730 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@hookform/resolvers": "^3.1.0",
"@mantine/hooks": "^6.0.13",
"@next-auth/prisma-adapter": "^1.0.6",
"@prisma/client": "^4.14.1",
"@prisma/client": "^5.2.0",
"@radix-ui/react-avatar": "^1.0.3",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-label": "^2.0.2",
Expand Down
2 changes: 2 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ model User {
email String? @unique
emailVerified DateTime?

username String? @unique

image String?
accounts Account[]
sessions Session[]
Expand Down
24 changes: 24 additions & 0 deletions src/app/(auth)/sign-in/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { buttonVariants } from '@/components/ui/Button'
import { FC } from 'react'
import { cn } from '@/lib/utils'
import Link from 'next/link'
import SignIn from '@/components/SignIn'


const page: FC = () => {
return (<div className='absolute inset-0'>
<div className='h-full max-w-2xl mx-auto flex flex-col items-center justify-center gap-20'>
<Link
href='/'
className={cn(buttonVariants({ variant: 'ghost' }),
'self-start -mt-20')}>
Home
</Link>

<SignIn />
</div>
</div>
)
}

export default page
6 changes: 6 additions & 0 deletions src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { authOptions } from "@/lib/auth";
import NextAuth from "next-auth";

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST }
22 changes: 20 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
import { cn } from '@/lib/utils'
import '@/styles/globals.css'
import { Inter } from 'next/font/google'
import Navbar from '@/components/Navbar'
import { Toaster } from '@/components/ui/Toaster'


export const metadata = {
title: 'Breadit',
description: 'A Reddit clone built with Next.js and TypeScript.',
}

const inter = Inter({ subsets: ['latin'] })

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang='en'>
<body>{children}</body>
<html lang='en'
className={cn('bg-white text-slate-900 antialiased light',
inter.className
)}>
<body className='min-h-screen pt-12 bg-slate-50 antialiased'>
<Navbar />

<div className='container max-w-7xl mx-auto h-full pt-12'>
{children}
</div>

<Toaster />
</body>
</html>
)
}
54 changes: 54 additions & 0 deletions src/components/Icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { LucideProps } from "lucide-react";

export const Icons = {
logo: (props: LucideProps) => (
<svg {...props} viewBox='0 0 497 497'>
<g>
<path
d='m392 30c-71.75 0-71.75-30-143.5-30l128.5 497h30c33.137 0 60-26.863 60-60v-228.526c18.555-18.938 30-44.867 30-73.474 0-57.99-47.01-105-105-105z'
fill='#c87044'
/>
<path
d='m437 437-45-377c-41.895 0-63.904-18.405-83.322-34.644-16.942-14.167-30.323-25.356-60.178-25.356-71.75 0-71.75 30-143.5 30-57.99 0-105 47.01-105 105 0 28.607 11.445 54.537 30 73.474v228.526c0 33.137 26.863 60 60 60h287c33.137 0 60-26.863 60-60z'
fill='#db905a'
/>
<path
d='m392 60-15 407h30c16.542 0 30-13.458 30-30v-228.526c0-7.851 3.077-15.388 8.571-20.996 13.819-14.103 21.429-32.74 21.429-52.478 0-41.355-33.645-75-75-75z'
fill='#ffd185'
/>
<path
d='m407 437v-228.526c0-15.796 6.088-30.708 17.143-41.991 8.291-8.462 12.857-19.643 12.857-31.483 0-41.355-20.187-75-45-75-41.895 0-63.904-9.203-83.322-17.322-16.942-7.083-30.323-12.678-60.178-12.678-29.856 0-43.236 5.595-60.177 12.678-19.419 8.119-41.429 17.322-83.323 17.322-41.355 0-75 33.645-75 75 0 19.738 7.61 38.375 21.429 52.479 5.494 5.607 8.571 13.145 8.571 20.995v228.526c0 16.542 13.458 30 30 30h287c16.542 0 30-13.458 30-30z'
fill='#ffe8c2'
/>
<g fill='#ffd185'>
<circle cx='392' cy='135' r='7.5' />
<circle cx='362' cy='165' r='7.5' />
<circle cx='105' cy='377' r='7.5' />
<circle cx='135' cy='407' r='7.5' />
<circle cx='105' cy='135' r='7.5' />
</g>
</g>
</svg>
),
google: (props: LucideProps) => (
<svg {...props} viewBox='0 0 24 24'>
<path
d='M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z'
fill='#4285F4'
/>
<path
d='M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z'
fill='#34A853'
/>
<path
d='M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z'
fill='#FBBC05'
/>
<path
d='M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z'
fill='#EA4335'
/>
<path d='M1 1h22v22H1z' fill='none' />
</svg>
),
}
26 changes: 26 additions & 0 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Link from "next/link";
import { Icons } from "./Icons";
import { buttonVariants } from "./ui/Button";
import { getAuthSession } from "@/lib/auth";

const Navbar = async () => {

const session = await getAuthSession()

return (
<div className="fixed top-0 inset-x-0 h-fit bg-zinc-100 border-b border-zinc-300 z-[10] py-2">
<div className="container max-w-7xl h-full mx-auto items-center flex justify-between gap-2">
<Link href='/' className="flex gap-2 items-center">
<Icons.logo className="h-8 w-8 smh:h-6 sm:w-6" />
<p className="hidden text-zinc-700 text-sm font-medium md:block">Breadit</p>
</Link>

{/* search bar */}

<Link href="/sign-in" className={buttonVariants()}>Sign In</Link>
</div>
</div>
)
}

export default Navbar;
31 changes: 31 additions & 0 deletions src/components/SignIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Link from "next/link";
import { Icons } from "./Icons"
import UserAuthForm from "./UserAuthForm";

const SignIn = () => {
return (
<div className="container mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[400px]">
<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 max-w-xs mx-auto">
By Continuing, you are setting up a Breadit account and agree to our User Agreement and Privacy Policy.
</p>

{/* { sign in form} */}
<UserAuthForm />

<p className='px-8 text-center text-sm text-zinc-700'>
New to Breadit?{' '}
<Link
href="/sign-up"
className='hover:text-zinc-800 text-sm underline underline-offset-4'>
Sign Up
</Link>
</p>
</div>
</div>
)
}

export default SignIn;
49 changes: 49 additions & 0 deletions src/components/UserAuthForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"use client"


import { FC, useState } from 'react'
import { Button } from './ui/Button'
import { cn } from '@/lib/utils'
import { signIn } from 'next-auth/react';
import { Icons } from './Icons';
import { useToast } from '@/hooks/use-toast';


const UserAuthForm = () => {

const [isLoading, setIsLoading] = useState<boolean>(false);
const { toast } = useToast();

const loginWithGoogle = async () => {
setIsLoading(true);

try {
await signIn('google')
} catch (error) {
toast({
title: 'There was a problem.',
description: 'There was an error logging in with Google',
variant: 'destructive',
})
} finally {
setIsLoading(false)
}
};

return (
<div className='flex justify-center'>
<Button
onClick={loginWithGoogle}
isLoading={isLoading}
size='sm'
className='w-full'>
{isLoading ? null : <Icons.google className='h-4 w-4 mr-2' />}
Google
</Button>

</div>

)
}

export default UserAuthForm
Loading