updates and fixes

* seo friendly urls
* custom client serve-static module
* database fixes
* fix recent pages
* other fixes
This commit is contained in:
Philipinho
2024-05-18 03:19:42 +01:00
parent eefe63d1cd
commit 9c7c2f1163
102 changed files with 921 additions and 536 deletions

View File

@ -14,6 +14,8 @@ import { IconDots } from "@tabler/icons-react";
import { Link, useParams } from "react-router-dom";
import classes from "./breadcrumb.module.css";
import { SpaceTreeNode } from "@/features/page/tree/types.ts";
import { buildPageSlug } from "@/features/page/page.utils.ts";
import { usePageQuery } from "@/features/page/queries/page-query.ts";
function getTitle(name: string, icon: string) {
if (icon) {
@ -27,23 +29,17 @@ export default function Breadcrumb() {
const [breadcrumbNodes, setBreadcrumbNodes] = useState<
SpaceTreeNode[] | null
>(null);
const { pageId } = useParams();
const { slugId } = useParams();
const { data: currentPage } = usePageQuery(slugId);
useEffect(() => {
if (treeData.length) {
const breadcrumb = findBreadcrumbPath(treeData, pageId);
if (treeData?.length > 0 && currentPage) {
const breadcrumb = findBreadcrumbPath(treeData, currentPage.id);
if (breadcrumb) {
setBreadcrumbNodes(breadcrumb);
}
}
}, [pageId, treeData]);
useEffect(() => {
if (treeData.length) {
const breadcrumb = findBreadcrumbPath(treeData, pageId);
if (breadcrumb) setBreadcrumbNodes(breadcrumb);
}
}, [pageId, treeData]);
}, [currentPage?.id, treeData]);
const HiddenNodesTooltipContent = () =>
breadcrumbNodes?.slice(1, -2).map((node) => (
@ -51,7 +47,7 @@ export default function Breadcrumb() {
<Button
justify="start"
component={Link}
to={`/p/${node.id}`}
to={buildPageSlug(node.slugId, node.name)}
variant="default"
style={{ border: "none" }}
>
@ -63,16 +59,14 @@ export default function Breadcrumb() {
const getLastNthNode = (n: number) =>
breadcrumbNodes && breadcrumbNodes[breadcrumbNodes.length - n];
// const getTitle = (title: string) => (title?.length > 0 ? title : "untitled");
const getBreadcrumbItems = () => {
if (breadcrumbNodes?.length > 3) {
return [
<Anchor
component={Link}
to={`/p/${breadcrumbNodes[0].id}`}
to={buildPageSlug(breadcrumbNodes[0].slugId, breadcrumbNodes[0].name)}
underline="never"
key={breadcrumbNodes[0].id}
key={breadcrumbNodes[0].slugId}
>
{getTitle(breadcrumbNodes[0].name, breadcrumbNodes[0].icon)}
</Anchor>,
@ -94,17 +88,17 @@ export default function Breadcrumb() {
</Popover>,
<Anchor
component={Link}
to={`/p/${getLastNthNode(2)?.id}`}
to={buildPageSlug(getLastNthNode(2)?.slugId, getLastNthNode(2)?.name)}
underline="never"
key={getLastNthNode(2)?.id}
key={getLastNthNode(2)?.slugId}
>
{getTitle(getLastNthNode(2)?.name, getLastNthNode(2)?.icon)}
</Anchor>,
<Anchor
component={Link}
to={`/p/${getLastNthNode(1)?.id}`}
to={buildPageSlug(getLastNthNode(1)?.slugId, getLastNthNode(1)?.name)}
underline="never"
key={getLastNthNode(1)?.id}
key={getLastNthNode(1)?.slugId}
>
{getTitle(getLastNthNode(1)?.name, getLastNthNode(1)?.icon)}
</Anchor>,
@ -115,7 +109,7 @@ export default function Breadcrumb() {
return breadcrumbNodes.map((node) => (
<Anchor
component={Link}
to={`/p/${node.id}`}
to={buildPageSlug(node.slugId, node.name)}
underline="never"
key={node.id}
>

View File

@ -1,11 +1,15 @@
import { UserProvider } from "@/features/user/user-provider.tsx";
import Shell from "./shell.tsx";
import { Outlet } from "react-router-dom";
import { Helmet } from "react-helmet-async";
export default function DashboardLayout() {
return (
<UserProvider>
<Shell>
<Helmet>
<title>Home</title>
</Helmet>
<Outlet />
</Shell>
</UserProvider>

View File

@ -1,18 +1,19 @@
import { ActionIcon, Menu, Button, Tooltip } from "@mantine/core";
import { ActionIcon, Menu, Tooltip } from "@mantine/core";
import {
IconDots,
IconFileInfo,
IconHistory,
IconLink,
IconLock,
IconShare,
IconTrash,
IconMessage,
} from "@tabler/icons-react";
import React from "react";
import useToggleAside from "@/hooks/use-toggle-aside.tsx";
import { useAtom } from "jotai";
import { historyAtoms } from "@/features/page-history/atoms/history-atoms.ts";
import { useClipboard } from "@mantine/hooks";
import { useParams } from "react-router-dom";
import { usePageQuery } from "@/features/page/queries/page-query.ts";
import { buildPageSlug } from "@/features/page/page.utils.ts";
import { notifications } from "@mantine/notifications";
export default function Header() {
const toggleAside = useToggleAside();
@ -42,6 +43,16 @@ export default function Header() {
function PageActionMenu() {
const [, setHistoryModalOpen] = useAtom(historyAtoms);
const clipboard = useClipboard({ timeout: 500 });
const { slugId } = useParams();
const { data: page, isLoading, isError } = usePageQuery(slugId);
const handleCopyLink = () => {
const pageLink =
window.location.host + buildPageSlug(page.slugId, page.title);
clipboard.copy(pageLink);
notifications.show({ message: "Link copied" });
};
const openHistoryModal = () => {
setHistoryModalOpen(true);
@ -63,9 +74,13 @@ function PageActionMenu() {
</Menu.Target>
<Menu.Dropdown>
<Menu.Item leftSection={<IconLink size={16} stroke={2} />}>
<Menu.Item
leftSection={<IconLink size={16} stroke={2} />}
onClick={handleCopyLink}
>
Copy link
</Menu.Item>
<Menu.Divider />
<Menu.Item
leftSection={<IconHistory size={16} stroke={2} />}
onClick={openHistoryModal}
@ -73,10 +88,12 @@ function PageActionMenu() {
Page history
</Menu.Item>
{/*
<Menu.Divider />
<Menu.Item leftSection={<IconTrash size={16} stroke={2} />}>
Delete
</Menu.Item>
*/}
</Menu.Dropdown>
</Menu>
);

View File

@ -1,11 +1,15 @@
import { UserProvider } from "@/features/user/user-provider.tsx";
import { Outlet } from "react-router-dom";
import SettingsShell from "@/components/layouts/settings/settings-shell.tsx";
import { Helmet } from "react-helmet-async";
export default function SettingsLayout() {
return (
<UserProvider>
<SettingsShell>
<Helmet>
<title>Settings</title>
</Helmet>
<Outlet />
</SettingsShell>
</UserProvider>