diff --git a/frontend/app/home.tsx b/frontend/app/home.tsx index ccc2de1e..e11f4132 100644 --- a/frontend/app/home.tsx +++ b/frontend/app/home.tsx @@ -1,7 +1,9 @@ import { useEffect, useState } from "react"; import { getEventsEventsGet, MiniEventDTO } from "@/client"; +import ArticleLoading from "@/components/news/article-loading"; import NewsArticle from "@/components/news/news-article"; +import { useUserStore } from "@/store/user/user-store-provider"; const NUM_TOP_EVENTS = 10; const DAYS_PER_WEEK = 7; @@ -10,6 +12,7 @@ const DAYS_PER_WEEK = 7; const Home = () => { const [topEvents, setTopEvents] = useState([]); const [isLoaded, setIsLoaded] = useState(false); + const user = useUserStore((state) => state.user); useEffect(() => { const fetchTopEvents = async () => { @@ -20,12 +23,24 @@ const Home = () => { .toISOString() .split("T")[0]; - const response = await getEventsEventsGet({ - query: { - start_date: formattedEventStartDate, - limit: NUM_TOP_EVENTS, - }, - }); + let eventQuery; + if (user?.categories && user.categories.length > 0) { + eventQuery = { + query: { + start_date: formattedEventStartDate, + limit: NUM_TOP_EVENTS, + category_ids: user.categories.map((category) => category.id), + }, + }; + } else { + eventQuery = { + query: { + start_date: formattedEventStartDate, + limit: NUM_TOP_EVENTS, + }, + }; + } + const response = await getEventsEventsGet(eventQuery); if (response.error) { console.log(response.error); @@ -36,7 +51,7 @@ const Home = () => { }; fetchTopEvents(); - }, []); + }, [user]); return (
@@ -51,7 +66,11 @@ const Home = () => {
{!isLoaded ? ( -

Loading data...

+ <> + + + + ) : ( topEvents.map((newsEvent: MiniEventDTO, index: number) => ( diff --git a/frontend/components/icons/placeholder-image.tsx b/frontend/components/icons/placeholder-image.tsx new file mode 100644 index 00000000..8399683a --- /dev/null +++ b/frontend/components/icons/placeholder-image.tsx @@ -0,0 +1,27 @@ +const PlaceholderImage = ({ classname }: { classname?: string }) => { + return ( +
+
+ + + + +
+
+ ); +}; + +export default PlaceholderImage; diff --git a/frontend/components/news/article-loading.tsx b/frontend/components/news/article-loading.tsx new file mode 100644 index 00000000..fc635d0a --- /dev/null +++ b/frontend/components/news/article-loading.tsx @@ -0,0 +1,26 @@ +const ArticleLoading = () => { + return ( +
+
+
+ {/* Article source placeholder */} +
+ {/* Article date placeholder */} +
+
+ {/* Event title placeholder */} +
+ {/* Event description placeholder */} +
+ {/* Event category placeholder */} +
+
+
+
+ {/* Event image placeholder */} +
+
+ ); +}; + +export default ArticleLoading; diff --git a/frontend/components/news/news-article.tsx b/frontend/components/news/news-article.tsx index 64d6faef..dabfdad2 100644 --- a/frontend/components/news/news-article.tsx +++ b/frontend/components/news/news-article.tsx @@ -4,6 +4,7 @@ import { ArrowUpRightIcon } from "lucide-react"; import { CategoryDTO, MiniEventDTO } from "@/client"; import Chip from "@/components/display/chip"; +import PlaceholderImage from "@/components/icons/placeholder-image"; import { categoriesToDisplayName, categoriesToIconsMap, @@ -15,15 +16,19 @@ const NewsArticle = (props: { newsEvent: MiniEventDTO }) => { const newsEvent = props.newsEvent; const newsArticle = newsEvent.original_article; const [categories, setCategories] = useState([]); - const PLACEHOLDER_IMG_URL = - "https://upload.wikimedia.org/wikipedia/commons/3/3f/Placeholder_view_vector.svg"; + const IMG_HEIGHT = 154; useEffect(() => { - setCategories( - newsEvent.categories.map((category: CategoryDTO) => - getCategoryFor(category.name), - ), - ); + try { + setCategories( + newsEvent.categories.map((category: CategoryDTO) => + getCategoryFor(category.name), + ), + ); + } catch (error) { + console.log(error); + setCategories([Category.Others]); + } }, [newsEvent]); const parseDate = (dateString: string) => { @@ -51,10 +56,10 @@ const NewsArticle = (props: { newsEvent: MiniEventDTO }) => {

{newsEvent.title}

{newsEvent.description}

- {categories?.map((category: Category) => ( + {categories?.map((category: Category, index: number) => ( @@ -62,17 +67,23 @@ const NewsArticle = (props: { newsEvent: MiniEventDTO }) => {
- + {newsArticle.image_url ? ( + + ) : ( +
+ +
+ )}
); diff --git a/frontend/types/categories.ts b/frontend/types/categories.ts index b22ef238..29d63d05 100644 --- a/frontend/types/categories.ts +++ b/frontend/types/categories.ts @@ -1,5 +1,6 @@ import { Building2, + CircleHelp, DollarSign, Film, HeartHandshake, @@ -23,6 +24,7 @@ export enum Category { GenderEquality = "Gender & equality", Religion = "Religion", SocietyCulture = "Society & culture", + Others = "Others", } export const getCategoryFor = (categoryName: string) => { @@ -39,7 +41,10 @@ export const getCategoryFor = (categoryName: string) => { "society & culture": Category.SocietyCulture, }; const formattedName = categoryName.toLowerCase(); - return mappings[formattedName]; + if (formattedName in mappings) { + return mappings[formattedName]; + } + return Category.Others; }; export const categoriesToDisplayName: Record = { @@ -53,6 +58,7 @@ export const categoriesToDisplayName: Record = { [Category.GenderEquality]: "Gender & equality", [Category.Religion]: "Religion", [Category.SocietyCulture]: "Society & culture", + [Category.Others]: "Others", }; export const categoriesToIconsMap: Record = { @@ -66,4 +72,5 @@ export const categoriesToIconsMap: Record = { [Category.GenderEquality]: Scale, [Category.Religion]: HeartHandshake, [Category.SocietyCulture]: UsersRound, + [Category.Others]: CircleHelp, };