diff --git a/src/components/algolia-results/summer-course/summer-course.tsx b/src/components/algolia-results/summer-course/summer-course.tsx index 56f59154..1b8cbffe 100644 --- a/src/components/algolia-results/summer-course/summer-course.tsx +++ b/src/components/algolia-results/summer-course/summer-course.tsx @@ -81,7 +81,7 @@ const SummerCourse = ({hit}: Props) => { }
- +
diff --git a/src/components/elements/favorite-button.tsx b/src/components/elements/favorite-button.tsx new file mode 100644 index 00000000..83a8a16d --- /dev/null +++ b/src/components/elements/favorite-button.tsx @@ -0,0 +1,37 @@ +"use client"; +import useFavorites from "@lib/hooks/useFavorites"; +import { HTMLAttributes } from "react"; +import { HeartIcon } from "@heroicons/react/24/outline"; +import { clsx } from "clsx"; +import { useIsClient } from "usehooks-ts"; + +type Props = HTMLAttributes & { + uuid: string; + title: string; + path: string; + units?: number; +}; + +const FavoriteButton = ({ uuid, title, path, units, ...props }: Props) => { + const { favs, addFav, removeFav } = useFavorites(); + const isFavorite = favs.some((fav) => fav.uuid === uuid); + + const onClick = () => { + isFavorite ? removeFav(uuid) : addFav(uuid, title, path, units); + }; + + // No need to add the button on the server, but also it doesn't show initial state correctly for some reason. + if (!useIsClient()) return null; + + return ( + + ); +}; + +export default FavoriteButton; diff --git a/src/components/elements/favorites-list.tsx b/src/components/elements/favorites-list.tsx new file mode 100644 index 00000000..cc5d76d5 --- /dev/null +++ b/src/components/elements/favorites-list.tsx @@ -0,0 +1,51 @@ +"use client"; + +import useFavorites from "@lib/hooks/useFavorites"; +import {HeartIcon} from "@heroicons/react/24/outline"; +import {useIsClient} from "usehooks-ts"; +import { XMarkIcon } from "@heroicons/react/20/solid"; + + +const FavoritesList = () => { + const { favs, removeFav } = useFavorites(); + + const removeFavorite = (uuid: string) => removeFav(uuid); + + // No need to add the button on the server, but also it doesn't show initial state correctly for some reason. + if (!useIsClient()) return; + + return ( +
+ {favs.length > 0 ? +
+ Your favorites list is empty. Tap the{" "} + {" "} + icon on courses you’re interested in to see them here. And share them with family and friends. +
+ : + <> + +
+ Total units +
+ + } +
+ {/* Shareable options: Text, Email, Copy Link */} +
+
+ ); +}; + +export default FavoritesList diff --git a/src/components/paragraphs/summer-user-favorite/user-favorite-paragraph.tsx b/src/components/paragraphs/summer-user-favorite/user-favorite-paragraph.tsx index 17945858..3617e75c 100644 --- a/src/components/paragraphs/summer-user-favorite/user-favorite-paragraph.tsx +++ b/src/components/paragraphs/summer-user-favorite/user-favorite-paragraph.tsx @@ -1,4 +1,4 @@ -import { HtmlHTMLAttributes} from "react"; +import { HtmlHTMLAttributes } from "react"; import {getConfigPage} from "@lib/gql/gql-queries"; import { StanfordBasicSiteSetting, @@ -12,8 +12,8 @@ type Props = HtmlHTMLAttributes & { } const UserFavoriteParagraph = async ({ paragraph, ...props }: Props) => { - const { favs } = useFavorites(); const siteSettingsConfig = await getConfigPage("StanfordBasicSiteSetting") + const { favs } = useFavorites(); if (!siteSettingsConfig?.suSiteAlgoliaId || !siteSettingsConfig.suSiteAlgoliaSearch || !siteSettingsConfig.suSiteAlgoliaIndex) { return; @@ -28,7 +28,8 @@ const UserFavoriteParagraph = async ({ paragraph, ...props }: Props) => { appId={siteSettingsConfig.suSiteAlgoliaId} searchIndex={siteSettingsConfig.suSiteAlgoliaIndex} searchApiKey={siteSettingsConfig.suSiteAlgoliaSearch} - itemUuids={favs} + // itemUuids={favs} + itemUuids={[]} // itemUuids={["eb0fe1c4-e98d-4fda-8962-4faa627340e0", "e66bd9be-a47b-4df7-804f-b173839e12aa", "e2979287-eef5-46a6-bb1e-e15e4c0e8280"]} /> diff --git a/src/lib/hooks/useFavorites.tsx b/src/lib/hooks/useFavorites.tsx index 50085e48..93f243e6 100644 --- a/src/lib/hooks/useFavorites.tsx +++ b/src/lib/hooks/useFavorites.tsx @@ -1,32 +1,38 @@ "use client"; import { useCallback } from "react"; -import { useLocalStorage, useIsClient } from "usehooks-ts"; +import { useLocalStorage } from "usehooks-ts"; + +type Favorite = { + uuid: string; + title: string; + path: string; + units: number; +}; const useFavorites = (): { - favs: string[]; - addFav: (_uuid: string) => void; + favs: Favorite[]; + addFav: (_uuid: string, _title: string, _path: string, _units?: number) => void; removeFav: (_uuid: string) => void; } => { - const isClient = useIsClient(); - const [favs, setFavs] = useLocalStorage("favorites", [], { initializeWithValue: false }); + const [favs, setFavs] = useLocalStorage("favorites", [], {initializeWithValue: false}); const addFav = useCallback( - (uuid: string) => { - setFavs([...favs, uuid ]); + (uuid: string, title: string, path: string, units: number) => { + setFavs([...favs, { uuid, title, path, units }]); }, [favs, setFavs] ); const removeFav = useCallback( (uuid: string) => { - const updatedFavs = favs.filter((fav) => fav !== uuid); + const updatedFavs = favs.filter((fav) => fav.uuid !== uuid); setFavs(updatedFavs); }, [favs, setFavs] ); - return { favs: isClient ? favs : [], addFav, removeFav }; + return { favs, addFav, removeFav }; }; export default useFavorites;