Skip to content

Commit

Permalink
adding header
Browse files Browse the repository at this point in the history
  • Loading branch information
IslemMedjahdi committed Dec 26, 2022
1 parent ce46511 commit 4e65077
Show file tree
Hide file tree
Showing 15 changed files with 234 additions and 10 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@headlessui/react": "^1.7.7",
"@next/font": "13.1.0",
"@types/node": "18.11.17",
"@types/react": "18.0.26",
Expand Down
12 changes: 11 additions & 1 deletion src/components/auth/AuthIndex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import useGoogleAuth from "../../hooks/useGoogleAuth";
const AuthIndex = () => {
const { handleGoogle, loading } = useGoogleAuth();

const origin =
typeof window !== "undefined" && window.location.origin
? window.location.origin.split("//")[1]
: "";

useEffect(() => {
const google = (window as any).google;
if (google) {
Expand All @@ -22,7 +27,7 @@ const AuthIndex = () => {
});
google.accounts.id.prompt();
}
}, [handleGoogle]);
}, []);

return (
<div className="grid h-screen grid-cols-1 text-gray-900 md:grid-cols-2">
Expand All @@ -46,6 +51,11 @@ const AuthIndex = () => {
<div id="authDiv" data-text="continue_with"></div>
)}
</div>
<div className="flex justify-center">
<p className="text-sm font-medium">
Copyright ©{new Date().getFullYear()} {origin} All rights reserved
</p>
</div>
</div>
<div
className="hidden h-full w-full bg-cover bg-no-repeat md:block"
Expand Down
28 changes: 28 additions & 0 deletions src/components/layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import useAuth from "../../hooks/useAuth";
import Footer from "./footer/Footer";
import Header from "./header/Header";

type Props = {
withFooter?: boolean;
withHeader?: boolean;
children: React.ReactNode;
};

const Layout: React.FC<Props> = ({
children,
withFooter = false,
withHeader = true,
}) => {
const { currentUser } = useAuth();

return (
<div>
{currentUser && withHeader && <Header />}
<div className="min-h-screen bg-gray-50">{children}</div>
{currentUser && withFooter && <Footer />}
</div>
);
};

export default Layout;
5 changes: 5 additions & 0 deletions src/components/layout/footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Footer = () => {
return <div>Footer</div>;
};

export default Footer;
41 changes: 41 additions & 0 deletions src/components/layout/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Image from "next/image";
import Link from "next/link";
import { ICONS } from "../../../constants/icons";
import { IMAGES } from "../../../constants/images";
import { INFO } from "../../../constants/info";
import { NAV } from "../../../constants/nav";
import { ROUTES } from "../../../constants/routes";
import ProfileMenu from "./ProfileMenu";

const Header = () => {
return (
<header className="flex items-center justify-between gap-x-4 border-b py-4 px-4">
<div className="flex items-center gap-x-4">
<button className="p-1 hover:bg-gray-50">
<ICONS.MENU className="text-2xl" />
</button>
<Link
href={ROUTES.HOME.path}
className="flex cursor-pointer flex-wrap items-baseline gap-2"
>
<Image src={IMAGES.Logo} alt="logo" width={50} height={50} />
<h1 className="hidden whitespace-nowrap font-serif text-xl font-bold text-white md:flex md:text-gray-900">
{INFO.Title}
</h1>
</Link>
</div>
<div className="flex items-center gap-x-4">
<nav className="hidden items-center gap-x-4 md:flex ">
{NAV.map((item) => (
<Link className="font-medium" href={item.path}>
{item.name}
</Link>
))}
</nav>
<ProfileMenu />
</div>
</header>
);
};

export default Header;
83 changes: 83 additions & 0 deletions src/components/layout/header/ProfileMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Menu, Transition } from "@headlessui/react";
import Link from "next/link";
import { Fragment } from "react";
import { MENU_NAV } from "../../../constants/menuNav";
import { NAV } from "../../../constants/nav";
import { ROUTES } from "../../../constants/routes";
import useAuth from "../../../hooks/useAuth";

const ProfileMenu = () => {
const { currentUser, signOut } = useAuth();

if (!currentUser) {
return <></>;
}
const ProfileImage = () => (
<div className="rounded-full bg-blue-primary p-2 font-medium text-white">
{currentUser.firstName[0]} {currentUser.lastName[0]}
</div>
);

return (
<div className="relative">
<Menu as="div" className="relative inline-block">
<Menu.Button className="cursor-pointer">
<ProfileImage />
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 mt-6 w-56 origin-top-right divide-y divide-gray-100 rounded bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<Menu.Item>
<Link
href={ROUTES.HOME.path}
className="flex flex-wrap items-center gap-x-2 px-3 py-2 hover:bg-gray-50 "
>
<ProfileImage />
<p>
{currentUser.firstName} {currentUser.lastName}
</p>
</Link>
</Menu.Item>
{MENU_NAV.map((item) => (
<Menu.Item>
<Link
className="flex flex-wrap items-center gap-x-2 px-3 py-4 hover:bg-gray-50"
href={item.path}
>
{item.name}
</Link>
</Menu.Item>
))}
{NAV.map((item) => (
<Menu.Item>
<Link
className="flex flex-wrap items-center gap-x-2 px-2 py-4 hover:bg-gray-50 md:hidden "
href={item.path}
>
{item.name}
</Link>
</Menu.Item>
))}
<Menu.Item>
<div
onClick={signOut}
className="flex cursor-pointer flex-wrap items-center gap-x-2 px-2 py-4 hover:bg-gray-50"
>
<p>Se déconnecter</p>
</div>
</Menu.Item>
</Menu.Items>
</Transition>
</Menu>
</div>
);
};

export default ProfileMenu;
6 changes: 5 additions & 1 deletion src/constants/icons.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export const ICONS = {};
import { FiMenu } from "react-icons/fi";

export const ICONS = {
MENU: FiMenu,
};
3 changes: 3 additions & 0 deletions src/constants/menuNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ROUTES } from "./routes";

export const MENU_NAV = [ROUTES.MESSAGES];
3 changes: 3 additions & 0 deletions src/constants/nav.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ROUTES } from "./routes";

export const NAV = [ROUTES.POSTED_ANNOUNCEMENTS, ROUTES.FAVORITE_ANNOUNCEMENTS];
22 changes: 21 additions & 1 deletion src/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,33 @@ import { ROLES } from "./roles";

export const ROUTES = {
AUTH: {
name: "auth",
path: "/auth",
pathname: "/auth",
allowedRoles: [] as ROLES[],
},
HOME: {
name: "Acceuille",
path: "/",
pathname: "/",
allowedRoles: [ROLES.ADMIN, ROLES.USER] as ROLES[],
allowedRoles: [ROLES.ADMIN, ROLES.USER],
},
POSTED_ANNOUNCEMENTS: {
name: "Annonces déposé",
path: "/posted-announcements",
pathname: "/posted-announcements",
allowedRoles: [ROLES.USER],
},
FAVORITE_ANNOUNCEMENTS: {
name: "Annonces préférées",
path: "/favorite-announcements",
pathname: "/favorite-announcements",
allowedRoles: [ROLES.USER],
},
MESSAGES: {
name: "Mes messages",
path: "/messages",
pathname: "/messages",
allowedRoles: [ROLES.USER],
},
};
19 changes: 15 additions & 4 deletions src/context/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { Auth } from "../typings/user";
const tokenService = TokenService.getInstance();
const userService = UserService.getInstance();

export const AuthContext = createContext<{ updateUser?: () => Promise<void> }>(
{}
);
export const AuthContext = createContext<{
updateUser?: () => Promise<void>;
currentUser: Auth.User | null | undefined;
signOut: () => void;
}>({ currentUser: undefined, signOut: () => {} });

const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
children,
Expand Down Expand Up @@ -55,6 +57,12 @@ const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
}
};

const signOut = () => {
userService.removeUser();
tokenService.removeAccessToken();
setCurrentUser(null);
};

useEffect(() => {
handleAuth();
}, []);
Expand Down Expand Up @@ -86,7 +94,10 @@ const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
}
}, [router.pathname, currentUser]);

const contextValue = useMemo(() => ({ updateUser }), [updateUser]);
const contextValue = useMemo(
() => ({ updateUser, currentUser, signOut }),
[updateUser, currentUser, signOut]
);

if (
pageLoading ||
Expand Down
5 changes: 4 additions & 1 deletion src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NextSeo } from "next-seo";
import type { AppProps } from "next/app";
import Layout from "../components/layout/Layout";
import { INFO } from "../constants/info";
import AuthProvider from "../context/AuthContext";
import "../styles/globals.css";
Expand All @@ -11,7 +12,9 @@ export default function App({ Component, pageProps }: AppProps) {
titleTemplate={`${INFO.Title} | %s`}
description={INFO.Description}
/>
<Component {...pageProps} />
<Layout>
<Component {...pageProps} />
</Layout>
</AuthProvider>
);
}
3 changes: 2 additions & 1 deletion src/pages/auth.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { NextPage } from "next";
import { NextSeo } from "next-seo";

import AuthIndex from "../components/auth/AuthIndex";

const Auth = () => {
const Auth: NextPage = () => {
return (
<>
<NextSeo title="Auth" />
Expand Down
4 changes: 4 additions & 0 deletions src/services/token.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ class TokenService {
updateAccessToken(token: string) {
localStorage.setItem("@token", token);
}

removeAccessToken() {
localStorage.removeItem("@token");
}
}

export default TokenService;
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"

"@headlessui/react@^1.7.7":
version "1.7.7"
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.7.tgz#d6f8708d8943ae8ebb1a6929108234e4515ac7e8"
integrity sha512-BqDOd/tB9u2tA0T3Z0fn18ktw+KbVwMnkxxsGPIH2hzssrQhKB5n/6StZOyvLYP/FsYtvuXfi9I0YowKPv2c1w==
dependencies:
client-only "^0.0.1"

"@humanwhocodes/config-array@^0.11.8":
version "0.11.8"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9"
Expand Down Expand Up @@ -710,7 +717,7 @@ chokidar@^3.5.3:
optionalDependencies:
fsevents "~2.3.2"

[email protected]:
[email protected], client-only@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
Expand Down

0 comments on commit 4e65077

Please sign in to comment.