Guest User

Untitled

a guest
Jul 3rd, 2023
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.89 KB | None | 0 0
  1. 1 - authprovider
  2. import { auth } from "@/firbaseConfig";
  3. import {
  4. onAuthStateChanged,
  5. signInWithPopup,
  6. GoogleAuthProvider,
  7. signOut,
  8. createUserWithEmailAndPassword,
  9. signInWithEmailAndPassword,
  10. GithubAuthProvider,
  11. } from "firebase/auth";
  12. import { useRouter } from "next/router";
  13. import {
  14. useEffect,
  15. useState,
  16. createContext,
  17. useContext,
  18. useMemo,
  19. useCallback,
  20. } from "react";
  21.  
  22. export const AuthContext = createContext({
  23. user: null,
  24. signUp: async () => {},
  25. login: async () => {},
  26. loginWithProvider: async () => {},
  27. logout: async () => {},
  28. error: "",
  29. loading: true,
  30. });
  31.  
  32. export const AuthProvider = ({ children }) => {
  33. const [user, setUser] = useState(null);
  34. const [loading, setLoading] = useState(true);
  35. const [error, setError] = useState("");
  36. const router = useRouter();
  37. const home = () => router.replace("/");
  38.  
  39. useEffect(() => {
  40. const unsubscribe = onAuthStateChanged(auth, (user) => {
  41. setUser(user);
  42. setLoading(false);
  43. });
  44. console.log(user ?? "no data");
  45. return () => unsubscribe();
  46. }, []);
  47.  
  48. const signUp = useCallback(
  49. async (email, password) => {
  50. setLoading(true);
  51.  
  52. try {
  53. const credential = await createUserWithEmailAndPassword(
  54. auth,
  55. email,
  56. password
  57. );
  58.  
  59. setUser(credential.user);
  60. } catch (error) {
  61. setError(error.message);
  62. } finally {
  63. setLoading(false);
  64. }
  65. },
  66. [auth, setUser, setError]
  67. );
  68.  
  69. const login = useCallback(
  70. async (email, password) => {
  71. setLoading(true);
  72.  
  73. try {
  74. const credential = await signInWithEmailAndPassword(
  75. auth,
  76. email,
  77. password
  78. );
  79.  
  80. setUser(credential.user);
  81. } catch (error) {
  82. setError(error.message);
  83. } finally {
  84. setLoading(false);
  85. }
  86. },
  87. [auth, setUser, setError]
  88. );
  89.  
  90. const loginWithProvider = useCallback(
  91. async (providerName) => {
  92. setLoading(true);
  93.  
  94. try {
  95. let provider;
  96.  
  97. if (providerName === "google") {
  98. provider = new GoogleAuthProvider();
  99. } else if (providerName === "github") {
  100. provider = new GithubAuthProvider();
  101. } else {
  102. throw new Error("Invalid provider");
  103. }
  104.  
  105. const credential = await signInWithPopup(auth, provider);
  106. setUser(credential.user);
  107. } catch (error) {
  108. setError(error.message);
  109. } finally {
  110. setLoading(false);
  111. }
  112. },
  113. [auth, setUser, setError]
  114. );
  115.  
  116. const logout = useCallback(async () => {
  117. setLoading(true);
  118.  
  119. try {
  120. await signOut(auth);
  121. setUser(null);
  122. } catch (error) {
  123. setError(error.message);
  124. } finally {
  125. setLoading(false);
  126. }
  127. }, [auth, setUser, setError]);
  128.  
  129. const authContextValue = useMemo(
  130. () => ({
  131. user,
  132. signUp,
  133. login,
  134. loginWithProvider,
  135. logout,
  136. error,
  137. loading,
  138. }),
  139. [user, signUp, login, loginWithProvider, logout, error, loading]
  140. );
  141.  
  142. return (
  143. <AuthContext.Provider value={authContextValue}>
  144. {children}
  145. </AuthContext.Provider>
  146. );
  147. };
  148.  
  149. export const useAuth = () => useContext(AuthContext);
  150. 2 - withAuth(protecting routes)
  151. import { useEffect } from "react";
  152. import { useAuth } from "./auth";
  153. import { useRouter } from "next/router";
  154.  
  155. export default function withAuth(Component) {
  156. return function WithAuthComponent(props) {
  157. const { loading, user } = useAuth();
  158. const router = useRouter();
  159. useEffect(() => {
  160. if (loading && !user) {
  161. router.push("/login");
  162. } else if (!loading && user) {
  163. router.push("/");
  164. }
  165. }, [loading, user, router]);
  166.  
  167. if (loading) return <div>Loading...</div>;
  168. return <Component {...props} />;
  169. };
  170. }
  171. 3 - login
  172. import React, { useState, useRef } from "react";
  173. import { IoLogoGithub } from "react-icons/io";
  174. import { AiOutlineEye, AiOutlineEyeInvisible } from "react-icons/ai";
  175. import { useAuth } from "@/provider/auth";
  176. function Login() {
  177. const { loginWithProvider } = useAuth();
  178. const [showPass, setShowPass] = useState(false);
  179. const [showEmail, setShowEmail] = useState(false);
  180. const handleShowPass = () => {
  181. setShowPass((prev) => !prev);
  182. passRef.current.blur();
  183. };
  184.  
  185. const handleShowEmail = () => {
  186. setShowEmail((prev) => !prev);
  187. emailRef.current.blur();
  188. };
  189. const emailRef = useRef(null);
  190. const passRef = useRef(null);
  191. return (
  192. <div className="h-screen flex items-center justify-center bg-c1">
  193. <div className="flex flex-col items-center w-full max-w-md md:max-w-xl px-4">
  194. <h1 className="text-2xl md:text-4xl font-bold text-center">
  195. Login to Your Account
  196. </h1>
  197. <p className="text-c3 mt-3 text-center">
  198. Connect and chat with anyone, anywhere
  199. </p>
  200. <div className="flex flex-col md:flex-row items-center gap-2 mt-4 space-x-4">
  201. <button
  202. onClick={() => loginWithProvider("google")}
  203. 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"
  204. >
  205. <img
  206. className="w-6 h-6 mr-2"
  207. src="https://www.svgrepo.com/show/475656/google-color.svg"
  208. loading="lazy"
  209. alt="google logo"
  210. />
  211. <span>Login with Google</span>
  212. </button>
  213. <button
  214. onClick={() => loginWithProvider("github")}
  215. 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"
  216. >
  217. <IoLogoGithub className="w-6 h-6 mr-2" />
  218. <span>Login with GitHub</span>
  219. </button>
  220. </div>
  221. {/* -OR- */}
  222. <div className="flex items-center gap-1">
  223. <span className="w-5 h-[1px] bg-c3" />
  224. <span>OR</span>
  225. <span className="bg-c3 w-5 h-[1px]" />
  226. </div>
  227. <form className="flex flex-col items-center gap-3 mt-5 w-full md:max-w-md">
  228. <div className="w-full flex justify-between bg-c5 rounded-lg py-2 px-5">
  229. <input
  230. className="w-full bg-c5 outline-none border-none text-c3 "
  231. // type={showEmail ? "text" : "password"}
  232. type="email"
  233. ref={emailRef}
  234. required
  235. placeholder="Email"
  236. autoComplete="off"
  237. />
  238. <span>
  239. <button onClick={handleShowEmail}>
  240. {showEmail ? (
  241. <>
  242. <AiOutlineEye className="text-white" />
  243. </>
  244. ) : (
  245. <>
  246. <AiOutlineEyeInvisible />
  247. </>
  248. )}
  249. </button>
  250. </span>
  251. </div>
  252. <div className="w-full flex justify-between bg-c5 rounded-lg py-2 px-5">
  253. <input
  254. ref={passRef}
  255. className="w-full bg-c5 outline-none border-none text-c3 "
  256. type={showPass ? "text" : "password"}
  257. required
  258. placeholder="Password"
  259. autoComplete="off"
  260. />
  261. <span>
  262. <button onClick={handleShowPass}>
  263. {showPass ? (
  264. <>
  265. <AiOutlineEye className="text-white" />
  266. </>
  267. ) : (
  268. <>
  269. <AiOutlineEyeInvisible />
  270. </>
  271. )}
  272. </button>
  273. </span>
  274. </div>
  275. <div></div>
  276. </form>
  277. </div>
  278. </div>
  279. );
  280. }
  281.  
  282. export default Login;
  283.  
Advertisement
Add Comment
Please, Sign In to add comment