2025-02-24 08:23:22 +08:00
|
|
|
import htmlParse from 'html-react-parser'
|
2025-03-08 15:34:38 +08:00
|
|
|
import { useReadingTime } from 'react-hook-reading-time'
|
2025-03-08 00:14:30 +07:00
|
|
|
import { useRouteLoaderData } from 'react-router'
|
2025-03-15 16:58:02 +08:00
|
|
|
import { twMerge } from 'tailwind-merge'
|
2025-02-24 08:23:22 +08:00
|
|
|
|
2025-03-15 16:58:02 +08:00
|
|
|
import { Button } from '~/components/ui/button'
|
2025-02-20 07:01:36 +08:00
|
|
|
import { Card } from '~/components/ui/card'
|
2025-02-28 18:55:12 +07:00
|
|
|
import { CarouselSection } from '~/components/ui/carousel-section'
|
2025-03-08 21:29:39 +07:00
|
|
|
import { NewsAuthor } from '~/components/ui/news-author'
|
2025-03-08 20:25:41 +07:00
|
|
|
import { SocialShareButtons } from '~/components/ui/social-share'
|
2025-03-09 11:56:57 +08:00
|
|
|
import { Tags } from '~/components/ui/tags'
|
2025-03-15 16:58:02 +08:00
|
|
|
import { useNewsContext } from '~/contexts/news'
|
2025-03-08 00:14:30 +07:00
|
|
|
import type { loader } from '~/routes/_news.detail.$slug'
|
2025-03-09 12:32:36 +08:00
|
|
|
import type { TNews } from '~/types/news'
|
2025-02-20 07:01:36 +08:00
|
|
|
|
|
|
|
|
export const NewsDetailPage = () => {
|
2025-03-15 16:58:02 +08:00
|
|
|
const { setIsSuccessOpen } = useNewsContext()
|
2025-03-08 00:14:30 +07:00
|
|
|
const loaderData = useRouteLoaderData<typeof loader>(
|
|
|
|
|
'routes/_news.detail.$slug',
|
|
|
|
|
)
|
2025-03-09 12:32:36 +08:00
|
|
|
const berita: TNews = {
|
|
|
|
|
title: loaderData?.beritaCategory?.name || '',
|
|
|
|
|
description: loaderData?.beritaCategory?.description || '',
|
|
|
|
|
items: loaderData?.beritaNews || [],
|
|
|
|
|
}
|
2025-03-08 20:25:41 +07:00
|
|
|
const currentUrl = globalThis.location
|
|
|
|
|
const { title, content, featured_image, author, live_at, tags } =
|
2025-03-09 09:32:51 +08:00
|
|
|
loaderData?.newsDetailData || {}
|
2025-03-15 16:58:02 +08:00
|
|
|
const { shouldSubscribe } = loaderData || {}
|
2025-03-08 00:14:30 +07:00
|
|
|
|
2025-03-08 15:34:38 +08:00
|
|
|
const { text } = useReadingTime(content || '')
|
2025-03-08 00:14:30 +07:00
|
|
|
|
2025-02-20 07:01:36 +08:00
|
|
|
return (
|
2025-03-02 12:15:31 +07:00
|
|
|
<div className="sm-max:mx-5 relative">
|
2025-02-20 22:20:27 +07:00
|
|
|
<Card>
|
|
|
|
|
<div className="py-5 sm:px-30">
|
2025-03-09 14:54:18 +08:00
|
|
|
<h2 className="text-xl font-extrabold sm:text-4xl">{title}</h2>
|
2025-02-20 22:20:27 +07:00
|
|
|
|
2025-02-28 18:55:12 +07:00
|
|
|
<div className="my-5 w-full items-center justify-between gap-2 align-middle sm:flex">
|
2025-03-08 21:29:39 +07:00
|
|
|
<NewsAuthor
|
|
|
|
|
author={author}
|
|
|
|
|
live_at={live_at}
|
|
|
|
|
text={text}
|
|
|
|
|
/>
|
2025-03-08 20:25:41 +07:00
|
|
|
<SocialShareButtons
|
|
|
|
|
url={`${currentUrl}`}
|
2025-03-08 20:53:30 +07:00
|
|
|
title={`${title}`}
|
2025-03-08 20:25:41 +07:00
|
|
|
/>
|
2025-02-20 22:20:27 +07:00
|
|
|
</div>
|
2025-03-08 21:29:39 +07:00
|
|
|
|
2025-02-20 22:20:27 +07:00
|
|
|
<div className="w-full bg-amber-200">
|
|
|
|
|
<img
|
2025-03-08 00:14:30 +07:00
|
|
|
src={featured_image}
|
2025-02-20 22:20:27 +07:00
|
|
|
alt={title}
|
2025-02-28 18:55:12 +07:00
|
|
|
className="w-full object-cover object-center sm:h-[600px]"
|
2025-02-20 22:20:27 +07:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-03-15 16:58:02 +08:00
|
|
|
<div className="mt-8 flex flex-col items-center justify-center gap-y-4">
|
|
|
|
|
<article
|
|
|
|
|
className={twMerge(
|
|
|
|
|
'prose prose-headings:my-0.5 prose-p:my-0.5',
|
|
|
|
|
shouldSubscribe ? 'line-clamp-5' : '',
|
|
|
|
|
)}
|
|
|
|
|
>
|
2025-03-08 15:23:22 +08:00
|
|
|
{content && htmlParse(content)}
|
2025-02-24 20:36:43 +07:00
|
|
|
</article>
|
2025-03-15 16:58:02 +08:00
|
|
|
{shouldSubscribe && (
|
|
|
|
|
<Button
|
|
|
|
|
onClick={() => setIsSuccessOpen('warning')}
|
|
|
|
|
className="w-full"
|
|
|
|
|
>
|
|
|
|
|
Read More
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
2025-02-24 20:36:43 +07:00
|
|
|
</div>
|
2025-03-06 22:49:56 +07:00
|
|
|
<div className="items-end justify-between border-b-gray-300 py-4 sm:flex">
|
2025-02-28 18:55:12 +07:00
|
|
|
<div className="flex flex-col max-sm:mb-3">
|
2025-02-20 22:20:27 +07:00
|
|
|
<p className="mb-2">Share this post</p>
|
2025-03-08 20:25:41 +07:00
|
|
|
|
|
|
|
|
<SocialShareButtons
|
|
|
|
|
url={`${currentUrl}`}
|
2025-03-08 20:53:30 +07:00
|
|
|
title={`${title}`}
|
2025-03-08 00:14:30 +07:00
|
|
|
/>
|
2025-02-20 22:20:27 +07:00
|
|
|
</div>
|
2025-03-09 11:56:57 +08:00
|
|
|
|
|
|
|
|
<Tags tags={tags || []} />
|
2025-02-20 22:20:27 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Card>
|
|
|
|
|
|
2025-03-02 12:15:31 +07:00
|
|
|
<Card className="bg-white p-5 max-sm:hidden">
|
2025-03-09 12:32:36 +08:00
|
|
|
<CarouselSection {...berita} />
|
2025-02-20 07:01:36 +08:00
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|