Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

Commit

Permalink
feat: rewrite signup and signin page with tailwind UI (#107)
Browse files Browse the repository at this point in the history
* feat: rewrite signup and signin page with tailwind UI #100

* fix: add corrections #100

* fix: add changes #100

* fix: add changes #100

* fix: add changes #100

* fix: add changes #100

* fix: add changes (#100)

* fix: refactor

* fix: fix typo in signup form

* fix: fix typo in signup form
  • Loading branch information
olamide203 committed Aug 23, 2022
1 parent cbd238b commit 83de475
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 163 deletions.
2 changes: 1 addition & 1 deletion .env.template
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
86 changes: 86 additions & 0 deletions components/SignIn/Form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { useState } from 'react';
import { supabase } from '../../utils/supabaseClient';
import { FaLock } from 'react-icons/fa';

export const SignInForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSignIn = async () => {
const { user, error } = await supabase.auth.signIn({ email, password });
if (error) alert(error.message);
else {
alert(`Success Login in ${user?.email}`);
setEmail('');
setPassword('');
}
};
return (
<form
className='mt-4 space-y-4'
onSubmit={e => {
e.preventDefault();
handleSignIn();
}}
>
<div className='flex w-full flex-col space-y-3'>
<label htmlFor='email-address' className='text-sm text-gray-600'>
Email address
</label>
<input
type='email'
id='email-address'
placeholder='example@gmail.com'
required
className='relative block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm'
value={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<div className='flex w-full flex-col space-y-2 '>
<label htmlFor='password' className='text-sm text-gray-600'>
password
</label>
<input
type='password'
id='password'
required
className='relative flex w-full appearance-none justify-center rounded-md border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm'
placeholder='*****'
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
{/*TODO: REMEMBER ME AND FORGOT PASSWORD FUNCTIONALITY */}
{/* <div className='flex items-center justify-between'>
<div className='flex items-center'>
<input
id='remember-me'
name='remember-me'
type='checkbox'
className='h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500'
/>
<label htmlFor='remember-me' className='ml-2 block text-sm text-gray-900'>
{' '}
Remember me{' '}
</label>
</div>
<div className='text-sm'>
<a href='#' className='font-medium text-indigo-600 hover:text-indigo-500'>
{' '}
Forgot your password?{' '}
</a>
</div>
</div> */}
<button
type='submit'
className='group relative my-4 flex w-full justify-center rounded-md border border-transparent bg-indigo-600 py-2 px-4 text-sm font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2'
>
<span className='absolute inset-y-0 left-0 flex items-center pl-3'>
<FaLock className='text-base text-indigo-500 group-hover:text-indigo-400' />
</span>
Sign in
</button>
</form>
);
};
38 changes: 38 additions & 0 deletions components/SignIn/Social.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FaGithub, FaGoogle } from 'react-icons/fa';

export const SignInSocial = () => {
return (
<div className='mt-6'>
<p className='text-sm text-gray-700'>Sign in with</p>
<div className='my-2 grid grid-cols-2 gap-4'>
<div>
<a
href='#'
className='inline-flex w-full justify-center rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-500 shadow-sm hover:bg-gray-50'
>
<span className='sr-only'>Sign in with Google</span>
<FaGoogle className='text-xl text-gray-500' />
</a>
</div>

<div>
<a
href='#'
className='inline-flex w-full justify-center rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-500 shadow-sm hover:bg-gray-50'
>
<span className='sr-only'>Sign in with GitHub</span>
<FaGithub className='text-xl text-gray-500' />
</a>
</div>
</div>
<div className='relative mt-6'>
<div className='absolute inset-0 flex items-center' aria-hidden='true'>
<div className='w-full border-t border-gray-300' />
</div>
<div className='relative flex justify-center text-sm'>
<span className='bg-white px-2 text-gray-500'>Or continue with</span>
</div>
</div>
</div>
);
};
61 changes: 61 additions & 0 deletions components/SignUp/Form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { useState } from 'react';
import { supabase } from '../../utils/supabaseClient';

export const SignUpForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSignUp = async () => {
const { user, error } = await supabase.auth.signUp({ email, password });
if (error) alert(error.message);
else {
alert(`Success Register in ${user?.email}`);
setEmail('');
setPassword('');
}
};
return (
<form
onSubmit={e => {
e.preventDefault();
handleSignUp();
}}
className='mt-4 flex flex-col space-y-4'
>
<div className='flex w-full flex-col space-y-2'>
<label htmlFor='email-address' className='text-sm text-gray-600'>
Email address
</label>
<input
type='email'
id='email-address'
placeholder='example@gmail.com'
required
className='relative block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm'
value={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<div className='flex w-full flex-col space-y-2 '>
<label htmlFor='password' className='text-sm text-gray-600'>
Password
</label>
<input
type='password'
id='password'
required
className='relative block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm'
placeholder='*****'
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
<button
type='submit'
onClick={handleSignUp}
className='group relative my-4 flex w-full justify-center rounded-md border border-transparent bg-indigo-600 py-2 px-4 text-sm font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2'
>
Sign up
</button>
</form>
);
};
38 changes: 38 additions & 0 deletions components/SignUp/Social.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FaGithub, FaGoogle } from 'react-icons/fa';

export const SignUpSocial = () => {
return (
<div className='mt-6'>
<p className='text-sm text-gray-700'>Sign up with</p>
<div className='my-2 grid grid-cols-2 gap-4'>
<div>
<a
href='#'
className='inline-flex w-full justify-center rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-500 shadow-sm hover:bg-gray-50'
>
<span className='sr-only'>Sign in with Google</span>
<FaGoogle className='text-xl text-gray-500' />
</a>
</div>

<div>
<a
href='#'
className='inline-flex w-full justify-center rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-500 shadow-sm hover:bg-gray-50'
>
<span className='sr-only'>Sign in with GitHub</span>
<FaGithub className='text-xl text-gray-500' />
</a>
</div>
</div>
<div className='relative mt-6'>
<div className='absolute inset-0 flex items-center' aria-hidden='true'>
<div className='w-full border-t border-gray-300' />
</div>
<div className='relative flex justify-center text-sm'>
<span className='bg-white px-2 text-gray-500'>Or continue with</span>
</div>
</div>
</div>
);
};
3 changes: 3 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/** @type {import('next').NextConfig} */
module.exports = {
reactStrictMode: true,
images: {
domains: ['images.unsplash.com'],
},
};
17 changes: 16 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"@supabase/supabase-js": "^1.35.6",
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0"
"react-dom": "18.2.0",
"react-icons": "^4.4.0"
},
"devDependencies": {
"@commitlint/cli": "^17.0.3",
Expand Down
90 changes: 22 additions & 68 deletions pages/signin.tsx
Original file line number Diff line number Diff line change
@@ -1,86 +1,40 @@
import { useState } from 'react';
import Image from 'next/image';
import Head from 'next/head';
import { type NextPage } from 'next';
import { supabase } from '../utils/supabaseClient';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { type NextPage } from 'next';
import { SignInForm } from '../components/SignIn/Form';
import { SignInSocial } from '../components/SignIn/Social';

const SignIn: NextPage = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSignIn = async () => {
const { user, error } = await supabase.auth.signIn({ email, password });
if (error) alert(error.message);
else {
alert(`Success Login in ${user?.email}`);
setEmail('');
setPassword('');
}
};
return (
<>
<Head>
<title>Defaang / Welcome</title>
</Head>
<main className='flex h-screen w-screen'>
{/* Left section - main login */}

<div className='flex h-screen w-[100%] flex-col items-center justify-center bg-gray-100 lg:w-[50%]'>
{/* Now you can decide different login ways - primarily I am giving google and twiiter for more add it yourself. */}
<div className='w-full bg-white p-4 md:shadow-lg lg:h-[500px] lg:w-[400px]'>
<h1 className='p-2 text-3xl font-semibold'>Sign in ⚡</h1>

<form
className='mt-4 space-y-4'
onSubmit={e => {
e.preventDefault();
handleSignIn();
}}
>
<div className='flex w-[90%] flex-col space-y-2'>
<p>Email</p>
<input
type='text'
placeholder='example@gmail.com'
required
className='input-field outline-none'
value={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<div className='flex w-[90%] flex-col space-y-2 '>
<p>Password</p>
<input
type='password'
required
className='input-field outline-none'
placeholder='*****'
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
</form>
<button
type='submit'
className='my-4 flex w-[90%] cursor-pointer items-center justify-center rounded-md bg-blue-600 py-2 font-semibold text-white hover:bg-blue-500'
onClick={handleSignIn}
>
Login
</button>
<p className='font-semibold'>
Not registered yet?
<main className='flex h-full min-h-screen'>
<div className='flex flex-1 flex-col justify-center py-12 px-4 sm:px-6 lg:flex-none lg:px-20 xl:px-24'>
<div className='mx-auto w-full max-w-sm lg:w-96'>
<div>
<h2 className='mt-6 text-start text-3xl font-bold tracking-tight text-gray-900'>Sign in</h2>
</div>
{/* TODO: social sign in options */}
{/* <SignInSocial /> */}
<SignInForm />
<p className='my-2 flex w-full justify-center text-sm text-gray-700'>
Not registered yet?{' '}
<Link className='cursor-pointer font-bold' href={'/signup'}>
<a className=' text-blue-600 hover:underline'> Sign up</a>
<a className='mx-1 text-blue-600 hover:underline'>Sign up</a>
</Link>
</p>
</div>
</div>
{/* Right Section - Image and just for UI. */}

<div className='relative hidden w-[50%] lg:inline-flex'>
<div className='absolute top-0 left-0 h-[100%] w-[100%] bg-black opacity-[0.5]'></div>
<Image src='/sidebar.jpg' alt='right-side-image' layout='fill' className='object-cover' />
<div className='relative hidden w-0 flex-1 lg:block'>
<Image
className='absolute inset-0 h-full w-full object-cover'
src='https://images.unsplash.com/photo-1505904267569-f02eaeb45a4c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1908&q=80'
alt=''
layout='fill'
/>
</div>
</main>
</>
Expand Down

1 comment on commit 83de475

@vercel
Copy link

@vercel vercel bot commented on 83de475 Aug 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

defaang – ./

defaang-git-main-ykdojo.vercel.app
defaang.vercel.app
defaang-ykdojo.vercel.app

Please sign in to comment.