diff --git a/components/Authentication/SignInForm.js b/components/Authentication/SignInForm.js index 29c3668..5b666fd 100644 --- a/components/Authentication/SignInForm.js +++ b/components/Authentication/SignInForm.js @@ -1,7 +1,7 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { useRouter } from "next/router"; -import { setCookie } from 'cookies-next'; -import Link from "next/link"; +import { setCookie } from "cookies-next"; +import { useSnackbar } from "notistack"; import Grid from "@mui/material/Grid"; import LoadingButton from "@mui/lab/LoadingButton"; import IconButton from "@mui/material/IconButton"; @@ -14,8 +14,12 @@ import Visibility from "@mui/icons-material/Visibility"; import VisibilityOff from "@mui/icons-material/VisibilityOff"; import styles from "./signinform.module.css"; import Fetcher from "services/Fetcher"; +import { useUserProfile } from "contexts/userProfileContext"; const SignInForm = () => { + const { state, dispatch } = useUserProfile(); + + // Define and initialize state variables const [formValues, setFormValues] = useState({ email: "", password: "", @@ -27,79 +31,123 @@ const SignInForm = () => { const [loading, setLoading] = useState(false); const [errMsg, setErrMsg] = useState(""); + // Create instances of external services const api = new Fetcher(); const router = useRouter(); + // Access the Snackbar notification function + const { enqueueSnackbar } = useSnackbar(); + + // Handle changes in the input fields const handleChange = (event) => { setFormValues({ ...formValues, [event.target.name]: event.target.value }); }; - // "use server" + // Handle form submission const handleSubmit = async (event) => { event.preventDefault(); const { email, password } = formValues; - if (email === "" || password === "") { + // Validate the form fields + if (email === "" && password === "") { setErrorHandlers({ ...errorHandlers, email: true, password: true }); + setErrMsg("all fields are required"); setTimeout(() => { setErrorHandlers({ ...errorHandlers, email: false, password: false }); - }, 1500); + setErrMsg(""); + }, 2000); return; } else if (email === "") { setErrorHandlers({ ...errorHandlers, email: true }); + setErrMsg("email field is required"); setTimeout(() => { setErrorHandlers({ ...errorHandlers, email: false }); - }, 1500); + setErrMsg(""); + }, 2000); return; } else if (password === "") { setErrorHandlers({ ...errorHandlers, password: true }); + setErrMsg("password field is required"); setTimeout(() => { setErrorHandlers({ ...errorHandlers, password: false }); - }, 1500); + setErrMsg(""); + }, 2000); return; } + // Initiate the login process setLoading(true); try { + // Prepare the login request data const data = { username: email, password, }; + + // Send the login request to the server const res = await api.login(data); if (res.status === 204 || res.length === 0) { - setErrorHandlers({ ...errorHandlers, email: true, password: true }); - setErrMsg("Wrong Credentials"); - setTimeout(() => { - setErrorHandlers({ ...errorHandlers, email: false, password: false }); - setLoading(false); - setErrMsg(""); - }, 1500); + // Handle login failure + enqueueSnackbar("Wrong Credentials", { + variant: "error", + }); + setLoading(false); + return; } // Store the token in cookies - await setCookie("cmc-token", res.token); - router.push("/"); + // Calculate the expiration time in 24 hours + const expirationDate = new Date(); + expirationDate.setTime(expirationDate.getTime() + 24 * 60 * 60 * 1000); // 24 hours in milliseconds + const cookieOptions = { + expires: expirationDate, + httpOnly: true, // Make the cookie accessible only via HTTP (recommended for security) + }; + + + // Set the login token in a cookie + await setCookie("cmc-token", res.token); + + const userProfileData = res.profile; + dispatch({ type: 'SET_USER_PROFILE', payload: userProfileData }); + + enqueueSnackbar("Login Successful", { + variant: "success", + autoHideDuration: 4000, + }); + + // Redirect the user to a new page after successful login + router.push("/"); console.log(res); } catch (error) { + // Handle any errors that occur during login setLoading(false); console.log(error); } finally { + // Ensure that the loading indicator is cleared after a short delay setTimeout(() => { setLoading(false); }, 5000); } }; + // Define and initialize the state variable for toggling password visibility const [showPassword, setShowPassword] = useState(false); + // Toggle password visibility const handleTogglePassword = () => { setShowPassword(!showPassword); }; + useEffect(() => { + // Prefetch the dashboard page to optimize navigation + router.prefetch("/"); + }); + return ( <>
@@ -129,15 +177,6 @@ const SignInForm = () => { className={styles.favicon} /> - {/* - Sign In{" "} - */} { > - {/* - Email - */} - { - {/* - Password - */} - { }, }} > - - {loading ? "Signing in…" : errMsg ? errMsg : "Sign In"} - + {loading ? "Signing in…" : "Sign In"} diff --git a/components/_App/Layout.js b/components/_App/Layout.js index edca465..9b6e926 100644 --- a/components/_App/Layout.js +++ b/components/_App/Layout.js @@ -6,7 +6,6 @@ import TopNavbar from "@/components/_App/TopNavbar"; import Footer from "@/components/_App/Footer"; import ScrollToTop from "./ScrollToTop"; import ControlPanelModal from "./ControlPanelModal"; -import AuthRoute from "middlewares/AuthRoute"; const Layout = ({ children }) => { const router = useRouter(); @@ -20,14 +19,11 @@ const Layout = ({ children }) => { useEffect(() => { const authenticationPages = [ - // "/", - "/auth", "/auth/login", "/auth/sign-up", "/auth/forgot-password", "/auth/lock-screen", "/auth/confirm-mail", - "/auth/logout", ]; setIsAuthenticationPage(authenticationPages.includes(router.pathname)); @@ -37,9 +33,6 @@ const Layout = ({ children }) => { // console.log("isAuthenticationPage:", isAuthenticationPage, router.pathname); const title = isAuthenticationPage ? "CMC - auth" : "CMC - dashboard"; - const mainWrapper = { - paddingLeft: typeof window !== "undefined" && isAuthenticationPage && "0" - } return ( <> @@ -49,8 +42,9 @@ const Layout = ({ children }) => {
{!isAuthenticationPage && ( <> @@ -65,7 +59,9 @@ const Layout = ({ children }) => { {children}
- {!isAuthenticationPage &&
diff --git a/components/_App/LeftSidebar/SidebarData.js b/components/_App/LeftSidebar/SidebarData.js index 11bce30..a74dff5 100644 --- a/components/_App/LeftSidebar/SidebarData.js +++ b/components/_App/LeftSidebar/SidebarData.js @@ -6,6 +6,7 @@ import LayersIcon from "@mui/icons-material/Layers"; import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import LockIcon from "@mui/icons-material/Lock"; +import LogoutIcon from "@mui/icons-material/Logout"; import SettingsIcon from "@mui/icons-material/Settings"; import PostAddIcon from "@mui/icons-material/PostAdd"; import MailOutlineIcon from "@mui/icons-material/MailOutline"; @@ -513,4 +514,9 @@ export const SidebarData = [ }, ], }, + { + title: "Logout", + path: "/auth/logout", + icon: , + }, ]; diff --git a/components/_App/LeftSidebar/index.js b/components/_App/LeftSidebar/index.js index bbd1224..8f5ff9d 100644 --- a/components/_App/LeftSidebar/index.js +++ b/components/_App/LeftSidebar/index.js @@ -1,69 +1,69 @@ -import React from 'react'; -import { - Box -} from "@mui/material"; +import React from "react"; +import { Box } from "@mui/material"; import { styled } from "@mui/material/styles"; -import { SidebarData } from './SidebarData'; -import SubMenu from './SubMenu'; -import Link from 'next/link'; -import ClearIcon from '@mui/icons-material/Clear'; -import IconButton from '@mui/material/IconButton'; +import { SidebarData } from "./SidebarData"; +import SubMenu from "./SubMenu"; +import Link from "next/link"; +import ClearIcon from "@mui/icons-material/Clear"; +import IconButton from "@mui/material/IconButton"; const SidebarNav = styled("nav")(({ theme }) => ({ - background: '#fff', + background: "#fff", boxShadow: "0px 4px 20px rgba(47, 143, 232, 0.07)", - width: '300px', - padding: '30px 10px', - height: '100vh', - display: 'flex', - justifyContent: 'center', - position: 'fixed', + width: "300px", + padding: "30px 10px", + height: "100vh", + display: "flex", + justifyContent: "center", + position: "fixed", top: 0, left: 0, - transition: '350ms', - zIndex: '10', - overflowY: 'auto' + transition: "350ms", + zIndex: "10", + overflowY: "auto", })); - + const SidebarWrap = styled("div")(({ theme }) => ({ - width: '100%' + width: "100%", })); const Sidebar = ({ toggleActive }) => { return ( <> -
+
- - - Logo + Logo {/* For Dark Variation */} - Logo - diff --git a/components/_App/TopNavbar/Profile.js b/components/_App/TopNavbar/Profile.js index 8c8c93a..4d60705 100644 --- a/components/_App/TopNavbar/Profile.js +++ b/components/_App/TopNavbar/Profile.js @@ -17,8 +17,12 @@ import MailOutlineIcon from "@mui/icons-material/MailOutline"; import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutline"; import AttachMoneyIcon from "@mui/icons-material/AttachMoney"; import Logout from "@mui/icons-material/Logout"; +import { useUserProfile } from "contexts/userProfileContext"; const Profile = () => { + const { state } = useUserProfile(); + const userProfile = state.userProfile; + const [anchorEl, setAnchorEl] = React.useState(null); const open = Boolean(anchorEl); const handleClick = (event) => { diff --git a/contexts/userProfileContext.js b/contexts/userProfileContext.js new file mode 100644 index 0000000..9af0b95 --- /dev/null +++ b/contexts/userProfileContext.js @@ -0,0 +1,38 @@ +// UserProfileContext.js +import { createContext, useContext, useReducer } from "react"; + +// Define the initial state +const initialState = { + userProfile: null, +}; + +// Create the context +const UserProfileContext = createContext(); + +// Create a custom hook for using the context +export const useUserProfile = () => { + return useContext(UserProfileContext); +}; + +// Define a reducer function to update the context state +const userProfileReducer = (state, action) => { + switch (action.type) { + case "SET_USER_PROFILE": + return { ...state, userProfile: action.payload }; + case "CLEAR_USER_PROFILE": + return { ...state, userProfile: null }; + default: + return state; + } +}; + +// Create the UserProfileProvider component +export const UserProfileProvider = ({ children }) => { + const [state, dispatch] = useReducer(userProfileReducer, initialState); + + return ( + + {children} + + ); +}; diff --git a/middleware.js b/middleware.js index a8c1570..2f412c3 100644 --- a/middleware.js +++ b/middleware.js @@ -32,17 +32,6 @@ export async function middleware(req, next) { }); } - // Add authentication logic here (verify the token, etc.) - // const isAuthenticated = verifyToken(token); - // const isAuthenticated = hasCookie("cmc-token", { req }); - - // if (!isAuthenticated) { - // // Handle unauthenticated users - // return NextResponse.error(new Error("Authentication failed"), { - // status: 401, - // }); - // } - } catch (error) { console.error("Error during authentication check:", error); return NextResponse.error(); @@ -54,12 +43,7 @@ export const config = { }; const authenticationPages = [ - // "/", - "/auth", "/auth/login", "/auth/sign-up", - "/auth/forgot-password", - "/auth/lock-screen", - "/auth/confirm-mail", "/auth/logout", ]; diff --git a/pages/_app.js b/pages/_app.js index c663c75..2fe7406 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; import "../styles/remixicon.css"; import "react-tabs/style/react-tabs.css"; import "swiper/css"; @@ -13,18 +13,51 @@ import "../styles/rtl.css"; import "../styles/dark.css"; // Theme Styles import theme from "../styles/theme"; - +import { SnackbarProvider } from "notistack"; import { ThemeProvider, CssBaseline } from "@mui/material"; import Layout from "@/components/_App/Layout"; +import { UserProfileProvider } from "contexts/userProfileContext"; +import { useRouter } from "next/router"; +import { hasCookie } from "cookies-next"; function MyApp({ Component, pageProps }) { + const router = useRouter(); + + const handlePopState = () => { + // Check if the user is logged in or if you need to redirect them after logout + if (!hasCookie("cmc-token")) { + router.push("/auth/login"); + } + }; + + // Attach the event handler when the component mounts + useEffect(() => { + window.onpopstate = handlePopState; + + // Clean up the event handler when the component unmounts + return () => { + window.onpopstate = null; + }; + }, []); + return ( <> + + {!hasCookie("cmc-token") && "CMC - auth"} + - - - + + + + + + + ); diff --git a/pages/auth/logout.js b/pages/auth/logout.js index f4b6894..1aeb13f 100644 --- a/pages/auth/logout.js +++ b/pages/auth/logout.js @@ -1,8 +1,22 @@ +import { useRouter } from "next/router"; import { Typography } from "@mui/material"; import { Box } from "@mui/system"; import Button from "@mui/material/Button"; +import LogoutIcon from "@mui/icons-material/Logout"; +import { deleteCookie } from "cookies-next"; export default function Logout() { + const router = useRouter(); + const handleLogout = () => { + // Remove the cookie + deleteCookie("cmc-token"); + + // Use replaceState to replace the current URL with the root URL + window.history.replaceState({}, document.title, window.location.href); + + // Redirect to the login page + router.push("/auth/login"); + }; return ( <>
@@ -20,51 +34,51 @@ export default function Logout() { maxWidth: "510px", ml: "auto", mr: "auto", - textAlign: "center" + textAlign: "center", }} className="bg-black" > - Black logo - White logo - Coffee + - You are Logged Out - - - - Thank you for using Admash admin template + Would you like to sign out? diff --git a/pages/index.js b/pages/index.js index ec9013d..9c2b14d 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,12 +1,87 @@ -import { useRouter } from "next/router"; -import ECommerce from "./ecommerce"; +import React from "react"; +import Grid from "@mui/material/Grid"; +import Link from "next/link"; +import styles from "@/styles/PageTitle.module.css"; +import Features from "@/components/Dashboard/eCommerce/Features"; +import Ratings from "@/components/Dashboard/eCommerce/Ratings"; +import AudienceOverview from "@/components/Dashboard/eCommerce/AudienceOverview"; +import VisitsByDay from "@/components/Dashboard/eCommerce/VisitsByDay"; +import Impressions from "@/components/Dashboard/eCommerce/Impressions"; +import ActivityTimeline from "@/components/Dashboard/eCommerce/ActivityTimeline"; +import RevenuStatus from "@/components/Dashboard/eCommerce/RevenuStatus"; +import SalesByCountries from "@/components/Dashboard/eCommerce/SalesByCountries"; +import NewCustomers from "@/components/Dashboard/eCommerce/NewCustomers"; +import RecentOrders from "@/components/Dashboard/eCommerce/RecentOrders"; +import TeamMembersList from "@/components/Dashboard/eCommerce/TeamMembersList"; +import BestSellingProducts from "@/components/Dashboard/eCommerce/BestSellingProducts"; +import LiveVisitsOnOurSite from "@/components/Dashboard/eCommerce/LiveVisitsOnOurSite"; -export default function Home() { - const router = useRouter(); +function MainPage() { + return ( + <> + {/* Page title */} +
+

eCommerce

+
    +
  • + Dashboard +
  • +
  • eCommerce
  • +
+
+ + + {/* Features */} + + {/* AudienceOverview */} + + + + {/* VisitsByDay */} + + + + {/* Impressions */} + - console.log("Check pathname: " + router.pathname) - - if (router.pathname === "/") { - return ; - } + {/* ActivityTimeline */} + + + + {/* RevenuStatus */} + + + + + + {/* Ratings */} + + {/* LiveVisitsOnOurSite */} + + {/* SalesByLocations */} + + {/* NewCustomers */} + + + + {/* Recent Orders */} + + + + {/* TeamMembersList */} + + + + {/* BestSellingProducts */} + + + + + ); } + +export default MainPage \ No newline at end of file diff --git a/pages/pages/profile.js b/pages/pages/profile.js index cb5a6fd..3979430 100644 --- a/pages/pages/profile.js +++ b/pages/pages/profile.js @@ -9,8 +9,13 @@ import ProfileContent from '@/components/Pages/Profile/ProfileContent'; import ImpressionGoalConversions from "@/components/Dashboard/Analytics/ImpressionGoalConversions"; import Link from 'next/link'; import styles from '@/styles/PageTitle.module.css'; +import { useUserProfile } from 'contexts/userProfileContext'; export default function Profile() { + const { state } = useUserProfile(); + const userProfile = state.userProfile; + + console.log(userProfile) return ( <> {/* Page title */} diff --git a/services/Fetcher.js b/services/Fetcher.js index 6e667cc..e4ff8f0 100644 --- a/services/Fetcher.js +++ b/services/Fetcher.js @@ -3,7 +3,8 @@ import Axios from "axios"; class Fetcher { constructor(url) { // this.url = url; - console.log("first request!!!"); + // console.log("first request!!!"); + // return new Response("Working!!!" + url) } // Endpoints Here diff --git a/styles/globals.css b/styles/globals.css index 98296fb..c7991d2 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -804,6 +804,10 @@ img { position: relative; transition: all 0.5s ease-out; } + +.main-wrapper-content.authBox{ + padding-left: 0; +} .main-wrapper-content.active { padding-left: 0; }