From 6edca07fa6e83193c7c6f4e2c00c20a4cac3cfab Mon Sep 17 00:00:00 2001 From: Ardeman Date: Thu, 20 Mar 2025 12:10:38 +0800 Subject: [PATCH] feat: enhance news fetching with pagination and active status filters --- app/apis/common/get-news.ts | 9 +- app/components/ui/category-section.tsx | 117 +++++++++++++------------ app/pages/news-categories/index.tsx | 2 +- app/pages/news-detail/index.tsx | 2 +- app/routes/_news._index.tsx | 3 + app/routes/_news.category.$code.tsx | 3 +- app/routes/_news.detail.$slug.tsx | 8 +- app/routes/actions.log.ads.$id.ts | 3 +- 8 files changed, 80 insertions(+), 67 deletions(-) diff --git a/app/apis/common/get-news.ts b/app/apis/common/get-news.ts index 67114e3..2960725 100644 --- a/app/apis/common/get-news.ts +++ b/app/apis/common/get-news.ts @@ -33,15 +33,22 @@ export type TAuthorResponse = z.infer type TParameters = { categories?: string[] tags?: string[] + active?: boolean + limit?: number + page?: number } & THttpServer export const getNews = async (parameters?: TParameters) => { - const { categories, tags, ...restParameters } = parameters || {} + const { categories, tags, active, limit, page, ...restParameters } = + parameters || {} try { const { data } = await HttpServer(restParameters).get(`/api/news`, { params: { ...(categories && { categories: categories.join('+') }), ...(tags && { tags: tags.join('+') }), + ...(active && { active }), + ...(limit && { limit }), + ...(page && { page }), }, }) return dataResponseSchema.parse(data) diff --git a/app/components/ui/category-section.tsx b/app/components/ui/category-section.tsx index 97a2c00..a67f875 100644 --- a/app/components/ui/category-section.tsx +++ b/app/components/ui/category-section.tsx @@ -1,23 +1,18 @@ -import { useRouteLoaderData } from 'react-router' +import { Suspense } from 'react' +import { Await, useRouteLoaderData } from 'react-router' import { stripHtml } from 'string-strip-html' import { twMerge } from 'tailwind-merge' -import type { TNewsResponse } from '~/apis/common/get-news' import { CarouselNextIcon } from '~/components/icons/carousel-next' import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' import { Button } from '~/components/ui/button' import { useNewsContext } from '~/contexts/news' import type { loader } from '~/routes/_news' +import type { TNews } from '~/types/news' import { getPremiumAttribute } from '~/utils/render' import { Tags } from './tags' -type TNews = { - title: string - description: string - items: TNewsResponse[] -} - export const CategorySection = (properties: TNews) => { const { setIsSuccessOpen } = useNewsContext() const loaderData = useRouteLoaderData('routes/_news') @@ -47,56 +42,64 @@ export const CategorySection = (properties: TNews) => {
- {items.map( - ( - { featured_image, title, content, tags, slug, is_premium }, - index, - ) => ( -
- {title} -
- - -
-

Loading...

}> + + {(value) => + value.data.map( + ( + { featured_image, title, content, tags, slug, is_premium }, + index, + ) => ( +
- {title} - -

- {stripHtml(content).result} -

-
- -
-
- ), - )} + {title} +
+ + +
+

+ {title} +

+

+ {stripHtml(content).result} +

+
+ +
+
+ ), + ) + } + +
diff --git a/app/pages/news-categories/index.tsx b/app/pages/news-categories/index.tsx index 6cfdb78..65f0293 100644 --- a/app/pages/news-categories/index.tsx +++ b/app/pages/news-categories/index.tsx @@ -17,7 +17,7 @@ export const NewsCategoriesPage = () => {
diff --git a/app/pages/news-detail/index.tsx b/app/pages/news-detail/index.tsx index 62d2c23..2235d43 100644 --- a/app/pages/news-detail/index.tsx +++ b/app/pages/news-detail/index.tsx @@ -21,7 +21,7 @@ export const NewsDetailPage = () => { const berita: TNews = { title: loaderData?.beritaCategory?.name || '', description: loaderData?.beritaCategory?.description || '', - items: loaderData?.beritaNews || [], + items: loaderData?.beritaData || Promise.resolve({ data: [] }), } const currentUrl = globalThis.location const { title, content, featured_image, author, live_at, tags } = diff --git a/app/routes/_news._index.tsx b/app/routes/_news._index.tsx index 55de589..a9345fc 100644 --- a/app/routes/_news._index.tsx +++ b/app/routes/_news._index.tsx @@ -27,12 +27,15 @@ export const loader = async ({}: Route.LoaderArgs) => { const spotlightData = getNews({ categories: [spotlightCode], + active: true, }) const beritaData = getNews({ categories: [beritaCode], + active: true, }) const kajianData = getNews({ categories: [kajianCode], + active: true, }) return { spotlightCategory, diff --git a/app/routes/_news.category.$code.tsx b/app/routes/_news.category.$code.tsx index a472132..3788e96 100644 --- a/app/routes/_news.category.$code.tsx +++ b/app/routes/_news.category.$code.tsx @@ -11,8 +11,7 @@ export const loader = async ({ params }: Route.LoaderArgs) => { const { data: categoriesData } = await getCategories() const { code } = params const categoryData = categoriesData.find((category) => category.code === code) - let { data: newsData } = await getNews({ categories: [code] }) - newsData = newsData.filter((news) => new Date(news.live_at) <= new Date()) + const newsData = getNews({ categories: [code], active: true }) return { categoryData, newsData } } diff --git a/app/routes/_news.detail.$slug.tsx b/app/routes/_news.detail.$slug.tsx index 57b7f58..16f314f 100644 --- a/app/routes/_news.detail.$slug.tsx +++ b/app/routes/_news.detail.$slug.tsx @@ -15,7 +15,8 @@ export const loader = async ({ request, params }: Route.LoaderArgs) => { const userAgent = request.headers.get('user-agent') const ipAddress = request.headers.get('cf-connecting-ip') || - request.headers.get('x-forwarded-for') + request.headers.get('x-forwarded-for') || + 'localhost' const { userToken: accessToken } = await handleCookie(request) let userData if (accessToken) { @@ -43,13 +44,12 @@ export const loader = async ({ request, params }: Route.LoaderArgs) => { const beritaCategory = categoriesData.find( (category) => category.code === beritaCode, ) - let { data: beritaNews } = await getNews({ categories: [beritaCode] }) - beritaNews = beritaNews.filter((news) => new Date(news.live_at) <= new Date()) + const beritaData = getNews({ categories: [beritaCode], active: true }) return { newsDetailData, beritaCategory, - beritaNews, + beritaData, shouldSubscribe, } } diff --git a/app/routes/actions.log.ads.$id.ts b/app/routes/actions.log.ads.$id.ts index 4766052..7e5ea84 100644 --- a/app/routes/actions.log.ads.$id.ts +++ b/app/routes/actions.log.ads.$id.ts @@ -10,7 +10,8 @@ export const action = async ({ request, params }: Route.ActionArgs) => { const userAgent = request.headers.get('user-agent') const ipAddress = request.headers.get('cf-connecting-ip') || - request.headers.get('x-forwarded-for') + request.headers.get('x-forwarded-for') || + 'localhost' const { userToken: accessToken } = await handleCookie(request) const { id } = params try {