mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-09 15:05:35 +00:00
156 lines
3.9 KiB
TypeScript
156 lines
3.9 KiB
TypeScript
import { useRouter } from "next/router";
|
|
import { useCallback, useState } from "react";
|
|
import { useHotkeys } from "react-hotkeys-hook";
|
|
|
|
import useModal from "../hooks/useModal";
|
|
|
|
import Links from "../components/Links/Links";
|
|
import SearchModal from "../components/SearchModal/SearchModal";
|
|
import SideMenu from "../components/SideMenu/SideMenu";
|
|
|
|
import { Category, ItemComplete, Link } from "../types";
|
|
import { prisma } from "../utils/back";
|
|
import { BuildCategory } from "../utils/front";
|
|
|
|
const OPEN_SEARCH_KEY = "s";
|
|
const CLOSE_SEARCH_KEY = "escape";
|
|
|
|
const OPEN_CREATE_LINK_KEY = "l";
|
|
const OPEN_CREATE_CATEGORY_KEY = "c";
|
|
|
|
interface HomeProps {
|
|
categories: Category[];
|
|
favorites: Link[];
|
|
items: ItemComplete[];
|
|
currentCategory: Category | undefined;
|
|
}
|
|
|
|
function Home({ categories, favorites, currentCategory, items }: HomeProps) {
|
|
const router = useRouter();
|
|
const modal = useModal();
|
|
|
|
const [categoryActive, setCategoryActive] = useState<Category | null>(
|
|
currentCategory || categories?.[0]
|
|
);
|
|
|
|
const handleSelectCategory = (category: Category) => {
|
|
setCategoryActive(category);
|
|
const newUrl = `/?categoryId=${category.id}`;
|
|
window.history.replaceState(
|
|
{ ...window.history.state, as: newUrl, url: newUrl },
|
|
"",
|
|
newUrl
|
|
);
|
|
};
|
|
|
|
const openSearchModal = useCallback(
|
|
(event) => {
|
|
event.preventDefault();
|
|
modal.open();
|
|
},
|
|
[modal]
|
|
);
|
|
const closeSearchModal = useCallback(() => modal.close(), [modal]);
|
|
|
|
const gotoCreateLink = useCallback(() => {
|
|
router.push(`/link/create?categoryId=${categoryActive.id}`);
|
|
}, [categoryActive.id, router]);
|
|
|
|
const gotoCreateCategory = useCallback(() => {
|
|
router.push("/category/create");
|
|
}, [router]);
|
|
|
|
useHotkeys(OPEN_SEARCH_KEY, openSearchModal, { enabled: !modal.isShowing });
|
|
useHotkeys(CLOSE_SEARCH_KEY, closeSearchModal, { enabled: modal.isShowing });
|
|
|
|
useHotkeys(OPEN_CREATE_LINK_KEY, gotoCreateLink, {
|
|
enabled: !modal.isShowing,
|
|
});
|
|
useHotkeys(OPEN_CREATE_CATEGORY_KEY, gotoCreateCategory, {
|
|
enabled: !modal.isShowing,
|
|
});
|
|
|
|
return (
|
|
<div className="App">
|
|
<SideMenu
|
|
categories={categories}
|
|
favorites={favorites}
|
|
handleSelectCategory={handleSelectCategory}
|
|
categoryActive={categoryActive}
|
|
/>
|
|
<Links category={categoryActive} />
|
|
{modal.isShowing && (
|
|
<SearchModal
|
|
close={modal.close}
|
|
categories={categories}
|
|
favorites={favorites}
|
|
items={items}
|
|
handleSelectCategory={handleSelectCategory}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export async function getServerSideProps({ query }) {
|
|
const queryCategoryId = (query?.categoryId as string) || "";
|
|
|
|
const categoriesDB = await prisma.category.findMany({
|
|
include: { links: true },
|
|
});
|
|
|
|
const items = [] as ItemComplete[];
|
|
|
|
const favorites = [] as Link[];
|
|
const categories = categoriesDB.map((categoryDB) => {
|
|
const category = BuildCategory(categoryDB);
|
|
|
|
category.links.map((link) => {
|
|
if (link.favorite) {
|
|
favorites.push(link);
|
|
}
|
|
items.push({
|
|
id: link.id,
|
|
name: link.name,
|
|
url: link.url,
|
|
type: "link",
|
|
});
|
|
});
|
|
|
|
items.push({
|
|
id: category.id,
|
|
name: category.name,
|
|
url: `/?categoryId=${category.id}`,
|
|
type: "category",
|
|
});
|
|
|
|
return category;
|
|
});
|
|
|
|
if (categories.length === 0) {
|
|
return {
|
|
redirect: {
|
|
destination: "/category/create",
|
|
},
|
|
};
|
|
}
|
|
|
|
const currentCategory = categories.find(
|
|
(c) => c.id === Number(queryCategoryId)
|
|
);
|
|
|
|
return {
|
|
props: {
|
|
categories: JSON.parse(JSON.stringify(categories)),
|
|
favorites: JSON.parse(JSON.stringify(favorites)),
|
|
items: JSON.parse(JSON.stringify(items)),
|
|
currentCategory: currentCategory
|
|
? JSON.parse(JSON.stringify(currentCategory))
|
|
: null,
|
|
},
|
|
};
|
|
}
|
|
|
|
Home.authRequired = true;
|
|
export default Home;
|