Skip to content

Commit

Permalink
feat: Improved the site structure (rupali-codes#303)
Browse files Browse the repository at this point in the history
* feat: Improved the site structure

* fix: Changed the bg to the same color as the header

* fix: Fixed the header

* fix: Added animations to sidebar and popup
  • Loading branch information
zvolcsey authored Mar 7, 2023
1 parent b8c158c commit 37de498
Show file tree
Hide file tree
Showing 19 changed files with 378 additions and 221 deletions.
10 changes: 10 additions & 0 deletions components/Aside/Aside.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FC } from "react";
import { SideNavbarBody } from "components/SideNavbar/SideNavbarBody";

export const Aside: FC<{}> = () => {
return (
<aside className="fixed top-[76px] left-0 z-[20] hidden h-screen w-[290px] lg:block">
<SideNavbarBody />
</aside>
);
};
6 changes: 3 additions & 3 deletions components/Backdrop/Backdrop.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { FC } from "react";
import { createPortal } from "react-dom";

export const Backdrop: FC<{ onClick: (() => void) | undefined}> = (props) => {
const { onClick } = props;
export const Backdrop: FC<{ onClick: (() => void) | undefined, className?: string | undefined }> = (props) => {
const { onClick, className } = props;

return createPortal(
<div
className={`fixed inset-0 z-50 h-full w-full cursor-pointer bg-black/80 lg:hidden`}
className={`fixed inset-0 z-50 h-full w-full cursor-pointer bg-black/80 ${className}`}
onClick={onClick}
></div>,
document.getElementById('backdrop-root')!
Expand Down
6 changes: 2 additions & 4 deletions components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import Image from "next/image";
import Link from "next/link";
import type { FC } from "react";
import Logo from "../logo";

interface FooterProps {}

export const Footer: FC<FooterProps> = ({}) => {
return (
<div className="w-full flex items-baseline justify-center z-10 gap-1 rounded-lg bg-[#ffffff0a] backdrop-blur-md sm:py-3 py-2 px-1 md:mt-4">
<footer className="z-10 mb-4 flex w-full items-baseline justify-center rounded-lg bg-[#ffffff0a] py-2 backdrop-blur-md sm:py-3">
<p className="md:text-lg text-center text-black dark:text-gray-100">
Open source |{" "}
<Link
Expand All @@ -19,6 +17,6 @@ export const Footer: FC<FooterProps> = ({}) => {
</Link>{" "}
2023 LinksHub
</p>
</div>
</footer>
);
};
37 changes: 37 additions & 0 deletions components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { FC, useContext } from "react";
import Link from "next/link";
import { AiOutlineMenu } from "react-icons/ai";
import Logo from "components/logo";
import { GlobalContext } from "context/GlobalContext";
import { ThemeToggler } from "../ThemeToggler/themeToggler";
import { TopBar } from "../TopBar/TopBar";
import { SocialMediaIconsList } from "components/SocialMedia/SocialMediaIconsList";

export const Header:FC<{}> = () => {
const { toggleNav } = useContext(GlobalContext);

return (
<header className="fixed top-0 left-0 z-30 row-start-1 row-end-2 flex h-[76px] w-screen items-center justify-between">
<div className="bg-base-200 h-full w-fit flex-none px-6 py-4 dark:bg-gray-900 lg:w-[290px]">
<Link href={"/"}>
<Logo className="text-3xl" />
</Link>
</div>
<div className="bg-base-200 relative h-full grow px-8 dark:bg-gray-900 lg:bg-gray-100 lg:dark:bg-[#101623]">
<TopBar className="absolute left-8 hidden h-full md:flex" />
<div className="absolute right-8 flex h-full gap-4">
<SocialMediaIconsList className={"hidden lg:flex"} />
<ThemeToggler />
<button
className="dark:text-gray-300 lg:hidden"
onClick={toggleNav}
>
<AiOutlineMenu
size={24}
/>
</button>
</div>
</div>
</header>
)
}
6 changes: 3 additions & 3 deletions components/LinksContainer/LinkContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { BsBoxArrowUpRight } from "react-icons/bs";
export const LinkContainer = (props) => {
const { name, description, url, getCardId } = props;
return (
<div
<li
onClick={() => getCardId(props)}
className="transition-all ease-in duration-100 w-full cursor-pointer md:w-72 h-64 bg-gray-100 shadow-lg dark:shadow-sm border hover:scale-[1.02] border-dashed border-violet-500 rounded-3xl dark:bg-gray-900 dark:text-gray-300"
className="z-10 h-64 w-[98%] cursor-pointer rounded-3xl border border-dashed border-violet-500 bg-gray-100 shadow-lg transition-all duration-100 ease-in hover:scale-[1.02] dark:bg-gray-900 dark:text-gray-300 dark:shadow-sm md:w-72"
>
<div className="card-body">
<h2
Expand All @@ -33,6 +33,6 @@ export const LinkContainer = (props) => {
</a>
</div>
</div>
</div>
</li>
);
};
102 changes: 23 additions & 79 deletions components/SideNavbar/SideNavbar.tsx
Original file line number Diff line number Diff line change
@@ -1,91 +1,35 @@
import Link from "next/link";
import { Searchbar } from "../Searchbar";
import useSidebarSearch from "hooks/useSidebarSearch";
import { createRef, useContext, useEffect } from "react";
import { AiOutlineClose, AiOutlineMenu } from "react-icons/ai";
import { FC } from "react";
import { useContext } from "react";
import { GlobalContext } from "context/GlobalContext";
import Logo from "../logo";
import classNames from "classnames";
import { useTheme } from "next-themes";
import { SideNavbarCategoryList } from "./SideNavbarCategoryList";
import { Backdrop } from "components/Backdrop/Backdrop";
import { SideNavbarHeader } from "./SideNavbarHeader";
import { SideNavbarBody } from "./SideNavbarBody";
import { createPortal } from "react-dom";
import { SocialMediaIconsList } from "components/SocialMedia/SocialMediaIconsList";
import useDelayUnmount from "hooks/useDelayUnmount";

export const SideNavbar = () => {
const { toggleNav, sidebar, openNav, closeNav } = useContext(GlobalContext);
const { theme } = useTheme();
const menuRef = createRef<HTMLDivElement>();
const menuBtnRef = createRef<HTMLButtonElement>();
export const SideNavbar:FC<{}> = () => {
const { sidebar, closeNav } = useContext(GlobalContext);
const showElement = useDelayUnmount(sidebar, 300);

// closing navbar on click
useEffect(() => {
const handler = (e: MouseEvent): void => {
const target = e.target as HTMLElement;

if (
sidebar &&
!menuRef.current?.contains(target) &&
!menuBtnRef.current?.contains(target)
) {
closeNav && closeNav();
}
};

document.addEventListener("mousedown", handler);

return () => {
document.removeEventListener("mousedown", handler);
};
});

const { setSearch, searchResults } = useSidebarSearch();
if (!showElement) {
return null;
}

return (
<>
{sidebar && <Backdrop onClick={closeNav} />}
<div
className={`lg:w-[290px] fixed top-0 left-0 w-full h-[87px] z-[100] lg:h-full`}
>
<div className="flex bg-gray-100 p-4 pb-0 justify-between dark:bg-gray-900 transition-all ease-in duration-300">
<Link href={"/"}>
<Logo className="text-3xl mb-4" />
</Link>

<button
ref={menuBtnRef}
className="relative h-[24px] w-[24px] lg:hidden dark:text-gray-300"
onClick={toggleNav && toggleNav}
>
<AiOutlineMenu
size={24}
className={`transition-all left-0 top-[5%] duration-[.5s] absolute ${
sidebar ? "z-[-1] opacity-[0]" : "opacity-[1] z-[1]"
}`}
/>
<AiOutlineClose
size={24}
id="hamburger"
className={`absolute left-0 top-[5%] transition-all duration-[1s] ${
sidebar
? "opacity-[1] z-[1]"
: "opacity-[0] rotate-[180deg] z-[-1]"
}`}
/>
</button>
</div>
<Backdrop onClick={closeNav} className="lg:hidden" />
{createPortal(
<div
ref={menuRef}
className={classNames(
`lg:translate-x-0 lg:w-full w-[75%] bg-base-200 transition-all whitespace-nowrap ease-in duration-300 overflow-x-hidden h-screen z-[10] dark:bg-gray-900 dark:text-gray-300`,
sidebar ? "translate-x-[0%] " : "translate-x-[-100%]",
theme === "light" ? "scrollColorLight" : "scrollColorDark"
)}
className={`fixed top-0 left-0 z-[100] h-full w-[75%] transition-all lg:hidden
${sidebar ? 'animate-slide-in' : 'animate-slide-out'}
`}
>
<div className="sticky top-0 left-0 right-0 p-4 w-full z-10 bg-base-200 dark:bg-gray-900 transiton-all duration-300 ease-in">
<Searchbar setSearch={setSearch} />
</div>
<SideNavbarCategoryList items={searchResults} openByDefault={'frontend'} />
</div>
</div>
<SideNavbarHeader />
<SocialMediaIconsList className="bg-gray-100 px-6 py-2 dark:bg-gray-900" />
<SideNavbarBody />
</div>, document.getElementById('overlay-root')!
)}
</>
);
};
26 changes: 26 additions & 0 deletions components/SideNavbar/SideNavbarBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { FC } from "react";
import { Searchbar } from "../Searchbar";
import useSidebarSearch from "hooks/useSidebarSearch";
import classNames from "classnames";
import { useTheme } from "next-themes";
import { SideNavbarCategoryList } from "./SideNavbarCategoryList";

export const SideNavbarBody:FC<{}> = () => {
const { theme } = useTheme();

const { setSearch, searchResults } = useSidebarSearch();

return (
<div
className={classNames(
`bg-base-200 h-full w-full overflow-x-hidden whitespace-nowrap transition-all duration-300 ease-in dark:bg-gray-900 dark:text-gray-300`,
theme === "light" ? "scrollColorLight" : "scrollColorDark"
)}
>
<div className="bg-base-200 transiton-all w-full p-4 duration-300 ease-in dark:bg-gray-900">
<Searchbar setSearch={setSearch} />
</div>
<SideNavbarCategoryList items={searchResults} openByDefault={'frontend'} />
</div>
);
};
29 changes: 29 additions & 0 deletions components/SideNavbar/SideNavbarHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FC } from "react";
import Link from "next/link";
import { useContext } from "react";
import { AiOutlineClose } from "react-icons/ai";
import { GlobalContext } from "context/GlobalContext";
import Logo from "../logo";

export const SideNavbarHeader:FC<{}> = (props) => {
const { toggleNav } = useContext(GlobalContext);

return (
<header>
<div className="flex items-center justify-between bg-gray-100 p-4 dark:bg-gray-900">
<Link href={"/"}>
<Logo className="text-3xl" />
</Link>
<button
className="h-[24px] w-[24px] dark:text-gray-300 lg:hidden"
onClick={toggleNav}
>
<AiOutlineClose
size={24}
id="hamburger"
/>
</button>
</div>
</header>
);
};
57 changes: 57 additions & 0 deletions components/SocialMedia/SocialMediaIconsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { FC } from "react";
import { IconContext } from "react-icons";
import {FaDiscord, FaGithub, FaTwitter} from "react-icons/fa";

export const SocialMediaIconsList:FC<{className?: string}> = (props) => {
const { className } = props;

return (
<ul className={`flex items-center gap-6 ${className}`}>
<li>
<a
title="Link to Discord server (External Link)"
className="dark:text-gray-300"
target="_blank"
rel="noopener noreferrer"
href="https://discord.com/invite/NvK67YnJX5"
>
<IconContext.Provider
value={{ className: "shared-class", size: "24" }}
>
<FaDiscord className="hover:text-violet-500" />
</IconContext.Provider>
</a>
</li>
<li>
<a
title="Link to Github project (External Link)"
className="dark:text-gray-300"
target="_blank"
rel="noopener noreferrer"
href="https://github.com/rupali-codes/LinksHub"
>
<IconContext.Provider
value={{ className: "shared-class", size: "24" }}
>
<FaGithub className="hover:text-violet-500" />
</IconContext.Provider>
</a>
</li>
<li>
<a
title="Link to Twitter page (External Link)"
className="dark:text-gray-300"
target="_blank"
rel="noopener noreferrer"
href="https://twitter.com/the_linkshub"
>
<IconContext.Provider
value={{ className: "shared-class", size: "24" }}
>
<FaTwitter className="hover:text-violet-500" />
</IconContext.Provider>
</a>
</li>
</ul>
);
};
Loading

0 comments on commit 37de498

Please sign in to comment.