├── public ├── favicon.ico ├── assets │ └── images │ │ └── logo.png ├── vercel.svg ├── thirteen.svg └── next.svg ├── types ├── index.ts └── propTypes.ts ├── styles ├── globals.css └── Home.module.css ├── pages ├── products.tsx ├── login.tsx ├── signup.tsx ├── forgot-password.tsx ├── _document.tsx ├── api │ └── hello.ts ├── index.tsx └── _app.tsx ├── next.config.js ├── components ├── Form │ ├── ForgotPasswordElements.ts │ ├── InputFeildElements.ts │ ├── ForgotPasswordForm.tsx │ ├── InputFeild.tsx │ ├── FormElements.ts │ ├── LoginForm.tsx │ └── SignupForm.tsx ├── Button │ ├── index.tsx │ └── ButtonElements.ts ├── AppLogoTitle │ ├── AppLogoTitleElements.ts │ └── index.tsx └── Navbar │ ├── NavLink.tsx │ ├── NavElements.ts │ └── index.tsx ├── .gitignore ├── tsconfig.json ├── package.json ├── hooks └── index.ts └── README.md /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esu-coder/nextjs-auth-ui/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /types/index.ts: -------------------------------------------------------------------------------- 1 | export interface WindowSize { 2 | width: number; 3 | height: number; 4 | } -------------------------------------------------------------------------------- /public/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esu-coder/nextjs-auth-ui/HEAD/public/assets/images/logo.png -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | box-sizing: border-box; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | color: black; 9 | } -------------------------------------------------------------------------------- /pages/products.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | type Props = {} 4 | 5 | const products = (props: Props) => { 6 | return ( 7 |
products
8 | ) 9 | } 10 | 11 | export default products -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | compiler: { 5 | styledComponents: true, 6 | }, 7 | } 8 | 9 | module.exports = nextConfig 10 | -------------------------------------------------------------------------------- /pages/login.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import LoginForm from '../components/Form/LoginForm' 3 | 4 | const login = () => { 5 | return ( 6 | 7 | ) 8 | } 9 | 10 | export default login -------------------------------------------------------------------------------- /pages/signup.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import SignupForm from '../components/Form/SignupForm' 3 | 4 | const signup = () => { 5 | return ( 6 | 7 | ) 8 | } 9 | 10 | export default signup -------------------------------------------------------------------------------- /components/Form/ForgotPasswordElements.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { Form as ForgotPassForm } from '../Form/FormElements'; 3 | 4 | export const Form = styled(ForgotPassForm)` 5 | height: 50%; 6 | ` 7 | 8 | export * from '../Form/FormElements' -------------------------------------------------------------------------------- /pages/forgot-password.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ForgotPasswordForm from '../components/Form/ForgotPasswordForm' 3 | 4 | 5 | const forgotPassword = () => { 6 | return ( 7 | 8 | ) 9 | } 10 | 11 | export default forgotPassword -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from 'next/document' 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /components/Button/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ButtonProps } from '../../types/propTypes' 3 | import { Container } from './ButtonElements' 4 | 5 | const Button = ({ title, type }: ButtonProps) => { 6 | return ( 7 | 8 | {title} 9 | 10 | ) 11 | } 12 | 13 | export default Button -------------------------------------------------------------------------------- /pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from 'next' 3 | 4 | type Data = { 5 | name: string 6 | } 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse 11 | ) { 12 | res.status(200).json({ name: 'John Doe' }) 13 | } 14 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | 3 | export default function Home() { 4 | return ( 5 | <> 6 | 7 | Create Next App 8 | 9 | 10 | 11 | 12 | 13 | Home 14 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /components/Button/ButtonElements.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const Container = styled.button` 4 | background-color: #23C687; 5 | color: #fff; 6 | font-size: 0.9rem; 7 | padding: 0.8rem; 8 | transition: all 0.5s; 9 | border-radius: 5px; 10 | cursor: pointer; 11 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); 12 | width: 100%; 13 | border: none; 14 | 15 | &:hover { 16 | background-color: #707070; 17 | } 18 | ` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /types/propTypes.ts: -------------------------------------------------------------------------------- 1 | export interface NavLinkProps { 2 | route: string; 3 | children: React.ReactNode; 4 | color?: string; 5 | large?: boolean; 6 | onClick?: React.MouseEventHandler; 7 | } 8 | 9 | export interface InputProps { 10 | placeholder: string; 11 | icon: React.ReactNode; 12 | type: string; 13 | value: string; 14 | onChange: (event: React.ChangeEvent) => void; 15 | required?: boolean; 16 | } 17 | 18 | export interface ButtonProps { 19 | title: string; 20 | type: 'submit' | 'button' | 'reset'; 21 | } -------------------------------------------------------------------------------- /components/AppLogoTitle/AppLogoTitleElements.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import Image from "next/image"; 3 | import Link from "next/link"; 4 | 5 | export const Container = styled(Link)` 6 | display: flex; 7 | justify-content: center; 8 | align-items: center; 9 | margin: 1rem 0; 10 | text-decoration: none; 11 | color: #23C687; 12 | ` 13 | 14 | export const AppTitle = styled.h2` 15 | font-size: 1.2rem; 16 | ` 17 | 18 | export const LogoImage = styled(Image)` 19 | margin-left: 0.8rem; 20 | height: 2.2rem; 21 | width: 2.2rem; 22 | ` -------------------------------------------------------------------------------- /components/AppLogoTitle/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | AppTitle, 4 | Container, 5 | LogoImage 6 | } from './AppLogoTitleElements' 7 | import LogoImgSrc from '../../public/assets/images/logo.png' 8 | 9 | type Props = {} 10 | 11 | const AppLogoTitle = (props: Props) => { 12 | return ( 13 | 14 | OV Travels 15 | 19 | 20 | ) 21 | } 22 | 23 | export default AppLogoTitle -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-auth-ui", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@next/font": "13.1.2", 13 | "@types/node": "18.11.18", 14 | "@types/react": "18.0.26", 15 | "@types/react-dom": "18.0.10", 16 | "next": "13.1.2", 17 | "react": "18.2.0", 18 | "react-dom": "18.2.0", 19 | "react-icons": "^4.7.1", 20 | "styled-components": "^5.3.6", 21 | "typescript": "4.9.4" 22 | }, 23 | "devDependencies": { 24 | "@types/styled-components": "^5.1.26" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /components/Navbar/NavLink.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useRouter } from 'next/router' 3 | import { NavLinkProps } from '../../types/propTypes' 4 | import { NavLink as Link } from './NavElements' 5 | 6 | const NavLink = ({ route, children, color, large, onClick }: NavLinkProps) => { 7 | const router = useRouter() 8 | const currentRoute = router.pathname 9 | 10 | return ( 11 | 18 | {children} 19 | 20 | ) 21 | } 22 | 23 | export default NavLink -------------------------------------------------------------------------------- /hooks/index.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | import { WindowSize } from "../types"; 3 | 4 | export const useWindowSize = () => { 5 | const [windowSize, setWindowSize] = useState({ 6 | width: 0, 7 | height: 0 8 | }) 9 | 10 | useEffect(() => { 11 | const handleResize = () => { 12 | setWindowSize({ 13 | width: window.innerWidth, 14 | height: window.innerHeight 15 | }) 16 | } 17 | 18 | window.addEventListener("resize", handleResize) 19 | 20 | handleResize() 21 | 22 | return () => window.removeEventListener("resize", handleResize) 23 | }, []) 24 | 25 | return windowSize 26 | } -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | import type { AppProps } from 'next/app' 3 | import Navbar from '../components/Navbar' 4 | import { useRouter } from 'next/router' 5 | import { Roboto } from '@next/font/google' 6 | const roboto = Roboto({ weight: '400', subsets: ['latin'] }) 7 | 8 | export default function App({ Component, pageProps }: AppProps) { 9 | const router = useRouter() 10 | const { pathname } = router 11 | let showNavbar = true 12 | 13 | if (pathname === '/login' || pathname === '/signup' || pathname === '/forgot-password') { 14 | showNavbar = false 15 | } 16 | 17 | return ( 18 |
19 | {showNavbar && } 20 | 21 |
22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /components/Form/InputFeildElements.ts: -------------------------------------------------------------------------------- 1 | import styled, { css } from "styled-components"; 2 | import { BsEye, BsEyeSlash } from 'react-icons/bs'; 3 | 4 | export const Container = styled.div` 5 | display: flex; 6 | align-items: center; 7 | width: 100%; 8 | position: relative; 9 | 10 | & svg { 11 | position: absolute; 12 | transform: translateX(1rem); 13 | color: rgba(0, 0, 0, 0.65); 14 | } 15 | ` 16 | 17 | export const Input = styled.input` 18 | font-size: 0.85rem; 19 | padding: 1rem 3rem; 20 | border: 1px solid rgba(0, 0, 0, 0.25); 21 | border-radius: 4px; 22 | width: 100%; 23 | ` 24 | 25 | const EyeIcon = css` 26 | position: absolute; 27 | right: 25px; 28 | color: rgba(0, 0, 0, 0.65); 29 | ` 30 | 31 | export const ShowPassIcon = styled(BsEye)` 32 | ${EyeIcon} 33 | ` 34 | 35 | export const HidePassIcon = styled(BsEyeSlash)` 36 | ${EyeIcon} 37 | ` 38 | 39 | -------------------------------------------------------------------------------- /public/thirteen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/Form/ForgotPasswordForm.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import { AiOutlineMail } from 'react-icons/ai' 3 | import AppLogoTitle from '../AppLogoTitle' 4 | import Button from '../Button' 5 | import { 6 | Container, 7 | Form, 8 | FormTitle 9 | } from './ForgotPasswordElements' 10 | import InputFeild from './InputFeild' 11 | 12 | const ForgotPasswordForm = () => { 13 | const [email, setEmail] = useState("") 14 | 15 | const handleEmailChange = (event: React.ChangeEvent) => { 16 | setEmail(event.target.value) 17 | } 18 | 19 | const handleSubmit = (event: React.FormEvent) => { 20 | event.preventDefault() 21 | } 22 | 23 | return ( 24 | 25 | 26 | 27 |
28 | Forgot Password 29 | 30 | } 36 | required 37 | /> 38 | 39 |