Skip to content

Commit

Permalink
refactor(client): move aside menu component to server side gen and fi…
Browse files Browse the repository at this point in the history
…x sync with current entry list when deleting or creating new enttries
  • Loading branch information
huilensolis committed Sep 6, 2024
1 parent 840c688 commit af94722
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export function EntryTitle({
router.refresh();
}

if (defaultValue === debouncedTitle) return;

const ctrl = new AbortController();

// eslint-disable-next-line @typescript-eslint/no-floating-promises
Expand Down
Original file line number Diff line number Diff line change
@@ -1,98 +1,29 @@
"use client";

import { Hr } from "@/components/ui/hr";
import { AsideNavLinks } from "./components/navlinks";
import { ProfileCard } from "./components/profile-card";
import { EntrySearchModalTrigger } from "../entry-search-modal/search-entry-modal-trigger";
import { Command, Menu, X } from "lucide-react";
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerTrigger,
} from "../drawer";
import { Button } from "@/components/ui/button";
import { useAsideNavStore } from "./store";
import { useEffect, useState } from "react";
import { Command } from "lucide-react";
import { NewEntryBtn } from "./components/new-entry-btn";
import { EntryList } from "./components/entry-list";

export function AsideNav() {
const [isDrawerOpen, setIsDrawerOpen] = useState<boolean>(false);

const canDrawerOpen = useAsideNavStore((state) => state.canDrawerOpen);
const closeDrawer = useAsideNavStore((state) => state.closeDrawer);
const openDrawer = useAsideNavStore((state) => state.openDrawer);

function handleDrawerOpenChange(open: boolean) {
setIsDrawerOpen(open);
}

function handleFocusOnDrawerBackground() {
closeDrawer();

setTimeout(() => {
openDrawer();
}, 500);
}
import { MobileAsideView } from "./views/mobile";
import { DesktopAsideView } from "./views/desktop";

useEffect(() => {
if (!isDrawerOpen) return;

document.getElementsByTagName("body")[0].style.overflowY = "hidden";

return () => {
document.getElementsByTagName("body")[0].style.overflowY = "auto";
};

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isDrawerOpen]);
const VIEWS = {
mobile: MobileAsideView,
desktop: DesktopAsideView,
};

export function AsideNav() {
return (
<div className="bg-zinc-100">
<div className="hidden lg:flex">
<aside className="max-w-80 w-full h-full min-h-screen p-2 flex gap-2 flex-col items-center border-r border-neutral-300">
<VIEWS.desktop>
<MenuItems />
<Hr orientation="horizontal" className="my-1" />
<EntryList />
</aside>
</VIEWS.desktop>
</div>
<div className="lg:hidden bg-zinc-100 border-b border-gray-200 p-2">
{isDrawerOpen && (
<div
onClick={(e) => {
e.stopPropagation();

handleFocusOnDrawerBackground();
}}
className="h-screen w-full bg-black/40 absolute top-0 left-0 z-40"
></div>
)}
<Drawer
open={canDrawerOpen ? undefined : false}
modal={false}
onOpenChange={handleDrawerOpenChange}
>
<DrawerTrigger asChild>
<Button variant="ghost" className="hover:bg-zinc-200 px-1.5">
<Menu className="h-8 w-8" />
</Button>
</DrawerTrigger>
<DrawerContent hidden={!canDrawerOpen}>
<DrawerHeader className="flex items-center justify-start">
<DrawerClose asChild>
<Button variant="ghost" className="px-1.5">
<X className="h-8 w-8" />
</Button>
</DrawerClose>
</DrawerHeader>
<DrawerFooter>
<MenuItems />
</DrawerFooter>
</DrawerContent>
</Drawer>
<VIEWS.mobile>
<MenuItems />
</VIEWS.mobile>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,69 +1,33 @@
"use client";

import { EntryService } from "@/models/api/entry";
import { ClientRoutingService } from "@/models/routing/client";
import type { Entry } from "@/types/entry";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useState } from "react";

export function EntryList() {
const [entryList, setEntryList] = useState<Entry[]>([]);

useEffect(() => {
async function fetchEntryList(signal: AbortSignal) {
const { entryList, error } = await EntryService.getUserEntyList({
signal,
});

if (error || !entryList || entryList.length === 0) return;
import { EntryItem } from "./entry-item.component";
import { getCookie } from "@/utils/getCookies";

setEntryList(entryList);
}
export async function EntryList() {
const { cookie } = getCookie();

const ctrl = new AbortController();
if (!cookie) return <p>something went wrong</p>;

// eslint-disable-next-line @typescript-eslint/no-floating-promises
fetchEntryList(ctrl.signal);

return () => {
ctrl.abort();
};
}, []);
const { entryList, error } = await EntryService.getUserEntyList({ cookie });
console.log(entryList);

return (
<ul className="w-full flex flex-col gap-2">
{entryList.length > 0 &&
entryList.map((entry) => (
<li key={entry.id}>
<EntryItem entry={entry} />
</li>
))}
{!error &&
entryList &&
entryList.length > 0 &&
entryList
.sort((entry, nextEntry) =>
new Date(entry.updated_at).getTime() >
new Date(nextEntry.updated_at).getTime()
? -1
: 1,
)
.map((entry) => (
<li key={entry.id}>
<EntryItem entry={entry} />
</li>
))}
{error && <p>something went wrong</p>}
</ul>
);
}

function EntryItem({ entry }: { entry: Entry }) {
const [isActive, setIsActive] = useState<boolean>(false);

const pathName = usePathname();

useEffect(() => {
if (pathName === ClientRoutingService.app.entries.readById(entry.id)) {
setIsActive(true);
return;
}

setIsActive(false);
}, [pathName, entry.id]);

return (
<Link href={ClientRoutingService.app.entries.readById(entry.id)}>
<article
className={`p-2 hover:bg-zinc-200 ${isActive ? "bg-zinc-200" : ""} rounded-sm transition-all duration-150`}
>
<span className="font-semibold">{entry.title}</span>
</article>
</Link>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function NewEntryBtn() {

const url = ClientRoutingService.app.entries.readById(newEntryId);

router.refresh();
router.push(url);

setLoading(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export function DeleteEntryModalTrigger({

if (pathName === ClientRoutingService.app.entries.readById(entryId)) {
router.push(ClientRoutingService.app.home);
router.refresh();
return;
}

Expand Down
9 changes: 8 additions & 1 deletion apps/client/src/models/api/entry/entry.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,20 @@ export class EntryService extends ApiService {

public static async getUserEntyList({
signal,
cookie,
}: {
signal?: AbortSignal;
cookie?: string;
}): Promise<{ entryList: Entry[] | null; error: string | null }> {
try {
const { status, data } = await axios.get<Entry[]>(
ApiRoutingService.routing.entry.getEntryList,
{ ...(signal && { signal }) },
{
...(signal && { signal }),
headers: {
...(cookie && { Cookie: cookie }),
},
},
);

if (status !== 200)
Expand Down

0 comments on commit af94722

Please sign in to comment.