Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 1 - authprovider
- import { auth } from "@/firbaseConfig";
- import {
- onAuthStateChanged,
- signInWithPopup,
- GoogleAuthProvider,
- signOut,
- createUserWithEmailAndPassword,
- signInWithEmailAndPassword,
- GithubAuthProvider,
- } from "firebase/auth";
- import { useRouter } from "next/router";
- import {
- useEffect,
- useState,
- createContext,
- useContext,
- useMemo,
- useCallback,
- } from "react";
- export const AuthContext = createContext({
- user: null,
- signUp: async () => {},
- login: async () => {},
- loginWithProvider: async () => {},
- logout: async () => {},
- error: "",
- loading: true,
- });
- export const AuthProvider = ({ children }) => {
- const [user, setUser] = useState(null);
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState("");
- const router = useRouter();
- const home = () => router.replace("/");
- useEffect(() => {
- const unsubscribe = onAuthStateChanged(auth, (user) => {
- setUser(user);
- setLoading(false);
- });
- console.log(user ?? "no data");
- return () => unsubscribe();
- }, []);
- const signUp = useCallback(
- async (email, password) => {
- setLoading(true);
- try {
- const credential = await createUserWithEmailAndPassword(
- auth,
- email,
- password
- );
- setUser(credential.user);
- } catch (error) {
- setError(error.message);
- } finally {
- setLoading(false);
- }
- },
- [auth, setUser, setError]
- );
- const login = useCallback(
- async (email, password) => {
- setLoading(true);
- try {
- const credential = await signInWithEmailAndPassword(
- auth,
- email,
- password
- );
- setUser(credential.user);
- } catch (error) {
- setError(error.message);
- } finally {
- setLoading(false);
- }
- },
- [auth, setUser, setError]
- );
- const loginWithProvider = useCallback(
- async (providerName) => {
- setLoading(true);
- try {
- let provider;
- if (providerName === "google") {
- provider = new GoogleAuthProvider();
- } else if (providerName === "github") {
- provider = new GithubAuthProvider();
- } else {
- throw new Error("Invalid provider");
- }
- const credential = await signInWithPopup(auth, provider);
- setUser(credential.user);
- } catch (error) {
- setError(error.message);
- } finally {
- setLoading(false);
- }
- },
- [auth, setUser, setError]
- );
- const logout = useCallback(async () => {
- setLoading(true);
- try {
- await signOut(auth);
- setUser(null);
- } catch (error) {
- setError(error.message);
- } finally {
- setLoading(false);
- }
- }, [auth, setUser, setError]);
- const authContextValue = useMemo(
- () => ({
- user,
- signUp,
- login,
- loginWithProvider,
- logout,
- error,
- loading,
- }),
- [user, signUp, login, loginWithProvider, logout, error, loading]
- );
- return (
- <AuthContext.Provider value={authContextValue}>
- {children}
- </AuthContext.Provider>
- );
- };
- export const useAuth = () => useContext(AuthContext);
- 2 - withAuth(protecting routes)
- import { useEffect } from "react";
- import { useAuth } from "./auth";
- import { useRouter } from "next/router";
- export default function withAuth(Component) {
- return function WithAuthComponent(props) {
- const { loading, user } = useAuth();
- const router = useRouter();
- useEffect(() => {
- if (loading && !user) {
- router.push("/login");
- } else if (!loading && user) {
- router.push("/");
- }
- }, [loading, user, router]);
- if (loading) return <div>Loading...</div>;
- return <Component {...props} />;
- };
- }
- 3 - login
- import React, { useState, useRef } from "react";
- import { IoLogoGithub } from "react-icons/io";
- import { AiOutlineEye, AiOutlineEyeInvisible } from "react-icons/ai";
- import { useAuth } from "@/provider/auth";
- function Login() {
- const { loginWithProvider } = useAuth();
- const [showPass, setShowPass] = useState(false);
- const [showEmail, setShowEmail] = useState(false);
- const handleShowPass = () => {
- setShowPass((prev) => !prev);
- passRef.current.blur();
- };
- const handleShowEmail = () => {
- setShowEmail((prev) => !prev);
- emailRef.current.blur();
- };
- const emailRef = useRef(null);
- const passRef = useRef(null);
- return (
- <div className="h-screen flex items-center justify-center bg-c1">
- <div className="flex flex-col items-center w-full max-w-md md:max-w-xl px-4">
- <h1 className="text-2xl md:text-4xl font-bold text-center">
- Login to Your Account
- </h1>
- <p className="text-c3 mt-3 text-center">
- Connect and chat with anyone, anywhere
- </p>
- <div className="flex flex-col md:flex-row items-center gap-2 mt-4 space-x-4">
- <button
- onClick={() => loginWithProvider("google")}
- className="flex items-center justify-center px-4 py-2 border border-slate-200 rounded-lg hover:border-slate-400 hover:text-slate-100 hover:shadow transition duration-150"
- >
- <img
- className="w-6 h-6 mr-2"
- src="https://www.svgrepo.com/show/475656/google-color.svg"
- loading="lazy"
- alt="google logo"
- />
- <span>Login with Google</span>
- </button>
- <button
- onClick={() => loginWithProvider("github")}
- className="flex items-center justify-center px-4 py-2 border border-slate-200 rounded-lg hover:border-slate-400 hover:text-slate-100 hover:shadow transition duration-150"
- >
- <IoLogoGithub className="w-6 h-6 mr-2" />
- <span>Login with GitHub</span>
- </button>
- </div>
- {/* -OR- */}
- <div className="flex items-center gap-1">
- <span className="w-5 h-[1px] bg-c3" />
- <span>OR</span>
- <span className="bg-c3 w-5 h-[1px]" />
- </div>
- <form className="flex flex-col items-center gap-3 mt-5 w-full md:max-w-md">
- <div className="w-full flex justify-between bg-c5 rounded-lg py-2 px-5">
- <input
- className="w-full bg-c5 outline-none border-none text-c3 "
- // type={showEmail ? "text" : "password"}
- type="email"
- ref={emailRef}
- required
- placeholder="Email"
- autoComplete="off"
- />
- <span>
- <button onClick={handleShowEmail}>
- {showEmail ? (
- <>
- <AiOutlineEye className="text-white" />
- </>
- ) : (
- <>
- <AiOutlineEyeInvisible />
- </>
- )}
- </button>
- </span>
- </div>
- <div className="w-full flex justify-between bg-c5 rounded-lg py-2 px-5">
- <input
- ref={passRef}
- className="w-full bg-c5 outline-none border-none text-c3 "
- type={showPass ? "text" : "password"}
- required
- placeholder="Password"
- autoComplete="off"
- />
- <span>
- <button onClick={handleShowPass}>
- {showPass ? (
- <>
- <AiOutlineEye className="text-white" />
- </>
- ) : (
- <>
- <AiOutlineEyeInvisible />
- </>
- )}
- </button>
- </span>
- </div>
- <div></div>
- </form>
- </div>
- </div>
- );
- }
- export default Login;
Advertisement
Add Comment
Please, Sign In to add comment