Skip to content

Commit

Permalink
feat: add my bookmarks page
Browse files Browse the repository at this point in the history
  • Loading branch information
sina-saeedi committed Nov 12, 2024
1 parent b932e80 commit 8a8bf28
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 3 deletions.
41 changes: 38 additions & 3 deletions frontend/src/app/(dashboard)/dashboard/my/bookmarks/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
import {Metadata} from "next";
import {Suspense} from "react";
import {Box, Stack} from "@mantine/core";
import {DashboardBreadcrumbs} from "@/features/dashboard/components/breadcrumbs";
import {
MyBookmarksTable,
MyBookmarksTableSkeleton,
} from "@/features/dashboard/components/my-bookmarks";

const title = "بوکمارک های من";

export const metadata: Metadata = {
title: "بوکمارک های من",
title: title,
};

type Props = {
searchParams: {
page?: string;
};
};

function MyBookmarksPage() {
return <div>بوکمارک های من</div>;
function MyBookmarksPage({searchParams}: Props) {
const page = Number(searchParams.page) || 1;

return (
<Stack>
<DashboardBreadcrumbs
crumbs={[
{
label: title,
},
]}
/>
<Box>
<Suspense
key={JSON.stringify(searchParams)}
fallback={<MyBookmarksTableSkeleton />}
>
<MyBookmarksTable page={page} />
</Suspense>
</Box>
</Stack>
);
}

export default MyBookmarksPage;
16 changes: 16 additions & 0 deletions frontend/src/dal/bookmarks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import {AxiosRequestConfig} from "axios";
import {apiClient} from ".";

export async function fetchUserBookmarks(config?: AxiosRequestConfig) {
const response = await apiClient.get("dashboard/my/bookmarks", config);
return response.data;
}

export async function removeUserBookmark(id: string) {
const response = await apiClient.delete("dashboard/my/bookmarks", {
data: {
object_type: "article",
object_uuid: id,
},
});
return response.data;
}

export async function checkBookmarkStatus(
uuid?: string,
): Promise<boolean | undefined> {
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/features/dashboard/actions/remove-bookmark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use server";
import {revalidatePath} from "next/cache";
import {APP_PATHS} from "@/lib/app-paths";
import {removeUserBookmark} from "@/dal";

export async function removeBookmarkAction(formData: FormData) {
const fileId = formData.get("id")?.toString();
if (fileId === undefined) {
return;
}
await removeUserBookmark(fileId);
revalidatePath(APP_PATHS.dashboard.files);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"use client";
import {useState} from "react";
import {
Tooltip,
Modal,
ActionIcon,
Button,
Group,
rem,
Text,
} from "@mantine/core";
import {FormButton} from "@/components/form-button";
import {IconTrash} from "@tabler/icons-react";
import {removeBookmarkAction} from "../../actions/remove-bookmark";

type Props = {
bookmarkID: string;
title?: string;
};

export function MyBookmarkDeleteButton({title, bookmarkID}: Props) {
const [isConfirmOpen, setIsConfirmOpen] = useState(false);

const handleSubmit = async () => {
const fd = new FormData();
fd.set("id", bookmarkID);
await removeBookmarkAction(fd);
setIsConfirmOpen(false);
};

return (
<>
<Tooltip label="حذف کردن کامنت" withArrow>
<ActionIcon
variant="light"
size="lg"
color="red"
aria-label="حذف کردن کامنت"
onClick={() => {
setIsConfirmOpen(true);
}}
>
<IconTrash style={{width: rem(20)}} stroke={1.5} />
</ActionIcon>
</Tooltip>
<Modal
title="تایید عملیات"
opened={isConfirmOpen}
size="md"
centered
onClose={() => {
setIsConfirmOpen(false);
}}
>
<Text>از حذف {`"${title}"`} مطمئن هستید؟</Text>
<Group justify="flex-end" mt={"md"}>
<Button
color="gray"
onClick={() => {
setIsConfirmOpen(false);
}}
>
لفو کردن
</Button>
<form action={handleSubmit}>
<FormButton color="red">حذف کردن</FormButton>
</form>
</Group>
</Modal>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {TABLE_HEADERS} from "./bookmarks-table";
import {TableSkeleton} from "../table-skeleton";

export function MyBookmarksTableSkeleton() {
return <TableSkeleton headers={TABLE_HEADERS} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Link from "next/link";
import {
Table,
TableTr,
TableTd,
TableTh,
TableThead,
TableTbody,
ActionIcon,
ActionIconGroup,
Tooltip,
Group,
rem,
} from "@mantine/core";
import {Pagination} from "../pagination";
import {MyBookmarkDeleteButton} from "./bookmark-delete-button";
import {IconEye} from "@tabler/icons-react";
import {fetchUserBookmarks} from "@/dal/bookmarks";
import {dateFromNow} from "@/lib/date-and-time";
import {APP_PATHS} from "@/lib/app-paths";

export const TABLE_HEADERS = ["#", "عنوان", "تاریخ ثبت", "عملیات"];

type Props = {
page: number | string;
};

export async function MyBookmarksTable({page}: Props) {
const bookmarksResponse = await fetchUserBookmarks({
params: {
page: page,
},
});
const bookmarks = bookmarksResponse.items;
const {total_pages, current_page} = bookmarksResponse.pagination;

return (
<>
<Table verticalSpacing={"sm"} striped withRowBorders>
<TableThead>
<TableTr>
{TABLE_HEADERS.map((h) => {
return <TableTh key={h}>{h}</TableTh>;
})}
</TableTr>
</TableThead>
<TableTbody>
{bookmarks.length === 0 && (
<TableTr>
<TableTd colSpan={TABLE_HEADERS.length} ta={"center"}>
هنوز کامنتی را ثبت نکرده اید
</TableTd>
</TableTr>
)}
{bookmarks.map((bookmark: any, index: number) => {
return (
<TableTr key={bookmark.object_uuid}>
<TableTd>{index + 1}</TableTd>
<TableTd>{bookmark.title}</TableTd>
<TableTd>{dateFromNow(bookmark.created_at)}</TableTd>
<TableTd>
<ActionIconGroup>
<Tooltip label={"بازدید کردن کامنت"} withArrow>
<ActionIcon
variant="light"
size="lg"
color="blue"
aria-label="بازدید کردن کامنت"
component={Link}
href={`${APP_PATHS.articles.detail(bookmark.object_uuid)}`}
>
<IconEye style={{width: rem(20)}} stroke={1.5} />
</ActionIcon>
</Tooltip>
<MyBookmarkDeleteButton
title={bookmark.title}
bookmarkID={bookmark.object_uuid}
/>
</ActionIconGroup>
</TableTd>
</TableTr>
);
})}
</TableTbody>
</Table>
{bookmarks.length >= 1 && (
<Group mt="md" mb={"lg"} justify="flex-end">
<Pagination total={total_pages} current={current_page} />
</Group>
)}
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {MyBookmarksTable} from "./bookmarks-table";
export {MyBookmarksTableSkeleton} from "./bookmarks-table-skeleton";

0 comments on commit 8a8bf28

Please sign in to comment.