feat: implement social share buttons

This commit is contained in:
fredy.siswanto
2025-03-08 20:25:41 +07:00
parent 46e009f888
commit 1881032ed2
4 changed files with 95 additions and 53 deletions
+57 -46
View File
@@ -1,59 +1,70 @@
import type { FC } from 'react'
import { Link } from 'react-router'
import { twMerge } from 'tailwind-merge'
import { LinkIcon } from '@heroicons/react/20/solid'
import { useState } from 'react'
import {
FacebookShareButton,
LinkedinShareButton,
TwitterShareButton,
InstapaperShareButton,
} from 'react-share'
import { FacebookIcon } from '~/components/icons/facebook'
import { InstagramIcon } from '~/components/icons/instagram'
import { LinkIcon } from '~/components/icons/link-icon'
import { LinkedinIcon } from '~/components/icons/linkedin'
import { XIcon } from '~/components/icons/x'
type SocialMediaProperties = {
className?: string
slug?: string
type SocialShareButtonsProperties = {
url: string
title: string
}
const dataSocialMedia = [
{
type: 'link',
url: 'post-id/',
icon: LinkIcon,
},
{
type: 'facebook',
url: 'https://facebook.com/',
icon: FacebookIcon,
},
{
type: 'linkedin',
url: 'https://linkedin.com/',
icon: LinkedinIcon,
},
{
type: 'x',
url: 'https://x.com/',
icon: XIcon,
},
{
type: 'instagram',
url: 'https://instagram.com/',
icon: InstagramIcon,
},
]
export const SocialShareButtons = ({
url,
title,
}: SocialShareButtonsProperties) => {
const [showPopup, setShowPopup] = useState(false)
export const IconsSocial: FC<SocialMediaProperties> = ({ className }) => {
const handleCopyLink = () => {
navigator.clipboard.writeText(url)
setShowPopup(true)
setTimeout(() => setShowPopup(false), 2000)
}
return (
<div className={twMerge('flex gap-2', className)}>
{dataSocialMedia.map(({ url, icon: Icon }, index) => (
<Link
key={index}
to={url}
target="_blank"
rel="noopener noreferrer"
>
<Icon className="h-8 w-8 rounded-full bg-gray-400 p-2 sm:h-10 sm:w-10" />
</Link>
))}
<div className="flex items-center space-x-2">
{showPopup && (
<div className="absolute top-0 rounded-lg border-2 border-gray-400 bg-white p-2 shadow-lg">
Link berhasil disalin!
</div>
)}
<button onClick={handleCopyLink}>
<LinkIcon className="h-8 w-8 rounded-full bg-gray-400 p-2 sm:h-10 sm:w-10" />
</button>
<FacebookShareButton
url={url}
title={title}
>
<FacebookIcon className="h-8 w-8 rounded-full bg-gray-400 p-2 sm:h-10 sm:w-10" />
</FacebookShareButton>
<LinkedinShareButton
url={url}
title={title}
>
<LinkedinIcon className="h-8 w-8 rounded-full bg-gray-400 p-2 sm:h-10 sm:w-10" />
</LinkedinShareButton>
<TwitterShareButton
url={url}
title={title}
>
<XIcon className="h-8 w-8 rounded-full bg-gray-400 p-2 sm:h-10 sm:w-10" />
</TwitterShareButton>
<InstapaperShareButton
url={url}
title={title}
>
<InstagramIcon className="h-8 w-8 rounded-full bg-gray-400 p-2 sm:h-10 sm:w-10" />
</InstapaperShareButton>
</div>
)
}
+12 -7
View File
@@ -4,7 +4,7 @@ import { useRouteLoaderData } from 'react-router'
import type { TTagResponse } from '~/apis/common/get-tags'
import { Card } from '~/components/ui/card'
import { CarouselSection } from '~/components/ui/carousel-section'
import { IconsSocial } from '~/components/ui/social-share'
import { SocialShareButtons } from '~/components/ui/social-share'
import { BERITA } from '~/data/contents'
import type { loader } from '~/routes/_news.detail.$slug'
import { formatDate } from '~/utils/formatter'
@@ -13,10 +13,10 @@ export const NewsDetailPage = () => {
const loaderData = useRouteLoaderData<typeof loader>(
'routes/_news.detail.$slug',
)
const currentUrl = globalThis.location
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { newsDetailData }: any = loaderData
const { title, content, featured_image, slug, author, live_at, tags } =
const { title, content, featured_image, author, live_at, tags } =
newsDetailData
return (
@@ -40,7 +40,11 @@ export const NewsDetailPage = () => {
<p className="text-sm">{formatDate(live_at)} . 5 min read </p>
</div>
</div>
<IconsSocial className="flex-row" />
{/* <IconsSocial className="flex-row" /> */}
<SocialShareButtons
url={`${currentUrl}`}
title={title}
/>
</div>
{/* end next planing create component for this section */}
<div className="w-full bg-amber-200">
@@ -59,9 +63,10 @@ export const NewsDetailPage = () => {
<div className="items-end justify-between border-b-gray-300 py-4 sm:flex">
<div className="flex flex-col max-sm:mb-3">
<p className="mb-2">Share this post</p>
<IconsSocial
className="a"
slug={slug}
<SocialShareButtons
url={`${currentUrl}`}
title={title}
/>
</div>
<div className="flex flex-wrap items-end gap-2">