fix: button save in landing page
This commit is contained in:
parent
c003ef075e
commit
2e86d97aee
|
|
@ -78,12 +78,21 @@ const useTableColumns = () => {
|
|||
return <span className="whitespace-nowrap">{formattedDate}</span>;
|
||||
},
|
||||
},
|
||||
// {
|
||||
// accessorKey: "creatorName",
|
||||
// header: "Creator Group",
|
||||
// cell: ({ row }) => (
|
||||
// <span className="whitespace-nowrap">
|
||||
// {row.getValue("creatorName") || row.getValue("createdByName")}
|
||||
// </span>
|
||||
// ),
|
||||
// },
|
||||
{
|
||||
accessorKey: "creatorName",
|
||||
header: "Creator Group",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorName") || row.getValue("createdByName")}
|
||||
{row.original.creatorName || row.original.createdByName || "-"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
|
|
@ -130,33 +139,90 @@ const useTableColumns = () => {
|
|||
},
|
||||
},
|
||||
|
||||
// {
|
||||
// accessorKey: "statusName",
|
||||
// header: "Status",
|
||||
// cell: ({ row }) => {
|
||||
// const statusColors: Record<string, string> = {
|
||||
// diterima: "bg-green-100 text-green-600",
|
||||
// "menunggu review": "bg-orange-100 text-orange-600",
|
||||
// };
|
||||
|
||||
// const colors = [
|
||||
// "bg-orange-100 text-orange-600",
|
||||
// "bg-orange-100 text-orange-600",
|
||||
// "bg-green-100 text-green-600",
|
||||
// "bg-blue-100 text-blue-600",
|
||||
// "bg-red-200 text-red-600",
|
||||
// ];
|
||||
|
||||
// const status =
|
||||
// Number(row.original?.statusId) == 2 &&
|
||||
// row.original?.reviewedAtLevel !== null &&
|
||||
// !row.original?.reviewedAtLevel?.includes(`:${userLevelId}:`) &&
|
||||
// Number(row.original?.creatorGroupLevelId) != Number(userLevelId)
|
||||
// ? "1"
|
||||
// : row.original?.statusId;
|
||||
// const statusStyles =
|
||||
// colors[Number(status)] || "bg-red-200 text-red-600";
|
||||
// // const statusStyles = statusColors[status] || "bg-red-200 text-red-600";
|
||||
|
||||
// return (
|
||||
// <Badge
|
||||
// className={cn(
|
||||
// "rounded-full px-5 w-full whitespace-nowrap",
|
||||
// statusStyles
|
||||
// )}
|
||||
// >
|
||||
// {(Number(row.original?.statusId) == 2 &&
|
||||
// !row.original?.reviewedAtLevel !== null &&
|
||||
// !row.original?.reviewedAtLevel?.includes(
|
||||
// `:${Number(userLevelId)}:`
|
||||
// ) &&
|
||||
// Number(row.original?.creatorGroupLevelId) !=
|
||||
// Number(userLevelId)) ||
|
||||
// (Number(row.original?.statusId) == 1 &&
|
||||
// Number(row.original?.needApprovalFromLevel) ==
|
||||
// Number(userLevelId))
|
||||
// ? "Menunggu Review"
|
||||
// : row.original?.statusName}{" "}
|
||||
// </Badge>
|
||||
// );
|
||||
// },
|
||||
// },
|
||||
{
|
||||
accessorKey: "statusName",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
const statusColors: Record<string, string> = {
|
||||
diterima: "bg-green-100 text-green-600",
|
||||
"menunggu review": "bg-orange-100 text-orange-600",
|
||||
const statusId = Number(row.original?.statusId);
|
||||
const reviewedAtLevel = row.original?.reviewedAtLevel || "";
|
||||
const creatorGroupLevelId = Number(row.original?.creatorGroupLevelId);
|
||||
const needApprovalFromLevel = Number(
|
||||
row.original?.needApprovalFromLevel
|
||||
);
|
||||
|
||||
const userHasReviewed = reviewedAtLevel.includes(`:${userLevelId}:`);
|
||||
const isCreator = creatorGroupLevelId === Number(userLevelId);
|
||||
|
||||
const isWaitingForReview =
|
||||
statusId === 2 && !userHasReviewed && !isCreator;
|
||||
const isApprovalNeeded =
|
||||
statusId === 1 && needApprovalFromLevel === Number(userLevelId);
|
||||
|
||||
const label =
|
||||
isWaitingForReview || isApprovalNeeded
|
||||
? "Menunggu Review"
|
||||
: statusId === 2
|
||||
? "Diterima"
|
||||
: row.original?.statusName;
|
||||
|
||||
const colors: Record<string, string> = {
|
||||
"Menunggu Review": "bg-orange-100 text-orange-600",
|
||||
Diterima: "bg-green-100 text-green-600",
|
||||
default: "bg-red-200 text-red-600",
|
||||
};
|
||||
|
||||
const colors = [
|
||||
"bg-orange-100 text-orange-600",
|
||||
"bg-orange-100 text-orange-600",
|
||||
"bg-green-100 text-green-600",
|
||||
"bg-blue-100 text-blue-600",
|
||||
"bg-red-200 text-red-600",
|
||||
];
|
||||
|
||||
const status =
|
||||
Number(row.original?.statusId) == 2 &&
|
||||
row.original?.reviewedAtLevel !== null &&
|
||||
!row.original?.reviewedAtLevel?.includes(`:${userLevelId}:`) &&
|
||||
Number(row.original?.creatorGroupLevelId) != Number(userLevelId)
|
||||
? "1"
|
||||
: row.original?.statusId;
|
||||
const statusStyles =
|
||||
colors[Number(status)] || "bg-red-200 text-red-600";
|
||||
// const statusStyles = statusColors[status] || "bg-red-200 text-red-600";
|
||||
const statusStyles = colors[label] || colors.default;
|
||||
|
||||
return (
|
||||
<Badge
|
||||
|
|
@ -165,18 +231,7 @@ const useTableColumns = () => {
|
|||
statusStyles
|
||||
)}
|
||||
>
|
||||
{(Number(row.original?.statusId) == 2 &&
|
||||
!row.original?.reviewedAtLevel !== null &&
|
||||
!row.original?.reviewedAtLevel?.includes(
|
||||
`:${Number(userLevelId)}:`
|
||||
) &&
|
||||
Number(row.original?.creatorGroupLevelId) !=
|
||||
Number(userLevelId)) ||
|
||||
(Number(row.original?.statusId) == 1 &&
|
||||
Number(row.original?.needApprovalFromLevel) ==
|
||||
Number(userLevelId))
|
||||
? "Menunggu Review"
|
||||
: row.original?.statusName}{" "}
|
||||
{label}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,17 +14,16 @@ import { toggleBookmark, getBookmarkSummaryForUser } from "@/service/content";
|
|||
export default function Header() {
|
||||
const [data, setData] = useState<any[]>([]);
|
||||
const [bookmarkedIds, setBookmarkedIds] = useState<Set<number>>(new Set());
|
||||
const [userId, setUserId] = useState<string | null>(getCookiesDecrypt("uie") || null);
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
||||
// Get slug from URL params
|
||||
const slug = params?.slug as string;
|
||||
|
||||
// ✅ Ambil data artikel
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// 🔹 Ambil artikel
|
||||
const response = await listArticles(
|
||||
1,
|
||||
5,
|
||||
|
|
@ -38,8 +37,7 @@ export default function Header() {
|
|||
let articlesData: any[] = [];
|
||||
|
||||
if (response?.error) {
|
||||
// fallback ke API lama
|
||||
const fallbackResponse = await listData(
|
||||
const fallback = await listData(
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
|
@ -50,12 +48,11 @@ export default function Header() {
|
|||
"",
|
||||
""
|
||||
);
|
||||
articlesData = fallbackResponse?.data?.data?.content || [];
|
||||
articlesData = fallback?.data?.data?.content || [];
|
||||
} else {
|
||||
articlesData = response?.data?.data || [];
|
||||
}
|
||||
|
||||
// 🔹 Transform agar seragam
|
||||
const transformed = articlesData.map((article: any) => ({
|
||||
id: article.id,
|
||||
title: article.title,
|
||||
|
|
@ -81,65 +78,68 @@ export default function Header() {
|
|||
}));
|
||||
|
||||
setData(transformed);
|
||||
|
||||
const roleId = Number(getCookiesDecrypt("urie"));
|
||||
if (roleId && !isNaN(roleId)) {
|
||||
const saved = localStorage.getItem("bookmarkedIds");
|
||||
let localSet = new Set<number>();
|
||||
if (saved) {
|
||||
localSet = new Set(JSON.parse(saved));
|
||||
setBookmarkedIds(localSet);
|
||||
}
|
||||
|
||||
const res = await getBookmarkSummaryForUser();
|
||||
const bookmarks =
|
||||
res?.data?.data?.recentBookmarks ||
|
||||
res?.data?.data?.bookmarks ||
|
||||
res?.data?.data ||
|
||||
[];
|
||||
|
||||
const ids = new Set<number>(
|
||||
(Array.isArray(bookmarks) ? bookmarks : [])
|
||||
.map((b: any) => Number(b.articleId ?? b.id ?? b.article?.id))
|
||||
.filter((x) => !isNaN(x))
|
||||
);
|
||||
|
||||
const merged = new Set([...localSet, ...ids]);
|
||||
setBookmarkedIds(merged);
|
||||
localStorage.setItem(
|
||||
"bookmarkedIds",
|
||||
JSON.stringify(Array.from(merged))
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Gagal memuat data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
}, [slug]);
|
||||
|
||||
// Simpan setiap kali state berubah
|
||||
// ✅ Ambil data bookmark dari backend (bukan localStorage)
|
||||
useEffect(() => {
|
||||
if (bookmarkedIds.size > 0) {
|
||||
localStorage.setItem(
|
||||
"bookmarkedIds",
|
||||
JSON.stringify(Array.from(bookmarkedIds))
|
||||
);
|
||||
}
|
||||
}, [bookmarkedIds]);
|
||||
const fetchBookmarks = async () => {
|
||||
const currentUserId: any = getCookiesDecrypt("uie");
|
||||
setUserId(currentUserId);
|
||||
|
||||
if (!currentUserId) {
|
||||
setBookmarkedIds(new Set()); // logout: reset
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getBookmarkSummaryForUser();
|
||||
const bookmarks =
|
||||
res?.data?.data?.recentBookmarks ||
|
||||
res?.data?.data?.bookmarks ||
|
||||
res?.data?.data ||
|
||||
[];
|
||||
|
||||
const ids = new Set<number>(
|
||||
(Array.isArray(bookmarks) ? bookmarks : [])
|
||||
.map((b: any) => Number(b.articleId ?? b.id ?? b.article?.id))
|
||||
.filter((x) => !isNaN(x))
|
||||
);
|
||||
|
||||
setBookmarkedIds(ids);
|
||||
} catch (err) {
|
||||
console.error("Gagal memuat bookmark user:", err);
|
||||
setBookmarkedIds(new Set());
|
||||
}
|
||||
};
|
||||
|
||||
fetchBookmarks();
|
||||
}, [userId]); // ← otomatis re-fetch kalau cookie user berubah
|
||||
|
||||
return (
|
||||
<section className="max-w-[1350px] mx-auto px-4">
|
||||
<div className="flex flex-col lg:flex-row gap-6 py-6">
|
||||
{data.length > 0 && (
|
||||
<Card
|
||||
key={data[0].id}
|
||||
item={data[0]}
|
||||
isBig
|
||||
isInitiallyBookmarked={bookmarkedIds.has(Number(data[0].id))}
|
||||
onSaved={(id) =>
|
||||
setBookmarkedIds((prev) => new Set([...prev, Number(id)]))
|
||||
}
|
||||
onRemoved={(id) =>
|
||||
setBookmarkedIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.delete(Number(id));
|
||||
return next;
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
@ -152,6 +152,13 @@ export default function Header() {
|
|||
onSaved={(id) =>
|
||||
setBookmarkedIds((prev) => new Set([...prev, Number(id)]))
|
||||
}
|
||||
onRemoved={(id) =>
|
||||
setBookmarkedIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.delete(Number(id));
|
||||
return next;
|
||||
})
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -174,11 +181,13 @@ function Card({
|
|||
isBig = false,
|
||||
isInitiallyBookmarked = false,
|
||||
onSaved,
|
||||
onRemoved,
|
||||
}: {
|
||||
item: any;
|
||||
isBig?: boolean;
|
||||
isInitiallyBookmarked?: boolean;
|
||||
onSaved?: (id: number) => void;
|
||||
onRemoved?: (id: number) => void;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
|
@ -204,9 +213,8 @@ function Card({
|
|||
}
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
const handleToggleBookmark = async () => {
|
||||
const roleId = Number(getCookiesDecrypt("urie"));
|
||||
|
||||
if (!roleId || isNaN(roleId)) {
|
||||
MySwal.fire({
|
||||
icon: "warning",
|
||||
|
|
@ -226,26 +234,23 @@ function Card({
|
|||
MySwal.fire({
|
||||
icon: "error",
|
||||
title: "Gagal",
|
||||
text: "Gagal menyimpan artikel.",
|
||||
text: "Gagal memperbarui bookmark.",
|
||||
confirmButtonColor: "#d33",
|
||||
});
|
||||
} else {
|
||||
setIsBookmarked(true);
|
||||
onSaved?.(item.id);
|
||||
// ✅ Toggle berhasil di server
|
||||
const nowBookmarked = !isBookmarked;
|
||||
setIsBookmarked(nowBookmarked);
|
||||
|
||||
// 🔹 Simpan ke localStorage
|
||||
const saved = localStorage.getItem("bookmarkedIds");
|
||||
const newSet = new Set<number>(saved ? JSON.parse(saved) : []);
|
||||
newSet.add(Number(item.id));
|
||||
localStorage.setItem(
|
||||
"bookmarkedIds",
|
||||
JSON.stringify(Array.from(newSet))
|
||||
);
|
||||
if (nowBookmarked) onSaved?.(item.id);
|
||||
else onRemoved?.(item.id);
|
||||
|
||||
MySwal.fire({
|
||||
icon: "success",
|
||||
title: "Berhasil",
|
||||
text: "Artikel berhasil disimpan ke bookmark.",
|
||||
title: nowBookmarked ? "Disimpan!" : "Dihapus!",
|
||||
text: nowBookmarked
|
||||
? "Artikel berhasil disimpan ke bookmark."
|
||||
: "Artikel dihapus dari bookmark.",
|
||||
confirmButtonColor: "#3085d6",
|
||||
timer: 1500,
|
||||
showConfirmButton: false,
|
||||
|
|
@ -321,26 +326,24 @@ function Card({
|
|||
|
||||
<div className="flex justify-between items-center pt-2">
|
||||
<div className="flex gap-2 text-gray-500">
|
||||
<ThumbsUp
|
||||
size={18}
|
||||
className="cursor-pointer hover:text-[#F60100]"
|
||||
/>
|
||||
<ThumbsDown
|
||||
size={18}
|
||||
className="cursor-pointer hover:text-red-600"
|
||||
/>
|
||||
<ThumbsUp size={18} className="cursor-pointer hover:text-[#F60100]" />
|
||||
<ThumbsDown size={18} className="cursor-pointer hover:text-red-600" />
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={handleSave}
|
||||
disabled={isSaving || isBookmarked}
|
||||
onClick={handleToggleBookmark}
|
||||
disabled={isSaving}
|
||||
className={`text-sm px-3 py-1 rounded-md transition-all duration-200 ${
|
||||
isBookmarked
|
||||
? "bg-gray-400 text-white cursor-not-allowed"
|
||||
? "bg-gray-400 text-white hover:bg-gray-500"
|
||||
: "bg-[#F60100] text-white hover:bg-[#c90000]"
|
||||
}`}
|
||||
>
|
||||
{isSaving ? "Saving..." : isBookmarked ? "Saved" : "Save"}
|
||||
{isSaving
|
||||
? "Saving..."
|
||||
: isBookmarked
|
||||
? "Saved"
|
||||
: "Save"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -348,3 +351,358 @@ function Card({
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// "use client";
|
||||
|
||||
// import Image from "next/image";
|
||||
// import Link from "next/link";
|
||||
// import { ThumbsUp, ThumbsDown } from "lucide-react";
|
||||
// import { useEffect, useState } from "react";
|
||||
// import { useParams, useRouter } from "next/navigation";
|
||||
// import Swal from "sweetalert2";
|
||||
// import withReactContent from "sweetalert2-react-content";
|
||||
// import { listData, listArticles } from "@/service/landing/landing";
|
||||
// import { getCookiesDecrypt } from "@/lib/utils";
|
||||
// import { toggleBookmark, getBookmarkSummaryForUser } from "@/service/content";
|
||||
|
||||
// export default function Header() {
|
||||
// const [data, setData] = useState<any[]>([]);
|
||||
// const [bookmarkedIds, setBookmarkedIds] = useState<Set<number>>(new Set());
|
||||
// const router = useRouter();
|
||||
// const params = useParams();
|
||||
// const MySwal = withReactContent(Swal);
|
||||
|
||||
// // Get slug from URL params
|
||||
// const slug = params?.slug as string;
|
||||
|
||||
// useEffect(() => {
|
||||
// const fetchData = async () => {
|
||||
// try {
|
||||
// // 🔹 Ambil artikel
|
||||
// const response = await listArticles(
|
||||
// 1,
|
||||
// 5,
|
||||
// undefined,
|
||||
// undefined,
|
||||
// undefined,
|
||||
// "createdAt",
|
||||
// slug
|
||||
// );
|
||||
|
||||
// let articlesData: any[] = [];
|
||||
|
||||
// if (response?.error) {
|
||||
// // fallback ke API lama
|
||||
// const fallbackResponse = await listData(
|
||||
// "",
|
||||
// "",
|
||||
// "",
|
||||
// 5,
|
||||
// 0,
|
||||
// "createdAt",
|
||||
// "",
|
||||
// "",
|
||||
// ""
|
||||
// );
|
||||
// articlesData = fallbackResponse?.data?.data?.content || [];
|
||||
// } else {
|
||||
// articlesData = response?.data?.data || [];
|
||||
// }
|
||||
|
||||
// // 🔹 Transform agar seragam
|
||||
// const transformed = articlesData.map((article: any) => ({
|
||||
// id: article.id,
|
||||
// title: article.title,
|
||||
// categoryName:
|
||||
// article.categoryName ||
|
||||
// (article.categories && article.categories[0]?.title) ||
|
||||
// "",
|
||||
// createdAt: article.createdAt,
|
||||
// smallThumbnailLink: article.thumbnailUrl,
|
||||
// fileTypeId: article.typeId,
|
||||
// clientName: article.clientName,
|
||||
// categories: article.categories,
|
||||
// label:
|
||||
// article.typeId === 1
|
||||
// ? "Image"
|
||||
// : article.typeId === 2
|
||||
// ? "Video"
|
||||
// : article.typeId === 3
|
||||
// ? "Text"
|
||||
// : article.typeId === 4
|
||||
// ? "Audio"
|
||||
// : "",
|
||||
// }));
|
||||
|
||||
// setData(transformed);
|
||||
|
||||
// const roleId = Number(getCookiesDecrypt("urie"));
|
||||
// if (roleId && !isNaN(roleId)) {
|
||||
// // const saved = localStorage.getItem("bookmarkedIds");
|
||||
// const userId = getCookiesDecrypt("uie");
|
||||
// const localKey = `bookmarkedIds_${userId || "guest"}`;
|
||||
// const saved = localStorage.getItem(localKey);
|
||||
|
||||
// let localSet = new Set<number>();
|
||||
// if (saved) {
|
||||
// localSet = new Set(JSON.parse(saved));
|
||||
// setBookmarkedIds(localSet);
|
||||
// }
|
||||
|
||||
// const res = await getBookmarkSummaryForUser();
|
||||
// const bookmarks =
|
||||
// res?.data?.data?.recentBookmarks ||
|
||||
// res?.data?.data?.bookmarks ||
|
||||
// res?.data?.data ||
|
||||
// [];
|
||||
|
||||
// const ids = new Set<number>(
|
||||
// (Array.isArray(bookmarks) ? bookmarks : [])
|
||||
// .map((b: any) => Number(b.articleId ?? b.id ?? b.article?.id))
|
||||
// .filter((x) => !isNaN(x))
|
||||
// );
|
||||
|
||||
// const merged = new Set([...localSet, ...ids]);
|
||||
// setBookmarkedIds(merged);
|
||||
// localStorage.setItem(
|
||||
// "bookmarkedIds",
|
||||
// JSON.stringify(Array.from(merged))
|
||||
// );
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.error("Gagal memuat data:", error);
|
||||
// }
|
||||
// };
|
||||
|
||||
// fetchData();
|
||||
// }, []);
|
||||
|
||||
// // Simpan setiap kali state berubah
|
||||
// useEffect(() => {
|
||||
// if (bookmarkedIds.size > 0) {
|
||||
// localStorage.setItem(
|
||||
// "bookmarkedIds",
|
||||
// JSON.stringify(Array.from(bookmarkedIds))
|
||||
// );
|
||||
// }
|
||||
// }, [bookmarkedIds]);
|
||||
|
||||
// return (
|
||||
// <section className="max-w-[1350px] mx-auto px-4">
|
||||
// <div className="flex flex-col lg:flex-row gap-6 py-6">
|
||||
// {data.length > 0 && (
|
||||
// <Card
|
||||
// item={data[0]}
|
||||
// isBig
|
||||
// isInitiallyBookmarked={bookmarkedIds.has(Number(data[0].id))}
|
||||
// onSaved={(id) =>
|
||||
// setBookmarkedIds((prev) => new Set([...prev, Number(id)]))
|
||||
// }
|
||||
// />
|
||||
// )}
|
||||
|
||||
// <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 w-full">
|
||||
// {data.slice(1, 5).map((item) => (
|
||||
// <Card
|
||||
// key={item.id}
|
||||
// item={item}
|
||||
// isInitiallyBookmarked={bookmarkedIds.has(Number(item.id))}
|
||||
// onSaved={(id) =>
|
||||
// setBookmarkedIds((prev) => new Set([...prev, Number(id)]))
|
||||
// }
|
||||
// />
|
||||
// ))}
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <div className="relative w-full h-48 sm:h-64 md:h-80 lg:h-[460px] mt-4 rounded-xl">
|
||||
// <Image
|
||||
// src={"/PPS.png"}
|
||||
// alt={"pps"}
|
||||
// fill
|
||||
// className="object-cover rounded-xl"
|
||||
// />
|
||||
// </div>
|
||||
// </section>
|
||||
// );
|
||||
// }
|
||||
|
||||
// function Card({
|
||||
// item,
|
||||
// isBig = false,
|
||||
// isInitiallyBookmarked = false,
|
||||
// onSaved,
|
||||
// }: {
|
||||
// item: any;
|
||||
// isBig?: boolean;
|
||||
// isInitiallyBookmarked?: boolean;
|
||||
// onSaved?: (id: number) => void;
|
||||
// }) {
|
||||
// const router = useRouter();
|
||||
// const MySwal = withReactContent(Swal);
|
||||
// const [isSaving, setIsSaving] = useState(false);
|
||||
// const [isBookmarked, setIsBookmarked] = useState(isInitiallyBookmarked);
|
||||
|
||||
// useEffect(() => {
|
||||
// setIsBookmarked(isInitiallyBookmarked);
|
||||
// }, [isInitiallyBookmarked]);
|
||||
|
||||
// const getLink = () => {
|
||||
// switch (item?.fileTypeId) {
|
||||
// case 1:
|
||||
// return `/content/image/detail/${item?.id}`;
|
||||
// case 2:
|
||||
// return `/content/video/detail/${item?.id}`;
|
||||
// case 3:
|
||||
// return `/content/text/detail/${item?.id}`;
|
||||
// case 4:
|
||||
// return `/content/audio/detail/${item?.id}`;
|
||||
// default:
|
||||
// return "#";
|
||||
// }
|
||||
// };
|
||||
|
||||
// const handleSave = async () => {
|
||||
// const roleId = Number(getCookiesDecrypt("urie"));
|
||||
|
||||
// if (!roleId || isNaN(roleId)) {
|
||||
// MySwal.fire({
|
||||
// icon: "warning",
|
||||
// title: "Login diperlukan",
|
||||
// text: "Silakan login terlebih dahulu untuk menyimpan artikel.",
|
||||
// confirmButtonText: "Login Sekarang",
|
||||
// confirmButtonColor: "#d33",
|
||||
// }).then(() => router.push("/auth"));
|
||||
// return;
|
||||
// }
|
||||
|
||||
// try {
|
||||
// setIsSaving(true);
|
||||
// const res = await toggleBookmark(item.id);
|
||||
|
||||
// if (res?.error) {
|
||||
// MySwal.fire({
|
||||
// icon: "error",
|
||||
// title: "Gagal",
|
||||
// text: "Gagal menyimpan artikel.",
|
||||
// confirmButtonColor: "#d33",
|
||||
// });
|
||||
// } else {
|
||||
// setIsBookmarked(true);
|
||||
// onSaved?.(item.id);
|
||||
|
||||
// // 🔹 Simpan ke localStorage
|
||||
// const saved = localStorage.getItem("bookmarkedIds");
|
||||
// const newSet = new Set<number>(saved ? JSON.parse(saved) : []);
|
||||
// newSet.add(Number(item.id));
|
||||
// localStorage.setItem(
|
||||
// "bookmarkedIds",
|
||||
// JSON.stringify(Array.from(newSet))
|
||||
// );
|
||||
|
||||
// MySwal.fire({
|
||||
// icon: "success",
|
||||
// title: "Berhasil",
|
||||
// text: "Artikel berhasil disimpan ke bookmark.",
|
||||
// confirmButtonColor: "#3085d6",
|
||||
// timer: 1500,
|
||||
// showConfirmButton: false,
|
||||
// });
|
||||
// }
|
||||
// } catch (err) {
|
||||
// console.error("Toggle bookmark error:", err);
|
||||
// MySwal.fire({
|
||||
// icon: "error",
|
||||
// title: "Kesalahan",
|
||||
// text: "Terjadi kesalahan saat menyimpan artikel.",
|
||||
// confirmButtonColor: "#d33",
|
||||
// });
|
||||
// } finally {
|
||||
// setIsSaving(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <div>
|
||||
// <div
|
||||
// className={`rounded-xl overflow-hidden shadow hover:shadow-lg transition-all bg-white ${
|
||||
// isBig
|
||||
// ? "w-full lg:max-w-[670px] lg:min-h-[680px]"
|
||||
// : "w-full h-[350px] md:h-[330px]"
|
||||
// }`}
|
||||
// >
|
||||
// <div
|
||||
// className={`relative ${
|
||||
// isBig ? "aspect-[3/2] lg:h-[525px]" : "aspect-video"
|
||||
// } w-full`}
|
||||
// >
|
||||
// <Link href={getLink()}>
|
||||
// <Image
|
||||
// src={item.smallThumbnailLink || "/contributor.png"}
|
||||
// alt={item.title}
|
||||
// fill
|
||||
// className="object-cover"
|
||||
// />
|
||||
// </Link>
|
||||
// </div>
|
||||
|
||||
// <div className="p-4 space-y-2">
|
||||
// <div className="flex items-center gap-2 text-xs font-semibold flex-wrap">
|
||||
// <span className="bg-emerald-600 text-white px-2 py-0.5 rounded">
|
||||
// {item.clientName}
|
||||
// </span>
|
||||
// <span className="text-orange-600">
|
||||
// {item.categories?.map((cat: any) => cat.title).join(", ")}
|
||||
// </span>
|
||||
// </div>
|
||||
|
||||
// <div className="text-xs text-gray-500">
|
||||
// {new Date(item.createdAt)
|
||||
// .toLocaleString("id-ID", {
|
||||
// day: "2-digit",
|
||||
// month: "short",
|
||||
// year: "numeric",
|
||||
// hour: "2-digit",
|
||||
// minute: "2-digit",
|
||||
// hour12: false,
|
||||
// timeZone: "Asia/Jakarta",
|
||||
// })
|
||||
// .replace(".", ":")}{" "}
|
||||
// WIB
|
||||
// </div>
|
||||
|
||||
// <Link href={getLink()}>
|
||||
// <h3 className="text-sm font-semibold leading-snug line-clamp-2">
|
||||
// {item.title}
|
||||
// </h3>
|
||||
// </Link>
|
||||
|
||||
// <div className="flex justify-between items-center pt-2">
|
||||
// <div className="flex gap-2 text-gray-500">
|
||||
// <ThumbsUp
|
||||
// size={18}
|
||||
// className="cursor-pointer hover:text-[#F60100]"
|
||||
// />
|
||||
// <ThumbsDown
|
||||
// size={18}
|
||||
// className="cursor-pointer hover:text-red-600"
|
||||
// />
|
||||
// </div>
|
||||
|
||||
// <button
|
||||
// onClick={handleSave}
|
||||
// disabled={isSaving || isBookmarked}
|
||||
// className={`text-sm px-3 py-1 rounded-md transition-all duration-200 ${
|
||||
// isBookmarked
|
||||
// ? "bg-gray-400 text-white cursor-not-allowed"
|
||||
// : "bg-[#F60100] text-white hover:bg-[#c90000]"
|
||||
// }`}
|
||||
// >
|
||||
// {isSaving ? "Saving..." : isBookmarked ? "Saved" : "Save"}
|
||||
// </button>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
|
|
|||
Loading…
Reference in New Issue