Skip to content

Commit

Permalink
persist store
Browse files Browse the repository at this point in the history
  • Loading branch information
sinamics committed Dec 30, 2024
1 parent 3ae0085 commit 6f99eb0
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 120 deletions.
14 changes: 6 additions & 8 deletions src/components/layouts/authenticatedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,29 @@
// before zustand is hydrated.

import { ReactNode } from "react";
import dynamic from "next/dynamic";
import Footer from "./footer";
import Header from "./header";
import Modal from "../shared/modal";
import { useSidebarStore } from "~/store/sidebarStore";
import useStore from "~/store/useStore";

// Dynamically import Sidebar to avoid SSR mismatch.
const Sidebar = dynamic(() => import("./sidebar"), { ssr: false });
import Sidebar from "./sidebar";

export default function MainLayout({ children }: { children: ReactNode }) {
const hydrated = useStore(useSidebarStore, (state) => state.hydrated);
const open = useStore(useSidebarStore, (state) => state.open);
const store = useStore(useSidebarStore, (state) => state);

// While rehydrating from localStorage, render nothing
// so the server DOM matches the client DOM.
if (!hydrated) return null;
// if (!store?.hydrated) return null;

return (
<div className="outer-container">
<Modal />
<Header />
<div className="flex">
<aside
className={`duration-150 transition-all ${open ? "w-64" : "w-0 opacity-0"}`}
className={`duration-150 transition-all ${
store?.open ? "w-64" : "w-0 opacity-0"
}`}
>
<Sidebar />
</aside>
Expand Down
175 changes: 87 additions & 88 deletions src/components/layouts/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { forwardRef, useEffect, useState } from "react";
import { api } from "~/utils/api";
import { useSession } from "next-auth/react";
import { useSidebarStore } from "~/store/sidebarStore";
import useStore from "~/store/useStore";

const Themes = [
"light",
Expand All @@ -21,99 +22,97 @@ const Themes = [
"cyberpunk",
];

const Header = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
(props, ref) => {
const { data: session } = useSession();
const { theme, setTheme } = useTheme();
const { toggle, open } = useSidebarStore();
const [mounted, setMounted] = useState(false);
const { data: globalOptions } = api.settings.getAllOptions.useQuery();
const Header = (props) => {
const { data: session } = useSession();
const { theme, setTheme } = useTheme();

useEffect(() => {
setMounted(true);
}, []);
const store = useStore(useSidebarStore, (state) => state);

return (
<header
ref={ref}
className="header bg-base-200 px-4 py-1 shadow-md shadow-base"
{...props}
>
<div className="header-content flex flex-row items-center">
<div className="hidden md:inline-flex">
<Link href="/network" className="inline-flex flex-row items-center gap-2">
<img
style={{ width: 25, height: 25 }}
alt="ztnet logo"
title="ztnet logo"
src={ZtnetLogo.src}
/>
<span className="ml-1 text-2xl font-bold uppercase leading-10 text-accent zt-color">
{globalOptions?.siteName || "ZTNET"}
</span>
</Link>
</div>
<div className="md:pl-12 flex items-center pt-1">
<label className={`${mounted && open ? "swap-active" : ""} swap swap-rotate`}>
<div className="swap-off">
<svg
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 512 512"
onClick={() => toggle()}
>
<path d="M64,384H448V341.33H64Zm0-106.67H448V234.67H64ZM64,128v42.67H448V128Z" />
</svg>
</div>
<div className="swap-on">
<svg
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 512 512"
onClick={() => toggle()}
>
<polygon points="400 145.49 366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49" />
</svg>
</div>
</label>
</div>
<div className="ml-auto flex">
{/* <a href="#" className="flex flex-row items-center"> */}
<div className="dropdown dropdown-end">
<label tabIndex={0} className="btn btn-primary btn-sm m-1">
{theme?.toUpperCase()}
</label>
<ul
tabIndex={0}
className="menu dropdown-content rounded-box z-30 w-52 bg-base-300 p-2 shadow"
const [mounted, setMounted] = useState(false);
const { data: globalOptions } = api.settings.getAllOptions.useQuery();

useEffect(() => {
setMounted(true);
}, []);

return (
<header className="header bg-base-200 px-4 py-1 shadow-md shadow-base" {...props}>
<div className="header-content flex flex-row items-center">
<div className="hidden md:inline-flex">
<Link href="/network" className="inline-flex flex-row items-center gap-2">
<img
style={{ width: 25, height: 25 }}
alt="ztnet logo"
title="ztnet logo"
src={ZtnetLogo.src}
/>
<span className="ml-1 text-2xl font-bold uppercase leading-10 text-accent zt-color">
{globalOptions?.siteName || "ZTNET"}
</span>
</Link>
</div>
<div className="md:pl-12 flex items-center pt-1">
<label
className={`${mounted && store?.open ? "swap-active" : ""} swap swap-rotate`}
>
<div className="swap-off">
<svg
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 512 512"
onClick={() => store?.toggle()}
>
{Themes.map((theme) => {
return (
<li key={theme} onClick={() => setTheme(theme)}>
<a>{theme.toUpperCase()}</a>
</li>
);
})}
</ul>
<path d="M64,384H448V341.33H64Zm0-106.67H448V234.67H64ZM64,128v42.67H448V128Z" />
</svg>
</div>
<span className="ml-2 flex flex-col justify-center">
<span className="truncate font-semibold leading-none tracking-wide">
{/* {session.data?.user?.name} */}
</span>
<span className="mt-1 w-20 truncate text-xs leading-none text-gray-500">
{/* {session.data?.user?.role} */}
</span>
</span>
{/* </a> */}
<div className="swap-on">
<svg
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 512 512"
onClick={() => store?.toggle()}
>
<polygon points="400 145.49 366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49" />
</svg>
</div>
</label>
</div>
<div className="ml-auto flex">
{/* <a href="#" className="flex flex-row items-center"> */}
<div className="dropdown dropdown-end">
<label tabIndex={0} className="btn btn-primary btn-sm m-1">
{theme?.toUpperCase()}
</label>
<ul
tabIndex={0}
className="menu dropdown-content rounded-box z-30 w-52 bg-base-300 p-2 shadow"
>
{Themes.map((theme) => {
return (
<li key={theme} onClick={() => setTheme(theme)}>
<a>{theme.toUpperCase()}</a>
</li>
);
})}
</ul>
</div>
<span className="ml-2 flex flex-col justify-center">
<span className="truncate font-semibold leading-none tracking-wide">
{/* {session.data?.user?.name} */}
</span>
<span className="mt-1 w-20 truncate text-xs leading-none text-gray-500">
{/* {session.data?.user?.role} */}
</span>
</span>
{/* </a> */}
</div>
</header>
);
},
);
</div>
</header>
);
};

export default Header;
12 changes: 6 additions & 6 deletions src/components/layouts/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const useIsBelowMd = () => {
};

const Sidebar = (): JSX.Element => {
const open = useStore(useSidebarStore, (state) => state.open);
const setOpenState = useStore(useSidebarStore, (state) => state.setOpenState);
const store = useStore(useSidebarStore, (state) => state);
// const setOpenState = useStore(useSidebarStore, (state) => state.setOpenState);

const { setBulkNewMessages } = useSocketStore();
const { hasNewMessages } = useSocketStore();
Expand Down Expand Up @@ -59,11 +59,11 @@ const Sidebar = (): JSX.Element => {

useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (isBelowMd && open) {
if (isBelowMd && store?.open) {
if (sidebarRef.current && !sidebarRef.current.contains(event.target as Node)) {
// called after the click event on hamburger menu to close sidebar
setTimeout(() => {
setOpenState(false);
store?.setOpenState?.(false);
}, 100);
}
}
Expand All @@ -73,13 +73,13 @@ const Sidebar = (): JSX.Element => {
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isBelowMd, open, setOpenState]);
}, [isBelowMd, store?.open, store?.setOpenState]);

return (
<aside
ref={sidebarRef}
className={`overflow-y-auto fixed z-10 h-full bg-base-200 transition-transform duration-150 ease-in md:relative md:shadow
${open ? "w-64" : "w-0"}`}
${store?.open ? "w-64" : "w-0"}`}
>
<div className="sidebar-content px-4 py-3">
<ul className="flex w-full flex-col">
Expand Down
13 changes: 0 additions & 13 deletions src/components/layouts/sidebarStateWrapper.tsx

This file was deleted.

11 changes: 6 additions & 5 deletions src/hooks/useHandleResize.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { useEffect } from "react";
import { useSidebarStore } from "~/utils/store";
import { useSidebarStore } from "~/store/sidebarStore";
import useStore from "~/store/useStore";

// Create a custom hook
export const useHandleResize = () => {
const { setOpenState } = useSidebarStore();

const setOpenState = useStore(useSidebarStore, (state) => state.setOpenState);
console.log(setOpenState);
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
const handleResize = () => {
if (window.innerWidth >= 768) return setOpenState(true);
if (window.innerWidth >= 768) return setOpenState?.(true);

setOpenState(false);
setOpenState?.(false);
};

// Initial check
Expand Down

0 comments on commit 6f99eb0

Please sign in to comment.