From b6293d118e7545b81e216073e66cd54c5b1a0b00 Mon Sep 17 00:00:00 2001 From: Daksh Pareek Date: Sun, 12 Jan 2025 21:53:34 +0530 Subject: feat: Add Bookmark Sorting Feature (#812) * feat: add bookmark sorting by creation date - Add sort order toggle in GlobalActions component - Implement ascending/descending sort functionality - Update translations for sorting feature in all languages - Add sort order icons and dropdown menu - Maintain sort preference in URL params * feat: add bookmark sorting by creation date - Add sort order toggle in GlobalActions component - Implement ascending/descending sort functionality - Update translations for sorting feature in all languages - Add sort order icons and dropdown menu - Maintain sort preference in URL params during session Note: Sort order resets to default on page refresh, server-side persistence can be implemented in future enhancement * feat: Add global sort by date feature with shared sort order state - Implement global sort order functionality using a shared Zustand store (`useSortOrder` hook). - Update `getBookmarks` and `searchBookmarks` endpoints to accept a `sortOrder` parameter. - Refactor code to import `ZSortOrder` from shared types (`bookmarks.ts`), ensuring consistency across the codebase. - Update components (`UpdatableBookmarksGrid`, `bookmark-search`) to use the shared `useSortOrder` hook. - Remove unused `zSortBy` definition from `packages/shared/types/bookmarks.ts` to avoid confusion. - Ensure consistent naming conventions by prefixing Zod inferred types with `Z`. - Clean up code and address previous PR feedback comments. * tiny fixes and fixing TS errors --------- Co-authored-by: Mohamed Bassem --- apps/web/components/dashboard/GlobalActions.tsx | 2 + apps/web/components/dashboard/SortOrderToggle.tsx | 56 ++++++++++++++++++++++ .../components/dashboard/bookmarks/Bookmarks.tsx | 2 +- .../dashboard/bookmarks/UpdatableBookmarksGrid.tsx | 19 ++++++-- 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 apps/web/components/dashboard/SortOrderToggle.tsx (limited to 'apps/web/components') diff --git a/apps/web/components/dashboard/GlobalActions.tsx b/apps/web/components/dashboard/GlobalActions.tsx index 9c05dddf..ecbb70bf 100644 --- a/apps/web/components/dashboard/GlobalActions.tsx +++ b/apps/web/components/dashboard/GlobalActions.tsx @@ -2,11 +2,13 @@ import BulkBookmarksAction from "@/components/dashboard/BulkBookmarksAction"; import ChangeLayout from "@/components/dashboard/ChangeLayout"; +import SortOrderToggle from "@/components/dashboard/SortOrderToggle"; export default function GlobalActions() { return (
+
); diff --git a/apps/web/components/dashboard/SortOrderToggle.tsx b/apps/web/components/dashboard/SortOrderToggle.tsx new file mode 100644 index 00000000..8c0f617d --- /dev/null +++ b/apps/web/components/dashboard/SortOrderToggle.tsx @@ -0,0 +1,56 @@ +import { ButtonWithTooltip } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { useTranslation } from "@/lib/i18n/client"; +import { useSortOrderStore } from "@/lib/store/useSortOrderStore"; +import { Check, SortAsc, SortDesc } from "lucide-react"; + +export default function SortOrderToggle() { + const { t } = useTranslation(); + + const { sortOrder: currentSort, setSortOrder } = useSortOrderStore(); + + return ( + + + + {currentSort === "asc" ? ( + + ) : ( + + )} + + + + setSortOrder("desc")} + > +
+ + {t("actions.sort.newest_first")} +
+ {currentSort === "desc" && } +
+ setSortOrder("asc")} + > +
+ + {t("actions.sort.oldest_first")} +
+ {currentSort === "asc" && } +
+
+
+ ); +} diff --git a/apps/web/components/dashboard/bookmarks/Bookmarks.tsx b/apps/web/components/dashboard/bookmarks/Bookmarks.tsx index 5729e846..3f606346 100644 --- a/apps/web/components/dashboard/bookmarks/Bookmarks.tsx +++ b/apps/web/components/dashboard/bookmarks/Bookmarks.tsx @@ -13,7 +13,7 @@ export default async function Bookmarks({ showDivider, showEditorCard = false, }: { - query: ZGetBookmarksRequest; + query: Omit; // Sort order is handled by the store header?: React.ReactNode; showDivider?: boolean; showEditorCard?: boolean; diff --git a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx index d18eeb1b..e43d061b 100644 --- a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx +++ b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx @@ -1,6 +1,8 @@ "use client"; +import { useEffect } from "react"; import UploadDropzone from "@/components/dashboard/UploadDropzone"; +import { useSortOrderStore } from "@/lib/store/useSortOrderStore"; import { api } from "@/lib/trpc"; import type { @@ -16,14 +18,18 @@ export default function UpdatableBookmarksGrid({ bookmarks: initialBookmarks, showEditorCard = false, }: { - query: ZGetBookmarksRequest; + query: Omit; // Sort order is handled by the store bookmarks: ZGetBookmarksResponse; showEditorCard?: boolean; itemsPerPage?: number; }) { - const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = + const sortOrder = useSortOrderStore((state) => state.sortOrder); + + const finalQuery = { ...query, sortOrder }; + + const { data, fetchNextPage, hasNextPage, isFetchingNextPage, refetch } = api.bookmarks.getBookmarks.useInfiniteQuery( - { ...query, useCursorV2: true }, + { ...finalQuery, useCursorV2: true }, { initialData: () => ({ pages: [initialBookmarks], @@ -31,9 +37,14 @@ export default function UpdatableBookmarksGrid({ }), initialCursor: null, getNextPageParam: (lastPage) => lastPage.nextCursor, + refetchOnMount: true, }, ); + useEffect(() => { + refetch(); + }, [sortOrder, refetch]); + const grid = ( b.bookmarks)} @@ -45,7 +56,7 @@ export default function UpdatableBookmarksGrid({ ); return ( - + {showEditorCard ? {grid} : grid} ); -- cgit v1.2.3-70-g09d2