feat:merge main

This commit is contained in:
Anang Yusman 2025-04-24 23:58:20 +08:00
commit 72bee46ec5
29 changed files with 252 additions and 279 deletions

View File

@ -16,6 +16,7 @@ import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
import withReactContent from "sweetalert2-react-content";
import Swal from "sweetalert2";
import parse from "html-react-parser";
import { postActivityLog } from "@/service/content/content";
const DetailAudio = () => {
@ -47,6 +48,7 @@ const DetailAudio = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -131,8 +133,7 @@ const DetailAudio = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -20,6 +20,7 @@ import { Button } from "@/components/ui/button";
import { useSearchParams } from "next/navigation";
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
import parse from "html-react-parser";
import { postActivityLog } from "@/service/content/content";
const DetailDocument = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
@ -59,6 +60,7 @@ const DetailDocument = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -151,8 +153,7 @@ const DetailDocument = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -17,6 +17,7 @@ import withReactContent from "sweetalert2-react-content";
import Swal from "sweetalert2";
import { useSearchParams } from "next/navigation";
import parse from "html-react-parser";
import { postActivityLog } from "@/service/content/content";
const DetailInfo = () => {
const MySwal = withReactContent(Swal);
@ -57,6 +58,7 @@ const DetailInfo = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -155,8 +157,7 @@ const DetailInfo = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
function addDefaultProfile(ev: any) {

View File

@ -20,7 +20,8 @@ const page = () => {
<div>
<NavbarKaltara />
<HeaderBannerKaltara />
<SearchSectionKaltara />
{/* <SearchSectionKaltara /> */}
<WelcomePolda />
<LatestContentKaltara group="polda" type="latest" />
<LatestContentKaltara group="polda" type="popular" />
<ContentCategory group="polda" />

View File

@ -11,6 +11,7 @@ import { Textarea } from "@/components/ui/textarea";
import { getCookiesDecrypt } from "@/lib/utils";
import { close, error, loading } from "@/config/swal";
import { useToast } from "@/components/ui/use-toast";
import { postActivityLog } from "@/service/content/content";
const DetailVideo = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
@ -34,6 +35,7 @@ const DetailVideo = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -126,8 +128,7 @@ const DetailVideo = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -160,6 +160,7 @@ import parse from "html-react-parser";
import { Skeleton } from "@/components/ui/skeleton";
import { useTranslations } from "next-intl";
import Image from "next/image";
import { postActivityLog } from "@/service/content/content";
interface Size {
label: string;
@ -215,6 +216,7 @@ const DetailInfo = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -333,8 +335,7 @@ const DetailInfo = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -11,6 +11,7 @@ import { useToast } from "@/components/ui/use-toast";
import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing";
import { getCookiesDecrypt } from "@/lib/utils";
import { close, error, loading } from "@/config/swal";
import { postActivityLog } from "@/service/content/content";
const DetailAudio = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
@ -35,6 +36,7 @@ const DetailAudio = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -119,8 +121,7 @@ const DetailAudio = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -10,6 +10,7 @@ import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/
import { close, error, loading } from "@/config/swal";
import { useToast } from "@/components/ui/use-toast";
import { Link, useRouter } from "@/i18n/routing";
import { postActivityLog } from "@/service/content/content";
const DetailDocument = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
@ -35,6 +36,7 @@ const DetailDocument = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -127,8 +129,7 @@ const DetailDocument = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -10,6 +10,7 @@ import { getCookiesDecrypt } from "@/lib/utils";
import { close, error, loading } from "@/config/swal";
import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing";
import { Link, useRouter } from "@/i18n/routing";
import { postActivityLog } from "@/service/content/content";
const DetailInfo = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
@ -35,6 +36,7 @@ const DetailInfo = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -127,7 +129,7 @@ const DetailInfo = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
await postActivityLog(data);
// console.log(response);
}

View File

@ -11,6 +11,7 @@ import { Textarea } from "@/components/ui/textarea";
import { getCookiesDecrypt } from "@/lib/utils";
import { close, error, loading } from "@/config/swal";
import { useToast } from "@/components/ui/use-toast";
import { postActivityLog } from "@/service/content/content";
const DetailVideo = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
@ -34,6 +35,7 @@ const DetailVideo = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -126,8 +128,7 @@ const DetailVideo = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
postActivityLog(data);
}
const handleDownload = () => {

View File

@ -21,6 +21,7 @@ import { checkMaliciousText, formatDateToIndonesian, getPublicLocaleTimestamp }
import parse from "html-react-parser";
import $ from "jquery";
import { useTranslations } from "next-intl";
import { postActivityLog } from "@/service/content/content";
const formWaveSurferOptions = (ref: any) => ({
container: ref,
@ -74,6 +75,7 @@ const DetailAudio = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -163,8 +165,7 @@ const DetailAudio = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -19,6 +19,7 @@ import withReactContent from "sweetalert2-react-content";
import Swal from "sweetalert2";
import parse from "html-react-parser";
import { useTranslations } from "next-intl";
import { postActivityLog } from "@/service/content/content";
const DetailDocument = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
@ -58,6 +59,7 @@ const DetailDocument = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -161,8 +163,7 @@ const DetailDocument = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -37,6 +37,7 @@ import parse from "html-react-parser";
import { Skeleton } from "@/components/ui/skeleton";
import { useTranslations } from "next-intl";
import Image from "next/image";
import { postActivityLog } from "@/service/content/content";
interface Size {
label: string;
@ -96,6 +97,7 @@ const DetailInfo = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -214,8 +216,7 @@ const DetailInfo = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -21,6 +21,7 @@ import Swal from "sweetalert2";
import parse from "html-react-parser";
import { useTranslations } from "next-intl";
import Image from "next/image";
import { postActivityLog } from "@/service/content/content";
interface Size {
label: string;
@ -62,6 +63,7 @@ const DetailVideo = () => {
useEffect(() => {
initFetch();
checkWishlist();
sendActivityLog(2);
}, []);
const initFetch = async () => {
@ -158,8 +160,7 @@ const DetailVideo = () => {
url: window.location.href,
};
// set activity
// const response = await postActivityLog(data, token);
// console.log(response);
await postActivityLog(data);
}
const handleDownload = () => {

View File

@ -13,6 +13,7 @@ import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server";
import DirectionProvider from "@/providers/direction-provider";
import AuthProvider from "@/providers/auth.provider";
import LoadScript from "@/utils/globals";
export const metadata: Metadata = {
title: "Media Hub | POLRI",
@ -34,6 +35,7 @@ export default async function RootLayout({
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet" />
<LoadScript />
</head>
<body className={`${inter.className} dashcode-app`}>
<NextIntlClientProvider messages={messages} locale={locale}>

View File

@ -1,7 +1,4 @@
import {
getCategoryData,
getPublicCategoryData,
} from "@/service/landing/landing";
import { getCategoryData, getPublicCategoryData } from "@/service/landing/landing";
import Link from "next/link";
import React, { useEffect, useState } from "react";
import { Button } from "../ui/button";
@ -10,6 +7,8 @@ import { useTranslations } from "next-intl";
import { usePathname } from "next/navigation";
import { useParams } from "next/navigation";
import Image from "next/image";
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "../ui/carousel";
import { useRouter } from "@/i18n/routing";
const ContentCategory = (props: { group?: string }) => {
const [categories, setCategories] = useState<any>();
@ -18,21 +17,16 @@ const ContentCategory = (props: { group?: string }) => {
const locale = params?.locale;
const poldaName = params?.polda_name;
const satkerName = params?.satker_name;
const router = useRouter();
let prefixPath = poldaName ? `/polda/${poldaName}` : satkerName ? `/satker/${satkerName}` : "/";
useEffect(() => {
initFetch();
}, []);
const initFetch = async () => {
const response = await getPublicCategoryData(
props.group == "mabes"
? ""
: props.group == "polda" && poldaName && String(poldaName)?.length > 1
? poldaName
: props.group == "satker" &&
satkerName &&
String(satkerName)?.length > 1
? "satker-" + satkerName
: "",
props.group == "mabes" ? "" : props.group == "polda" && poldaName && String(poldaName)?.length > 1 ? poldaName : props.group == "satker" && satkerName && String(satkerName)?.length > 1 ? "satker-" + satkerName : "",
"",
locale == "en" ? true : false
);
@ -58,16 +52,13 @@ const ContentCategory = (props: { group?: string }) => {
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
</svg>`;
const toBase64 = (str: string) =>
typeof window === "undefined"
? Buffer.from(str).toString("base64")
: window.btoa(str);
const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str));
return (
<div className="px-4 lg:px-24 py-10">
<Reveal>
<h2 className="bg-[#c03724] rounded-md p-3 w-fit text-white">
{/* {pathname?.split("/")[1] == "in" ? (
<h2 className="text-center text-xl lg:text-3xl font-bold text-[#bb3523] mb-4">
{pathname?.split("/")[1] == "in" ? (
<>
<span className="text-black dark:text-white">{t("category")}&nbsp;</span>
{t("content")}
@ -77,109 +68,53 @@ const ContentCategory = (props: { group?: string }) => {
<span className="text-black dark:text-white">{t("content")}&nbsp;</span>
{t("category")}
</>
)} */}
Kategori Konten
</h2>
{/* <div className="h-1 w-48 bg-[#bb3523] mx-auto mb-6 rounded"></div> */}
<div className="grid my-8 grid-cols-1 lg:grid-cols-4 gap-4">
{categories?.map((category: any, index: number) =>
!seeAllValue ? (
index < 4 ? (
// <Link key={category?.id} href={`all/filter?category=${category?.id}`} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
// <Image
// placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
// alt="category"
// width={2560}
// height={1440}
// src={category?.thumbnailLink}
// className="w-full lg:w-[315px] lg:h-[250px] h-40 object-cover group-hover:scale-110 transition-transform duration-300"
// />
// <div className="absolute bottom-5 left-0 right-16 bg-transparent backdrop-blur-md text-white p-4 border-l-2 border-[#bb3523]">
// <h3 className="text-sm font-semibold truncate">{category?.name}</h3>
// </div>
// </Link>
<Link
key={category?.id}
href={`all/filter?category=${category?.id}`}
className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg"
>
{/* Gambar */}
<Image
placeholder={`data:image/svg+xml;base64,${toBase64(
shimmer(700, 475)
)}`}
alt="category"
width={2560}
height={1440}
src={category?.thumbnailLink}
className="w-full lg:h-[250px] h-40 object-cover group-hover:scale-110 transition-transform duration-300"
/>
{/* Overlay gelap */}
<div className="absolute inset-0 bg-black bg-opacity-25 group-hover:bg-opacity-35 transition-all duration-300 rounded-md"></div>
{/* Judul */}
<div className="absolute bottom-5 left-0 right-16 bg-transparent backdrop-blur-md text-white p-4 border-l-2 border-[#bb3523] z-10 group-hover:scale-x-150 origin-left">
<h3 className="text-sm font-semibold truncate">
{category?.name}
</h3>
</div>
</Link>
) : (
""
)
) : (
// <Link key={category?.id} href={`all/filter?category=${category?.id}`} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
// <Image
// placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
// alt="category"
// width={2560}
// height={1440}
// src={category?.thumbnailLink}
// className="w-fulllg:w-[315px] lg:h-[250px] h-40 object-cover group-hover:scale-110 transition-transform duration-300"
// />
// <div className="absolute bottom-5 left-0 right-16 bg-transparent backdrop-blur-md text-white p-4 border-l-2 border-[#bb3523]">
// <h3 className="text-sm font-semibold truncate">{category?.name}</h3>
// </div>
// </Link>
<Link
key={category?.id}
href={`all/filter?category=${category?.id}`}
className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg"
>
{/* Gambar */}
<Image
placeholder={`data:image/svg+xml;base64,${toBase64(
shimmer(700, 475)
)}`}
alt="category"
width={2560}
height={1440}
src={category?.thumbnailLink}
className="w-full lg:h-[250px] h-40 object-cover group-hover:scale-110 transition-transform duration-300"
/>
{/* Overlay Gelap */}
<div className="absolute inset-0 bg-black bg-opacity-25 group-hover:bg-opacity-35 transition-all duration-300"></div>
{/* Judul */}
<div className="absolute bottom-5 left-0 right-16 bg-transparent backdrop-blur-md text-white p-4 border-l-2 border-[#bb3523] z-10">
<h3 className="text-sm font-semibold truncate">
{category?.name}
</h3>
</div>
</Link>
)
)}
</h2>
<div className="h-1 w-52 bg-[#bb3523] mx-auto mb-6 rounded"></div>
<div className="">
<Carousel className="w-full max-w-full">
<CarouselContent>
{categories?.map((category: any) => (
<CarouselItem key={category?.id} className="md:basis-1/2 lg:basis-1/3">
<Link href={`all/filter?category=${category?.id}`} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg block">
{/* Gambar */}
<Image
placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
alt="category"
width={2560}
height={1440}
src={category?.thumbnailLink}
className="w-full lg:h-[250px] h-40 object-cover group-hover:scale-110 transition-transform duration-300"
/>
{/* Overlay gelap */}
<div className="absolute inset-0 bg-black bg-opacity-25 group-hover:bg-opacity-35 transition-all duration-300 rounded-md"></div>
{/* Judul */}
<div className="absolute bottom-5 left-0 right-16 bg-transparent backdrop-blur-md text-white p-4 border-l-2 border-[#bb3523] z-10 group-hover:scale-x-150 origin-left">
<h3 className="text-sm font-semibold truncate">{category?.name}</h3>
</div>
</Link>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="-ml-0 lg:-ml-7" />
<CarouselNext className="-mr-0 lg:-mr-7" />
</Carousel>
</div>
<div className="flex items-center flex-row justify-center">
<Button
onClick={() => setSeeAllValue(!seeAllValue)}
className="bg-white hover:bg-[#bb3523] text-[#bb3523] hover:text-white border-2 border-[#bb3523]"
>
{/* <div className="flex items-center flex-row justify-center">
<Button onClick={() => setSeeAllValue(!seeAllValue)} className="bg-white hover:bg-[#bb3523] text-[#bb3523] hover:text-white border-2 border-[#bb3523]">
{seeAllValue ? t("seeLess") : t("seeMore")}
</Button>
</div> */}
<div className="flex items-center flex-row justify-center mt-7">
<div
// onClick={() => router.push(prefixPath + `/${selectedTab}/filter?sortBy=${props.type}`)}
className="cursor-pointer border text-[#bb3523] rounded-lg text-sm lg:text-md px-4 py-1 border-[#bb3523]"
>
{t("seeAll")}
</div>
</div>
</Reveal>
</div>

View File

@ -1,17 +1,72 @@
import { Button } from "@/components/ui/button";
import { Link } from "@/i18n/routing";
import { Icon } from "@iconify/react/dist/iconify.js";
import Image from "next/image";
import React from "react";
type Channel = {
name: string;
logo: string;
url: string;
};
const channels: Channel[] = [
{
name: "Divisi Humas Polri",
logo: "/assets/portal-humas.png",
url: "https://portal.humas.polri.go.id/",
},
{
name: "Media Hub",
logo: "/assets/mediahub-logo.gif",
url: "/polda/kaltara",
},
{
name: "SPIT",
logo: "/assets/logo-spit.png",
url: "https://spit.humas.polri.go.id/",
},
{
name: "Polri TV",
logo: "/assets/polriTv.png",
url: "https://tvradio.polri.go.id/",
},
{
name: "TBNews",
logo: "/assets/img/logo-tbn.png",
url: "/tbnews/polda-kaltara",
},
{
name: "INP",
logo: "/assets/logo-inp.png",
url: "https://inp.polri.go.id/",
},
];
const ContactUsKaltara = () => {
return (
<div className="bg-[#E7E7E7] h-full lg:h-[300px] text-black px-4 lg:px-20 mb-10">
<div className="container mx-auto py-8">
<div className="min-h-[300px] lg:min-h-[300px] text-black px-4 lg:px-20 pb-20">
<div className="w-full px-4 py-4 bg-white">
<h2 className="text-center text-xl md:text-2xl font-semibold mb-6">Channel Divisi Humas Polri</h2>
{/* Mobile version pakai grid, Desktop pakai flex */}
<div className="grid grid-cols-3 gap-4 sm:flex sm:justify-between sm:flex-wrap">
{channels.map((channel, index) => (
<Link key={index} href={channel.url} passHref>
<div key={index} className="w-16 h-16 sm:w-[170px] sm:h-[80px] relative mx-auto">
<Image src={channel.logo} alt={channel.name} width={1920} height={1080} className="object-contain w-full h-full" />
</div>
</Link>
))}
</div>
</div>
<div className="container mx-auto py-8 border-t-2 ">
<div className="flex flex-col md:flex-row justify-between items-start gap-4">
{/* Logo */}
<div className="flex flex-col items-center space-x-4">
<Image src="/assets/polda/logo-kontak.png" alt="" width={400} height={300} className="" />
<p className="text-[#bb3523] font-bold">Copyright @TribrataNews Kaltara</p>
<Image src="/assets/logo-humas-polri.png" alt="logo" width={1920} height={1080} className="h-[100px] lg:h-[200px] w-[100px] lg:w-[200px]" />
{/* <p className="text-[#bb3523] font-bold">Copyright @TribrataNews Kaltara</p> */}
</div>
{/* Contact Us */}
@ -100,6 +155,14 @@ const ContactUsKaltara = () => {
Index
</Link>
</div>
{/* login */}
<Link href="/auth">
<Button className="flex justify-center items-center bg-[#c03724] rounded-full gap-3 p-2 w-fit h-fit mt-4">
<Icon icon="material-symbols:lock" className="text-white" />
<p className="text-white">Kontributor Wilayah</p>
</Button>
</Link>
</div>
{/* Social Media */}

View File

@ -3,7 +3,7 @@ import { listData } from "@/service/landing/landing";
import { useParams } from "next/navigation";
import React, { useEffect, useState } from "react";
import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
import { formatDateToIndonesian, getPublicLocaleTimestamp, textEllipsis } from "@/utils/globals";
import { formatDateToIndonesian, getPublicLocaleTimestamp } from "@/utils/globals";
import { Icon } from "@iconify/react/dist/iconify.js";
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
import Image from "next/image";
@ -75,12 +75,12 @@ const HeaderBannerKaltara = () => {
<>
<Reveal>
{/* Header Left */}
<div className="flex flex-col lg:flex-row items-start justify-center gap-[25px] px-4 lg:px-0 py-4 w-auto mt-6">
<div className=" flex flex-col lg:flex-row items-start justify-center gap-[25px] px-4 lg:px-18 py-4 w-auto mt-6">
{isBannerLoading ? (
<div className="flex flex-col space-y-3 mx-auto w-full lg:w-2/3">
<Skeleton className="h-[310px] lg:h-[420px] rounded-xl" />
<div className="space-y-2">
<Skeleton className="h-4 w-[250px]" />
<Skeleton className=" h-4 w-[250px]" />
<Skeleton className="h-4 w-[200px]" />
</div>
</div>
@ -152,7 +152,7 @@ const HeaderBannerKaltara = () => {
</div>
</>
) : (
<ul className="py-4 lg:py-0 flex flex-row lg:flex-col gap-[20px] flex-nowrap w-[95vw] lg:w-auto overflow-x-auto">
<ul className="py-4 lg:py-0 flex flex-row lg:flex-col gap-[15px] flex-nowrap w-[95vw] lg:w-[380px] overflow-x-auto">
{content?.map((item: any) => (
<li key={item?.id} className="flex gap-4 flex-row lg:w-full bg-[#f8f8f8] p-[10px] rounded-lg">
<div className="flex-shrink-0 w-24 rounded-lg">
@ -161,7 +161,7 @@ const HeaderBannerKaltara = () => {
<div className="w-[280px] lg:w-auto">
<span className="text-[#bb3523] border border-[#bb3523] bg-white px-4 py-1 rounded-lg flex text-[8px] font-sans font-semibold uppercase w-fit">{item?.categoryName}</span>
<div onClick={() => router.push(prefixPath + `/image/detail/${item?.slug}`)} className="cursor-pointer">
<h3 className="text-base font-sans font-bold mt-2">{textEllipsis(item?.title, 30)}</h3>
<h3 className="text-[12px] font-sans font-bold mt-2">{item?.title}</h3>
</div>
<p className="text-[10px] flex flex-row items-center font-sans gap-1 text-gray-500 mt-1">
{formatDateToIndonesian(new Date(item?.createdAt))} {item?.timezone ? item?.timezone : "WIB"} |{" "}

View File

@ -6,7 +6,7 @@ import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious
import Image from "next/image";
import { Skeleton } from "@/components/ui/skeleton";
import { formatDateToIndonesian, secondToTimes } from "@/utils/globals";
import { useParams } from "next/navigation";
import { useParams, usePathname } from "next/navigation";
import { listData } from "@/service/landing/landing";
import { useRouter } from "@/i18n/routing";
import { Icon } from "@iconify/react/dist/iconify.js";
@ -23,6 +23,7 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
const [isBannerLoading, setIsBannerLoading] = useState(true);
const [centerPadding, setCenterPadding] = useState<any>();
const router = useRouter();
const pathname = usePathname();
const t = useTranslations("LandingPage");
let prefixPath = poldaName ? `/polda/${poldaName}` : satkerName ? `/satker/${satkerName}` : "/";
@ -73,9 +74,22 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
return (
<>
<Reveal>
<div className="px-4 lg:px-20 my-10">
<div className="bg-[#c03724] rounded-md p-3 w-fit text-white">Berita {props.type == "popular" ? "Terpopuler" : props.type == "latest" ? t("new") : "Serupa"}</div>
<div className="mx-auto w-full justify-center flex px-5 flex-col lg:flex-row gap-5 mb-4">
<div className="px-4 lg:px-24 my-10">
{/* <div className="bg-[#c03724] rounded-md p-3 w-fit text-white">Berita {props.type == "popular" ? "Terpopuler" : props.type == "latest" ? t("new") : "Serupa"}</div> */}
<div className="w-full justify-start flex flex-col lg:flex-row gap-20 mb-4">
<h2 className="flex items-center text-xl lg:text-2xl w-fit font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-white">
{pathname?.split("/")[1] == "in" ? (
<>
<span className="text-black ">{t("content")}</span>&nbsp;
{props.type == "popular" ? "Terpopuler" : props.type == "latest" ? t("new") : "Serupa"}
</>
) : (
<>
<span className="text-black ">{props.type == "popular" ? "Popular" : props.type == "latest" ? t("new") : "Serupa"}</span>&nbsp;
{t("content")}
</>
)}
</h2>
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
<TabsList className="grid grid-cols-2 lg:flex lg:flex-row">
<TabsTrigger
@ -130,46 +144,11 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
<div className="">
{selectedTab == "image" ? (
content?.length > 0 ? (
// <Carousel className="">
// <CarouselContent>
// {content?.map((image: any) => (
// <CarouselItem key={image?.id} className="basis-1/2 md:basis-1/3 lg:basis-1/4">
// <div onClick={() => router.push(prefixPath + `/video/detail/${image?.slug}`)} className="cursor-pointer relative group rounded-md overflow-hidden">
// {/* Gambar */}
// <Image
// placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
// alt="image"
// width={2560}
// height={1440}
// src={image?.thumbnailLink}
// className="w-full lg:w-[390px] h-48 md:h-56 lg:h-[490px] object-cover rounded-md"
// />
// {/* Kategori - Sekarang Berada di Atas */}
// <span className="absolute top-2 left-2 z-10 text-xs md:text-sm font-sans font-semibold uppercase px-2 py-1 bg-white bg-opacity-20 border border-[#c03724] text-[#c03724] rounded-md">{image?.categoryName}</span>
// {/* Overlay Konten (Informasi di Bawah) */}
// <div className="absolute bottom-0 left-0 right-0 p-4 bg-transparent rounded-md">
// {/* Judul */}
// <p className="text-white text-sm md:text-[20px] font-sans font-semibold mb-2">{image?.title}</p>
// {/* Info Tambahan */}
// {/* <p className="flex items-center text-xs md:text-sm text-white mt-1 gap-2">
// {formatDateToIndonesian(new Date(video?.createdAt))} {video?.timezone ? video?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {video?.clickCount}
// </p> */}
// </div>
// </div>
// </CarouselItem>
// ))}
// </CarouselContent>
// {/* <CarouselPrevious className="hover:bg-black" />
// <CarouselNext className="hover:bg-black -mr-6" /> */}
// </Carousel>
<Carousel className="">
<Carousel className="w-full mx-auto">
<CarouselContent>
{content?.map((image: any) => (
<CarouselItem key={image?.id} className="md:basis-1/3 lg:basis-1/4">
<div onClick={() => router.push(prefixPath + `/image/detail/${image?.slug}`)} className="cursor-pointer relative group rounded-md overflow-hidden">
<CarouselItem key={image?.id} className="md:basis-1/2 lg:basis-1/4">
<div onClick={() => router.push(prefixPath + `/image/detail/${image?.slug}`)} className="cursor-pointer relative group overflow-hidden shadow-md hover:shadow-lg">
{/* Gambar */}
<Image
placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
@ -177,23 +156,24 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
width={2560}
height={1440}
src={image?.thumbnailLink}
className="w-full lg:w-[400px] h-48 md:h-56 lg:h-[490px] object-cover rounded-md"
className="w-full rounded-lg h-48 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300"
/>
{/* Overlay gelap */}
<div className="absolute inset-0 bg-black bg-opacity-30 rounded-md"></div>
{/* Kategori */}
<span className="absolute top-2 left-2 z-10 text-xs md:text-sm font-sans font-semibold uppercase px-2 py-1 bg-white bg-opacity-20 border border-[#c03724] text-[#c03724] rounded-md">{image?.categoryName}</span>
{/* Konten Informasi */}
<div className="absolute bottom-0 left-0 right-0 p-4 z-10">
<p className="text-white text-sm md:text-[20px] font-sans font-semibold mb-2">{image?.title}</p>
<div className="absolute bottom-2 left-2 right-2 bg-gray-500/55 border-l-4 border-[#bb3523] rounded-lg backdrop-blur-sm text-white p-2">
<p className="text-sm lg:text-base mb-2 font-semibold h-6 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{image?.title}</p>
<p className="flex flex-row items-center text-[10px] gap-2">
{formatDateToIndonesian(new Date(image?.createdAt))} {image?.timezone ? image?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {image.clickCount}{" "}
</p>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="-ml-0 lg:-ml-7" />
<CarouselNext className="-mr-0 lg:-mr-7" />
</Carousel>
) : (
<p className="flex items-center justify-center">
@ -202,10 +182,10 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
)
) : selectedTab == "audio" ? (
content?.length > 0 ? (
<Carousel className="w-full max-w-7xl mx-auto">
<Carousel className="w-full mx-auto">
<CarouselContent>
{content?.map((audio: any) => (
<CarouselItem key={audio?.id} className="md:basis-1/2 lg:basis-1/3">
<CarouselItem key={audio?.id} className="md:basis-1/2 lg:basis-1/4">
<div className="flex flex-row gap-6">
<div onClick={() => router.push(prefixPath + `/audio/detail/${audio?.slug}`)} className="cursor-pointer flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 shadow-md rounded-lg p-4 gap-4 w-full">
<div className="flex items-center justify-center bg-red-500 text-white rounded-lg w-24 h-8 lg:h-16">
@ -230,8 +210,8 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
</CarouselItem>
))}
</CarouselContent>
{/* <CarouselPrevious />
<CarouselNext /> */}
<CarouselPrevious />
<CarouselNext />
</Carousel>
) : (
<p className="flex items-center justify-center">
@ -240,46 +220,11 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
)
) : selectedTab == "video" ? (
content?.length > 0 ? (
// <Carousel className="">
// <CarouselContent>
// {content?.map((video: any) => (
// <CarouselItem key={video?.id} className=" md:basis-1/3 lg:basis-1/4">
// <div onClick={() => router.push(prefixPath + `/video/detail/${video?.slug}`)} className="cursor-pointer relative group rounded-lg overflow-hidden">
// {/* Gambar */}
// <Image
// placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
// alt="video"
// width={2560}
// height={1440}
// src={video?.thumbnailLink}
// className="w-full lg:w-[315px] h-48 md:h-56 lg:h-[490px] object-cover rounded-lg transition-transform duration-300"
// />
// {/* Kategori - Sekarang Berada di Atas */}
// <span className="absolute top-2 left-2 z-10 text-xs md:text-sm font-sans font-semibold uppercase px-2 py-1 bg-white bg-opacity-20 border border-[#c03724] text-[#c03724] rounded-md">{video?.categoryName}</span>
// {/* Overlay Konten (Informasi di Bawah) */}
// <div className="absolute bottom-0 left-0 right-0 p-4 bg-transparent rounded-lg">
// {/* Judul */}
// <p className="text-white text-sm md:text-[20px] font-sans font-semibold mb-2">{video?.title}</p>
// {/* Info Tambahan */}
// {/* <p className="flex items-center text-xs md:text-sm text-white mt-1 gap-2">
// {formatDateToIndonesian(new Date(video?.createdAt))} {video?.timezone ? video?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {video?.clickCount}
// </p> */}
// </div>
// </div>
// </CarouselItem>
// ))}
// </CarouselContent>
// {/* <CarouselPrevious className="hover:bg-black" />
// <CarouselNext className="hover:bg-black -mr-6" /> */}
// </Carousel>
<Carousel className="">
<Carousel className="w-full mx-auto">
<CarouselContent>
{content?.map((video: any) => (
<CarouselItem key={video?.id} className="md:basis-1/3 lg:basis-1/4">
<div onClick={() => router.push(prefixPath + `/video/detail/${video?.slug}`)} className="cursor-pointer relative group rounded-md overflow-hidden">
<CarouselItem key={video?.id} className="md:basis-1/2 lg:basis-1/4">
<div onClick={() => router.push(prefixPath + `/video/detail/${video?.slug}`)} className="cursor-pointer relative group overflow-hidden shadow-md hover:shadow-lg">
{/* Gambar */}
<Image
placeholder={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
@ -287,23 +232,24 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
width={2560}
height={1440}
src={video?.thumbnailLink}
className="w-full lg:w-[400px] h-48 md:h-56 lg:h-[490px] object-cover rounded-md"
className="w-full rounded-lg h-48 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300"
/>
{/* Overlay Gelap */}
<div className="absolute inset-0 bg-black bg-opacity-30 rounded-lg"></div>
{/* Kategori */}
<span className="absolute top-2 left-2 z-10 text-xs md:text-sm font-sans font-semibold uppercase px-2 py-1 bg-white bg-opacity-20 border border-[#c03724] text-[#c03724] rounded-md">{video?.categoryName}</span>
{/* Overlay Konten (Judul) */}
<div className="absolute bottom-0 left-0 right-0 p-4 z-10">
<p className="text-white text-sm md:text-[20px] font-sans font-semibold mb-2 line-clamp-2">{video?.title}</p>
<div className="absolute bottom-2 left-2 right-2 bg-gray-500/55 border-l-4 border-[#bb3523] rounded-lg backdrop-blur-sm text-white p-2">
<p className="text-sm lg:text-base mb-2 font-semibold h-6 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{video?.title}</p>
<p className="flex flex-row items-center text-[10px] gap-2">
{formatDateToIndonesian(new Date(video?.createdAt))} {video?.timezone ? video?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {video.clickCount}{" "}
</p>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="-ml-0 lg:-ml-7" />
<CarouselNext className="-mr-0 lg:-mr-7" />
</Carousel>
) : (
<p className="flex items-center justify-center">
@ -311,10 +257,10 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
</p>
)
) : content.length > 0 ? (
<Carousel className="w-full max-w-7xl mx-auto">
<Carousel className="w-full mx-auto">
<CarouselContent>
{content?.map((text: any) => (
<CarouselItem key={text?.id} className="md:basis-1/2 lg:basis-1/3">
<CarouselItem key={text?.id} className="md:basis-1/2 lg:basis-1/4">
<div className="md:basis-1/2 lg:basis-1/3">
<div onClick={() => router.push(prefixPath + `/document/detail/${text?.slug}`)} className="flex flex-col bg-yellow-500 sm:flex-row items-center dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4">
<div className="flex items-center justify-center rounded-lg w-16 h-2 lg:h-16">
@ -346,8 +292,8 @@ const LatestContentKaltara = (props: { group: string; type: string }) => {
</CarouselItem>
))}
</CarouselContent>
{/* <CarouselPrevious />
<CarouselNext /> */}
<CarouselPrevious />
<CarouselNext />
</Carousel>
) : (
<p className="flex items-center justify-center">

View File

@ -136,8 +136,8 @@ const NavbarKaltara = () => {
</button>
<div className="hidden lg:flex items-center gap-5">
<Link href="/tbnews/polda-kaltara" className="text-white">
TBNews
<Link href="/tbnews/polda-kaltara">
<Image src="/assets/polda/logo-tbnews.png" alt="logo" width={1920} height={1080} className="w-[110px] h-[50px]" />
</Link>
<div className="flex items-center">
@ -174,14 +174,6 @@ const NavbarKaltara = () => {
{/* Dark Mode */}
<ThemeSwitcher />
{/* login */}
<Link href="/auth">
<Button className="hidden lg:flex justify-center items-center bg-white rounded-full gap-3 p-2 w-fit h-fit">
<Icon icon="material-symbols:lock" className="text-[#c03724]" />
<p className="text-[#c03724]">Login</p>
</Button>
</Link>
</div>
</div>
@ -278,7 +270,7 @@ const NavbarKaltara = () => {
<div className="flex lg:hidden flex-col items-center gap-1">
<div className="flex flex-row justify-between items-center gap-2">
<Link href="/tbnews/polda-kaltara" className="text-white">
TBNews
<Image src="/assets/polda/logo-tbnews.png" alt="logo" width={1920} height={1080} className="w-[100px] h-[40px]" />
</Link>
<div className="flex items-center">
@ -317,14 +309,6 @@ const NavbarKaltara = () => {
{/* Dark Mode */}
<ThemeSwitcher />
{/* login */}
<Link href="/auth">
<Button className="hidden lg:flex justify-center items-center bg-white rounded-full gap-3 p-2 w-fit h-fit">
<Icon icon="material-symbols:lock" className="text-[#c03724]" />
<p className="text-[#c03724]">Login</p>
</Button>
</Link>
</div>
</div>
</div>

View File

@ -1,8 +1,6 @@
import React, { useState } from "react";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
import { FiFile, FiImage, FiMusic, FiYoutube } from "react-icons/fi";
import { Icon } from "@iconify/react/dist/iconify.js";
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useRouter } from "@/i18n/routing";
import { useTranslations } from "next-intl";
@ -13,8 +11,8 @@ const SearchSection = () => {
const t = useTranslations("LandingPage");
return (
<section className="w-full py-8 px-4 ">
<div className="max-w-screen-xl mx-auto text-center">
<section className="w-full py-8 px-4 lg:px-24">
<div className="text-center">
{/* Heading */}
<h1 className="text-2xl md:text-3xl font-bold text-gray-800 dark:text-white">
<span className="text-[#bb3523] dark:text-white">{t("exploration")}</span> {t("and")} <span className="text-[#bb3523] dark:text-white">{t("download")}</span> {t("coverage")}{" "}

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
public/assets/logo-inp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
public/assets/logo-spit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,3 +1,4 @@
import { httpPost } from "../http-config/http-base-service";
import {
httpDeleteInterceptor,
httpGetInterceptor,
@ -225,3 +226,11 @@ export async function deleteSPIT(id: any) {
const url = `media/spit?id=${id}`;
return httpDeleteInterceptor(url);
}
export async function postActivityLog(data: any) {
const url = `activity`;
const headers = {
"content-type": "application/json",
};
return httpPost(url, headers, data);
}

View File

@ -7,6 +7,7 @@ import { getCsrfToken } from "../auth";
export async function httpPost(pathUrl: any, headers: any, data?: any) {
const resCsrf = await getCsrfToken();
const csrfToken = resCsrf?.data?.token;
const authToken = Cookies.get("access_token");
const defaultHeaders = {
"Content-Type": "application/json",
@ -16,6 +17,7 @@ export async function httpPost(pathUrl: any, headers: any, data?: any) {
...defaultHeaders,
...headers,
...(csrfToken ? { "X-XSRF-TOKEN": csrfToken } : {}),
...(authToken ? { "Authorization" : `Bearer ${authToken}`} : {}),
};
const response = await axiosBaseInstance

View File

@ -1,5 +1,8 @@
"use client";
import { format } from "date-fns";
import { id, tr } from "date-fns/locale";
import { useEffect } from "react";
export const generateLocalizedPath = (href: string, locale: string): string => {
if (href.startsWith(`/${locale}`)) {
@ -153,3 +156,19 @@ export const shimmer = (w: number, h: number) => `
</svg>`;
export const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str));
const LoadScript = () => {
useEffect(() => {
const script = document.createElement("script");
script.src = "https://cdn.userway.org/widget.js";
script.setAttribute("data-account", "X36s1DpjqB");
script.async = true;
document.head.appendChild(script);
return () => {
// Cleanup if needed
document.head.removeChild(script);
};
}, []);
return null; // Tidak perlu merender apa-apa
};
export default LoadScript;