From cc5331284b1bddedd0e547cec23e3d2068a20fc7 Mon Sep 17 00:00:00 2001 From: Ardeman Date: Sat, 15 Mar 2025 16:58:02 +0800 Subject: [PATCH] feat: enhance news detail page with subscription prompt and content restriction for basic users --- app/pages/news-detail/index.tsx | 22 ++++++++++++++-- app/routes/_news.detail.$slug.tsx | 44 +++++++++++++++++-------------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/app/pages/news-detail/index.tsx b/app/pages/news-detail/index.tsx index 8bcd236..62d2c23 100644 --- a/app/pages/news-detail/index.tsx +++ b/app/pages/news-detail/index.tsx @@ -1,16 +1,20 @@ import htmlParse from 'html-react-parser' import { useReadingTime } from 'react-hook-reading-time' import { useRouteLoaderData } from 'react-router' +import { twMerge } from 'tailwind-merge' +import { Button } from '~/components/ui/button' import { Card } from '~/components/ui/card' import { CarouselSection } from '~/components/ui/carousel-section' import { NewsAuthor } from '~/components/ui/news-author' import { SocialShareButtons } from '~/components/ui/social-share' import { Tags } from '~/components/ui/tags' +import { useNewsContext } from '~/contexts/news' import type { loader } from '~/routes/_news.detail.$slug' import type { TNews } from '~/types/news' export const NewsDetailPage = () => { + const { setIsSuccessOpen } = useNewsContext() const loaderData = useRouteLoaderData( 'routes/_news.detail.$slug', ) @@ -22,6 +26,7 @@ export const NewsDetailPage = () => { const currentUrl = globalThis.location const { title, content, featured_image, author, live_at, tags } = loaderData?.newsDetailData || {} + const { shouldSubscribe } = loaderData || {} const { text } = useReadingTime(content || '') @@ -51,10 +56,23 @@ export const NewsDetailPage = () => { /> -
-
+
+
{content && htmlParse(content)}
+ {shouldSubscribe && ( + + )}
diff --git a/app/routes/_news.detail.$slug.tsx b/app/routes/_news.detail.$slug.tsx index b3a4685..d183805 100644 --- a/app/routes/_news.detail.$slug.tsx +++ b/app/routes/_news.detail.$slug.tsx @@ -1,4 +1,5 @@ -import { isRouteErrorResponse, redirect } from 'react-router' +import { isRouteErrorResponse } from 'react-router' +import { stripHtml } from 'string-strip-html' import { getCategories } from '~/apis/common/get-categories' import { getNews } from '~/apis/common/get-news' @@ -12,17 +13,21 @@ import type { Route } from './+types/_news.detail.$slug' export const loader = async ({ request, params }: Route.LoaderArgs) => { const { userToken: accessToken } = await handleCookie(request) - if (!accessToken) { - return redirect('/') + let userData + if (accessToken) { + const { data } = await getUser({ accessToken }) + userData = data } - const { data: userData } = await getUser({ accessToken }) const { slug } = params - const { data: newsDetailData } = await getNewsBySlug({ slug, accessToken }) - if ( - userData.subscribe.subscribe_plan.code === 'basic' && - newsDetailData.is_premium - ) { - return redirect('/') + let { data: newsDetailData } = await getNewsBySlug({ slug, accessToken }) + const shouldSubscribe = + (!accessToken || userData?.subscribe?.subscribe_plan?.code === 'basic') && + newsDetailData?.is_premium + newsDetailData = { + ...newsDetailData, + content: shouldSubscribe + ? stripHtml(newsDetailData.content).result.slice(0, 600) + : newsDetailData.content, } const { data: categoriesData } = await getCategories() const beritaCode = 'berita' @@ -36,21 +41,20 @@ export const loader = async ({ request, params }: Route.LoaderArgs) => { newsDetailData, beritaCategory, beritaNews, + shouldSubscribe, } } export const meta = ({ data }: Route.MetaArgs) => { - if (data) { - const { newsDetailData } = data - const metaTitle = APP.title - const title = `${newsDetailData?.title} - ${metaTitle}` + const { newsDetailData } = data || {} + const metaTitle = APP.title + const title = `${newsDetailData?.title} - ${metaTitle}` - return [ - { - title, - }, - ] - } + return [ + { + title, + }, + ] } export const ErrorBoundary = ({ error }: Route.ErrorBoundaryProps) => {