├── app
├── (frontend)
│ ├── favicon.ico
│ ├── page.jsx
│ ├── layout.jsx
│ ├── register
│ │ └── page.jsx
│ ├── login
│ │ └── page.jsx
│ ├── forgot-password
│ │ └── page.jsx
│ ├── reset-password
│ │ └── page.jsx
│ └── verify-account
│ │ └── [id]
│ │ └── page.jsx
├── globals.css
├── (backoffice)
│ ├── dashboard
│ │ ├── page.jsx
│ │ └── profile
│ │ │ └── page.jsx
│ └── layout.jsx
├── api
│ ├── uploadthing
│ │ ├── route.js
│ │ └── core.js
│ └── users
│ │ ├── [id]
│ │ └── route.js
│ │ └── route.js
└── layout.jsx
├── jsconfig.json
├── postcss.config.js
├── .env
├── lib
└── uploadthing.js
├── next.config.js
├── .gitignore
├── public
├── vercel.svg
└── next.svg
├── tailwind.config.js
├── package.json
├── components
├── backoffice
│ ├── Navbar.jsx
│ ├── Sidebar.jsx
│ └── ProfileForm.jsx
├── FormInputs
│ └── ImageInput.jsx
├── FooterSection.jsx
├── NavbarSection.jsx
├── HeroSection.jsx
├── ResetPasswordForm.jsx
├── ForgotPasswordForm.jsx
├── LoginForm.jsx
└── RegisterForm.jsx
└── README.md
/app/(frontend)/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MUKE-coder/auth-system-starter/HEAD/app/(frontend)/favicon.ico
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | UPLOADTHING_SECRET=sk_live_162e91451573e8f5733561171853fdaa8bc82a0da5cb6c955d9b35b743dc79c9
2 | UPLOADTHING_APP_ID=w0xo10mntp
--------------------------------------------------------------------------------
/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | body {
6 | min-height: 100vh;
7 | }
8 |
--------------------------------------------------------------------------------
/lib/uploadthing.js:
--------------------------------------------------------------------------------
1 | import { generateComponents } from "@uploadthing/react";
2 |
3 | export const { UploadButton, UploadDropzone, Uploader } = generateComponents();
4 |
--------------------------------------------------------------------------------
/app/(backoffice)/dashboard/page.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function page() {
4 | return (
5 |
6 |
Dashboard
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/app/(frontend)/page.jsx:
--------------------------------------------------------------------------------
1 | import HeroSection from "@/components/HeroSection";
2 | import Image from "next/image";
3 |
4 | export default function Home() {
5 | return (
6 |
7 |
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/app/api/uploadthing/route.js:
--------------------------------------------------------------------------------
1 | import { createNextRouteHandler } from "uploadthing/next";
2 |
3 | import { ourFileRouter } from "./core";
4 |
5 | // Export routes for Next App Router
6 | export const { GET, POST } = createNextRouteHandler({
7 | router: ourFileRouter,
8 | });
9 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: "https",
7 | hostname: "utfs.io",
8 | },
9 | ],
10 | },
11 | };
12 |
13 | module.exports = nextConfig;
14 |
--------------------------------------------------------------------------------
/app/(frontend)/layout.jsx:
--------------------------------------------------------------------------------
1 | import FooterSection from "@/components/FooterSection";
2 | import NavbarSection from "@/components/NavbarSection";
3 | import React from "react";
4 |
5 | export default function Layout({ children }) {
6 | return (
7 |
8 |
9 | {children}
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/app/(backoffice)/layout.jsx:
--------------------------------------------------------------------------------
1 | import Navbar from "@/components/backoffice/Navbar";
2 | import Sidebar from "@/components/backoffice/Sidebar";
3 | import React from "react";
4 |
5 | export default function Layout({ children }) {
6 | return (
7 |
8 |
9 |
10 |
11 | {children}
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/app/api/users/[id]/route.js:
--------------------------------------------------------------------------------
1 | import db from "@/lib/db";
2 | import { NextResponse } from "next/server";
3 |
4 | export async function GET(request, { params: { id } }) {
5 | try {
6 | const user = await db.user.findUnique({
7 | where: {
8 | id,
9 | },
10 | });
11 | return NextResponse.json(user);
12 | } catch (error) {
13 | console.log(error);
14 | return NextResponse.json(
15 | {
16 | message: "Failed to Fetch User",
17 | error,
18 | },
19 | { status: 500 }
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/api/uploadthing/core.js:
--------------------------------------------------------------------------------
1 | import { createUploadthing } from "uploadthing/next";
2 |
3 | const f = createUploadthing();
4 |
5 | // FileRouter for your app, can contain multiple FileRoutes
6 | export const ourFileRouter = {
7 | // Define as many FileRoutes as you like, each with a unique routeSlug
8 | profileImageUploader: f({ image: { maxFileSize: "1MB" } })
9 | // Set permissions and file types for this FileRoute
10 | .onUploadComplete(async ({ metadata, file }) => {
11 | console.log("file url", file.url, metadata);
12 | return { uploadedBy: "JB" };
13 | }),
14 | };
15 |
--------------------------------------------------------------------------------
/.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 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.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 |
38 |
39 | # Contentlayer
40 | .contentlayer
41 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | import { withUt } from "uploadthing/tw";
3 |
4 | export default withUt({
5 | content: [
6 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
8 | "node_modules/flowbite-react/lib/esm/**/*.js",
9 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
10 | ],
11 | theme: {
12 | extend: {
13 | backgroundImage: {
14 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
15 | "gradient-conic":
16 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
17 | },
18 | },
19 | },
20 | plugins: [require("flowbite/plugin")],
21 | });
22 |
--------------------------------------------------------------------------------
/app/(frontend)/register/page.jsx:
--------------------------------------------------------------------------------
1 | import RegisterForm from "@/components/RegisterForm";
2 |
3 | export default function Register() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 | Create a new account
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "auth-app",
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 | "@auth/prisma-adapter": "^1.0.11",
13 | "@prisma/client": "^5.7.1",
14 | "@uploadthing/react": "^6.0.2",
15 | "flowbite-react": "^0.7.2",
16 | "lucide-react": "^0.298.0",
17 | "next": "14.0.4",
18 | "next-auth": "^4.24.5",
19 | "react": "^18",
20 | "react-dom": "^18",
21 | "react-hook-form": "^7.49.2",
22 | "react-hot-toast": "^2.4.1",
23 | "uploadthing": "^6.1.0"
24 | },
25 | "devDependencies": {
26 | "autoprefixer": "^10.0.1",
27 | "postcss": "^8",
28 | "prisma": "^5.7.1",
29 | "tailwindcss": "^3.3.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/(frontend)/login/page.jsx:
--------------------------------------------------------------------------------
1 | import LoginForm from "@/components/LoginForm";
2 | import React from "react";
3 |
4 | export default function Login() {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 | Sign in to your account
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/app/(backoffice)/dashboard/profile/page.jsx:
--------------------------------------------------------------------------------
1 | import RegisterForm from "@/components/RegisterForm";
2 | import ProfileForm from "@/components/backoffice/ProfileForm";
3 |
4 | export default function Profile() {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 | Update your Profile
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/app/(frontend)/forgot-password/page.jsx:
--------------------------------------------------------------------------------
1 | import ForgotPasswordForm from "@/components/ForgotPasswordForm";
2 | import RegisterForm from "@/components/RegisterForm";
3 |
4 | export default function Register() {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 | Reset Password
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/app/(frontend)/reset-password/page.jsx:
--------------------------------------------------------------------------------
1 | import ForgotPasswordForm from "@/components/ForgotPasswordForm";
2 | import RegisterForm from "@/components/RegisterForm";
3 | import ResetPasswordForm from "@/components/ResetPasswordForm";
4 |
5 | export default function PasswordReset() {
6 | return (
7 |
8 |
9 |
10 |
11 |
12 | Reset Password
13 |
14 |
15 |
16 |
17 |
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/app/layout.jsx:
--------------------------------------------------------------------------------
1 | import { Inter } from "next/font/google";
2 | import "./globals.css";
3 | import { NextSSRPlugin } from "@uploadthing/react/next-ssr-plugin";
4 | import { extractRouterConfig } from "uploadthing/server";
5 | import { ourFileRouter } from "./api/uploadthing/core";
6 | const inter = Inter({ subsets: ["latin"] });
7 |
8 | export const metadata = {
9 | title: "Create Next App",
10 | description: "Generated by create next app",
11 | };
12 |
13 | export default function RootLayout({ children }) {
14 | return (
15 |
16 |
17 |
26 | {children}
27 |
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/backoffice/Navbar.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Avatar, Dropdown } from "flowbite-react";
3 | import { History } from "lucide-react";
4 | import Link from "next/link";
5 | import React from "react";
6 |
7 | export default function Navbar() {
8 | return (
9 |
10 |
11 |
12 |
13 |
22 | }
23 | >
24 |
25 | Bonnie Green
26 |
27 | name@flowbite.com
28 |
29 |
30 | Dashboard
31 | Settings
32 |
33 | Profile
34 |
35 |
36 | Sign out
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/app/(frontend)/verify-account/[id]/page.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { HiInformationCircle } from "react-icons/hi";
4 | import { Alert } from "flowbite-react";
5 |
6 | export default function VerifyAccount() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 | Verify Account
14 |
15 |
16 | Please Check your Email! We
17 | have sent you a Verification Link and Click on the Link to Verify
18 | your Account. Thank you!
19 |
20 |
21 |
22 | Did not see it?{" "}
23 |
24 | Resend the Link
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/app/api/users/route.js:
--------------------------------------------------------------------------------
1 | import db from "@/lib/db";
2 | import { NextResponse } from "next/server";
3 | import bcrypt from "bcrypt";
4 | export async function POST(request) {
5 | try {
6 | //extract the credentials
7 | const { name, email, password, role } = await request.json();
8 | //Check if the user Already exists in the db
9 | const existingUser = await db.user.findUnique({
10 | where: {
11 | email,
12 | },
13 | });
14 | if (existingUser) {
15 | return NextResponse.json(
16 | {
17 | data: null,
18 | message: `User with this email ( ${email}) already exists in the Database`,
19 | },
20 | { status: 409 }
21 | );
22 | }
23 | // Encrypt the Password =>bcrypt
24 | const hashedPassword = await bcrypt.hash(password, 10);
25 | const newUser = await db.user.create({
26 | data: {
27 | name,
28 | email,
29 | password: hashedPassword,
30 | role,
31 | },
32 | });
33 | console.log(newUser);
34 | return NextResponse.json(
35 | {
36 | data: newUser,
37 | message: "User Created Successfully",
38 | },
39 | { status: 201 }
40 | );
41 | } catch (error) {
42 | console.log(error);
43 | return NextResponse.json(
44 | {
45 | error,
46 | message: "Server Error: Something went wrong",
47 | },
48 | { status: 500 }
49 | );
50 | }
51 | }
52 | export async function GET(request) {
53 | try {
54 | const users = await db.user.findMany({
55 | orderBy: {
56 | createdAt: "desc",
57 | },
58 | });
59 | return NextResponse.json(users);
60 | } catch (error) {
61 | console.log(error);
62 | return NextResponse.json(
63 | {
64 | message: "Failed to Fetch Users",
65 | error,
66 | },
67 | { status: 500 }
68 | );
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/components/FormInputs/ImageInput.jsx:
--------------------------------------------------------------------------------
1 | import { UploadButton, UploadDropzone } from "@/lib/uploadthing";
2 | import { Pencil } from "lucide-react";
3 | import Image from "next/image";
4 | import React from "react";
5 | import toast from "react-hot-toast";
6 |
7 | export default function ImageInput({
8 | label,
9 | imageUrl = "",
10 | setImageUrl,
11 | className = "col-span-full",
12 | endpoint = "",
13 | }) {
14 | return (
15 |
16 |
17 |
21 | {label}
22 |
23 | {imageUrl && (
24 |
setImageUrl("")}
26 | type="button"
27 | className="flex space-x-2 bg-slate-900 rounded-md shadow text-slate-50 py-1.5 px-3"
28 | >
29 |
30 | Change Image
31 |
32 | )}
33 |
34 | {imageUrl ? (
35 |
42 | ) : (
43 |
44 | {
47 | setImageUrl(res[0].url);
48 | // Do something with the response
49 | toast.success("Image Upload complete");
50 | console.log("Files: ", res);
51 | console.log("Upload Completed");
52 | }}
53 | onUploadError={(error) => {
54 | toast.error("Image Upload Failed, Try Again");
55 | // Do something with the error.
56 | console.log(`ERROR! ${error.message}`, error);
57 | }}
58 | />
59 |
60 | )}
61 |
62 | );
63 | }
64 |
--------------------------------------------------------------------------------
/components/backoffice/Sidebar.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import {
3 | Codesandbox,
4 | History,
5 | Home,
6 | Layers3,
7 | LayoutGrid,
8 | Settings,
9 | User2,
10 | } from "lucide-react";
11 | import Link from "next/link";
12 | import { usePathname } from "next/navigation";
13 | import React from "react";
14 |
15 | export default function Sidebar() {
16 | const pathname = usePathname();
17 | const navLinks = [
18 | {
19 | title: "Dashboard",
20 | icon: Home,
21 | href: "/dashboard",
22 | },
23 | {
24 | title: "Profile",
25 | icon: User2,
26 | href: "/dashboard/profile",
27 | },
28 | {
29 | title: "Products",
30 | icon: Layers3,
31 | href: "/dashboard/products",
32 | },
33 | {
34 | title: "Categories",
35 | icon: LayoutGrid,
36 | href: "/dashboard/categories",
37 | },
38 | {
39 | title: "Settings",
40 | icon: Settings,
41 | href: "/dashboard/settings",
42 | },
43 | ];
44 | return (
45 |
46 |
47 |
48 | {/*
*/}
53 |
54 | Desishub
55 |
56 |
57 |
58 | {navLinks.map((link, i) => {
59 | const Icon = link.icon;
60 | return (
61 |
70 |
71 | {link.title}
72 |
73 | );
74 | })}
75 |
76 |
77 | );
78 | }
79 |
--------------------------------------------------------------------------------
/components/FooterSection.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Footer } from "flowbite-react";
4 | import {
5 | BsDribbble,
6 | BsFacebook,
7 | BsGithub,
8 | BsInstagram,
9 | BsTwitter,
10 | } from "react-icons/bs";
11 |
12 | export default function FooterSection() {
13 | return (
14 |
15 |
16 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
29 | Flowbite
30 | Tailwind CSS
31 |
32 |
33 |
34 |
35 |
36 | Github
37 | Discord
38 |
39 |
40 |
41 |
42 |
43 | Privacy Policy
44 | Terms & Conditions
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | );
63 | }
64 |
--------------------------------------------------------------------------------
/components/NavbarSection.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React from "react";
3 | import { Avatar, Button, Dropdown, Navbar } from "flowbite-react";
4 | import { Codesandbox } from "lucide-react";
5 | import Link from "next/link";
6 | export default function NavbarSection() {
7 | const isLoggedIn = false;
8 | return (
9 |
10 |
11 |
12 | {/* */}
17 |
18 | Desishub
19 |
20 |
21 |
22 | {isLoggedIn && (
23 |
32 | }
33 | >
34 |
35 | Bonnie Green
36 |
37 | name@flowbite.com
38 |
39 |
40 | Dashboard
41 | Settings
42 | Earnings
43 |
44 | Sign out
45 |
46 | )}
47 |
51 | Log in
52 |
53 |
57 | Get started
58 |
59 |
60 |
61 |
62 |
63 | Home
64 |
65 | About
66 | Services
67 | Pricing
68 | Contact
69 |
70 |
71 | );
72 | }
73 |
--------------------------------------------------------------------------------
/components/HeroSection.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function HeroSection() {
4 | return (
5 |
6 |
7 |
8 |
Smart email campaign builder, made for Developers
9 |
10 | Turn your visitors into profitable
11 |
12 |
13 | business
14 |
15 |
16 |
17 |
45 |
46 |
60 Days free trial · No credit card required
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | )
62 | }
63 |
--------------------------------------------------------------------------------
/components/ResetPasswordForm.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { signIn } from "next-auth/react";
3 | import { useRouter } from "next/navigation";
4 | import { useState } from "react";
5 | import { useForm } from "react-hook-form";
6 | import toast from "react-hot-toast";
7 | import Link from "next/link";
8 | import { FaGoogle } from "react-icons/fa";
9 | import { FaGithub } from "react-icons/fa";
10 | export default function ResetPasswordForm() {
11 | const router = useRouter();
12 | const {
13 | register,
14 | handleSubmit,
15 | reset,
16 | formState: { errors },
17 | } = useForm();
18 | const [loading, setLoading] = useState(false);
19 |
20 | async function onSubmit(data) {
21 | console.log(data);
22 | try {
23 | setLoading(true);
24 | console.log("Attempting to sign in with credentials:", data);
25 | const loginData = await signIn("credentials", {
26 | ...data,
27 | redirect: false,
28 | });
29 | console.log("SignIn response:", loginData);
30 | if (loginData?.error) {
31 | setLoading(false);
32 | toast.error("Sign-in error: Check your credentials");
33 | } else {
34 | // Sign-in was successful
35 | toast.success("Login Successful");
36 | reset();
37 | router.push("/");
38 | }
39 | } catch (error) {
40 | setLoading(false);
41 | console.error("Network Error:", error);
42 | toast.error("Its seems something is wrong with your Network");
43 | }
44 | }
45 |
46 | return (
47 |
104 | );
105 | }
106 |
--------------------------------------------------------------------------------
/components/ForgotPasswordForm.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { signIn } from "next-auth/react";
3 | import { useRouter } from "next/navigation";
4 | import { useState } from "react";
5 | import { useForm } from "react-hook-form";
6 | import toast from "react-hot-toast";
7 | import Link from "next/link";
8 | import { FaGoogle } from "react-icons/fa";
9 | import { FaGithub } from "react-icons/fa";
10 | export default function ForgotPasswordForm() {
11 | const router = useRouter();
12 | const {
13 | register,
14 | handleSubmit,
15 | reset,
16 | formState: { errors },
17 | } = useForm();
18 | const [loading, setLoading] = useState(false);
19 |
20 | async function onSubmit(data) {
21 | console.log(data);
22 | try {
23 | setLoading(true);
24 | console.log("Attempting to sign in with credentials:", data);
25 | const loginData = await signIn("credentials", {
26 | ...data,
27 | redirect: false,
28 | });
29 | console.log("SignIn response:", loginData);
30 | if (loginData?.error) {
31 | setLoading(false);
32 | toast.error("Sign-in error: Check your credentials");
33 | } else {
34 | // Sign-in was successful
35 | toast.success("Login Successful");
36 | reset();
37 | router.push("/");
38 | }
39 | } catch (error) {
40 | setLoading(false);
41 | console.error("Network Error:", error);
42 | toast.error("Its seems something is wrong with your Network");
43 | }
44 | }
45 |
46 | return (
47 |
115 | );
116 | }
117 |
--------------------------------------------------------------------------------
/components/backoffice/ProfileForm.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { signIn } from "next-auth/react";
3 | import Link from "next/link";
4 | import { useRouter } from "next/navigation";
5 | import { useState } from "react";
6 | import { useForm } from "react-hook-form";
7 | import toast from "react-hot-toast";
8 | import { FaGithub, FaGoogle } from "react-icons/fa";
9 | import ImageInput from "../FormInputs/ImageInput";
10 |
11 | export default function ProfileForm() {
12 | const router = useRouter();
13 | const {
14 | register,
15 | handleSubmit,
16 | reset,
17 | formState: { errors },
18 | } = useForm();
19 | const [imageUrl, setImageUrl] = useState(
20 | "https://utfs.io/f/8b034fb4-1f45-425a-8c57-a7a68835311f-2558r.png"
21 | );
22 | const [loading, setLoading] = useState(false);
23 | const [emailErr, setEmailErr] = useState("");
24 | async function onSubmit(data) {
25 | try {
26 | console.log(data);
27 | setLoading(true);
28 | const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
29 | const response = await fetch(`${baseUrl}/api/user`, {
30 | method: "POST",
31 | headers: {
32 | "Content-Type": "application/json",
33 | },
34 | body: JSON.stringify(data),
35 | });
36 |
37 | const responseData = await response.json();
38 |
39 | if (response.ok) {
40 | setLoading(false);
41 | toast.success("User Created Successfully");
42 | reset();
43 | router.push("/login");
44 | } else {
45 | setLoading(false);
46 | if (response.status === 409) {
47 | setEmailErr("User with this Email already exists");
48 | toast.error("User with this Email already exists");
49 | } else {
50 | // Handle other errors
51 | console.error("Server Error:", responseData.message);
52 | toast.error("Oops Something Went wrong");
53 | }
54 | }
55 | } catch (error) {
56 | setLoading(false);
57 | console.error("Network Error:", error);
58 | toast.error("Something Went wrong, Please Try Again");
59 | }
60 | }
61 |
62 | return (
63 |
152 | );
153 | }
154 |
--------------------------------------------------------------------------------
/components/LoginForm.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { signIn } from "next-auth/react";
3 | import { useRouter } from "next/navigation";
4 | import { useState } from "react";
5 | import { useForm } from "react-hook-form";
6 | import toast from "react-hot-toast";
7 | import Link from "next/link";
8 | import { FaGoogle } from "react-icons/fa";
9 | import { FaGithub } from "react-icons/fa";
10 | export default function LoginForm() {
11 | const router = useRouter();
12 | const {
13 | register,
14 | handleSubmit,
15 | reset,
16 | formState: { errors },
17 | } = useForm();
18 | const [loading, setLoading] = useState(false);
19 |
20 | async function onSubmit(data) {
21 | console.log(data);
22 | try {
23 | setLoading(true);
24 | console.log("Attempting to sign in with credentials:", data);
25 | const loginData = await signIn("credentials", {
26 | ...data,
27 | redirect: false,
28 | });
29 | console.log("SignIn response:", loginData);
30 | if (loginData?.error) {
31 | setLoading(false);
32 | toast.error("Sign-in error: Check your credentials");
33 | } else {
34 | // Sign-in was successful
35 | toast.success("Login Successful");
36 | reset();
37 | router.push("/");
38 | }
39 | } catch (error) {
40 | setLoading(false);
41 | console.error("Network Error:", error);
42 | toast.error("Its seems something is wrong with your Network");
43 | }
44 | }
45 |
46 | return (
47 |
168 | );
169 | }
170 |
--------------------------------------------------------------------------------
/components/RegisterForm.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { signIn } from "next-auth/react";
3 | import Link from "next/link";
4 | import { useRouter } from "next/navigation";
5 | import { useState } from "react";
6 | import { useForm } from "react-hook-form";
7 | import toast from "react-hot-toast";
8 | import { FaGithub, FaGoogle } from "react-icons/fa";
9 |
10 | export default function RegisterForm() {
11 | const router = useRouter();
12 | const {
13 | register,
14 | handleSubmit,
15 | reset,
16 | formState: { errors },
17 | } = useForm();
18 | const [loading, setLoading] = useState(false);
19 | const [emailErr, setEmailErr] = useState("");
20 | async function onSubmit(data) {
21 | try {
22 | console.log(data);
23 | setLoading(true);
24 | const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
25 | const response = await fetch(`${baseUrl}/api/user`, {
26 | method: "POST",
27 | headers: {
28 | "Content-Type": "application/json",
29 | },
30 | body: JSON.stringify(data),
31 | });
32 |
33 | const responseData = await response.json();
34 |
35 | if (response.ok) {
36 | setLoading(false);
37 | toast.success("User Created Successfully");
38 | reset();
39 | router.push("/login");
40 | } else {
41 | setLoading(false);
42 | if (response.status === 409) {
43 | setEmailErr("User with this Email already exists");
44 | toast.error("User with this Email already exists");
45 | } else {
46 | // Handle other errors
47 | console.error("Server Error:", responseData.message);
48 | toast.error("Oops Something Went wrong");
49 | }
50 | }
51 | } catch (error) {
52 | setLoading(false);
53 | console.error("Network Error:", error);
54 | toast.error("Something Went wrong, Please Try Again");
55 | }
56 | }
57 |
58 | return (
59 |
194 | );
195 | }
196 |
--------------------------------------------------------------------------------