Merge branch 'dev-restructure' of https://gitlab.com/hanifsalafi/web-humas-polri into prod

This commit is contained in:
Rama Priyanto 2025-06-16 19:35:33 +07:00
commit 2224237481
5 changed files with 163 additions and 40 deletions

View File

@ -410,7 +410,10 @@ export default function BannerHumasNew() {
<TwIcon size={20} /> <TwIcon size={20} />
</div> </div>
</Link> </Link>
<Link href="https://www.tiktok.com/@divhumas_polri" target="_blank"> <Link
href="https://tiktok.com/@divhumaspolriofficial"
target="_blank"
>
<div className="bg-white p-0.5 rounded-md"> <div className="bg-white p-0.5 rounded-md">
<TtIcon size={24} /> <TtIcon size={24} />
</div> </div>

View File

@ -156,8 +156,9 @@ export default function FooterNew(props: { margin?: boolean }) {
</p> </p>
<div className="flex flex-row gap-2"> <div className="flex flex-row gap-2">
<Link <Link
href="" href="https://apps.apple.com/id/app/polri-super-app/id1617509708"
className="flex flex-row p-1 border-1 border-black dark:border-white rounded-lg items-center" className="flex flex-row p-1 border-1 border-black dark:border-white rounded-lg items-center"
target="_blank"
> >
<LandingAppleIcon size={36} /> <LandingAppleIcon size={36} />
<div className="flex flex-col gap-0 leading-none font-light mr-1"> <div className="flex flex-col gap-0 leading-none font-light mr-1">
@ -166,8 +167,9 @@ export default function FooterNew(props: { margin?: boolean }) {
</div> </div>
</Link> </Link>
<Link <Link
href="" href=" https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi"
className="flex flex-row p-1 border-1 border-black dark:border-white rounded-lg items-center" className="flex flex-row p-1 border-1 border-black dark:border-white rounded-lg items-center"
target="_blank"
> >
<LandingPlayStoreIcon size={30} /> <LandingPlayStoreIcon size={30} />
<div className="flex flex-col gap-0 leading-none font-light mr-1"> <div className="flex flex-col gap-0 leading-none font-light mr-1">

View File

@ -15,7 +15,12 @@ import {
Calendar, Calendar,
Checkbox, Checkbox,
CheckboxGroup, CheckboxGroup,
CheckboxIcon,
Image, Image,
Modal,
ModalBody,
ModalContent,
ModalHeader,
Pagination, Pagination,
Popover, Popover,
PopoverContent, PopoverContent,
@ -24,13 +29,14 @@ import {
SelectItem, SelectItem,
SelectSection, SelectSection,
Skeleton, Skeleton,
useDisclosure,
} from "@heroui/react"; } from "@heroui/react";
import ApexChartColumn from "./chart/column-chart"; import ApexChartColumn from "./chart/column-chart";
import ApexChartDonut from "./chart/donut-chart"; import ApexChartDonut from "./chart/donut-chart";
import ApexChartLineArea from "./chart/line-area-chart"; import ApexChartLineArea from "./chart/line-area-chart";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import Link from "next/link"; import Link from "next/link";
import { useEffect, useState } from "react"; import { Fragment, useEffect, useState } from "react";
import { import {
getListArticle, getListArticle,
getListArticleAdminPage, getListArticleAdminPage,
@ -47,6 +53,7 @@ import {
textEllipsis, textEllipsis,
} from "@/utils/global"; } from "@/utils/global";
import { parseDate, getLocalTimeZone } from "@internationalized/date"; import { parseDate, getLocalTimeZone } from "@internationalized/date";
import { Input } from "@heroui/input";
type ArticleData = Article & { type ArticleData = Article & {
no: number; no: number;
@ -68,6 +75,8 @@ interface PostCount {
} }
export default function DashboardContainer() { export default function DashboardContainer() {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const username = Cookies.get("username"); const username = Cookies.get("username");
const fullname = Cookies.get("ufne"); const fullname = Cookies.get("ufne");
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
@ -75,6 +84,7 @@ export default function DashboardContainer() {
const [topPagespage, setTopPagesPage] = useState(1); const [topPagespage, setTopPagesPage] = useState(1);
const [topPagesTotalPage, setTopPagesTotalPage] = useState(1); const [topPagesTotalPage, setTopPagesTotalPage] = useState(1);
const [article, setArticle] = useState<ArticleData[]>([]); const [article, setArticle] = useState<ArticleData[]>([]);
const [selectedCategory, setSelectedCategory] = useState("polda");
const [analyticsView, setAnalyticView] = useState<string[]>([ const [analyticsView, setAnalyticView] = useState<string[]>([
"comment", "comment",
"view", "view",
@ -109,7 +119,9 @@ export default function DashboardContainer() {
const [postCount, setPostCount] = useState<PostCount[]>([]); const [postCount, setPostCount] = useState<PostCount[]>([]);
const [polresData, setPolresData] = useState<any>({}); const [polresData, setPolresData] = useState<any>({});
const [selectedAccordion, setSelectedAccordion] = useState<any>(new Set([])); const [selectedAccordion, setSelectedAccordion] = useState<any>(new Set([]));
const [recapArticleList, setRecapArticleList] = useState<any>([]);
const [timeValue, setTimeValue] = useState("--:--");
const [selectedUnit, setSelectedUnit] = useState("");
const roleId = Cookies.get("urie"); const roleId = Cookies.get("urie");
useEffect(() => { useEffect(() => {
@ -287,6 +299,21 @@ export default function DashboardContainer() {
} }
}; };
const openModalArticle = async (limit: number) => {
const req = {
limit: `${limit}`,
page: topPagespage,
search: "",
sort: "desc",
startDate: getDate(topContentDate.startDate),
endDate: getDate(topContentDate.endDate),
};
const res = await getTopArticles(req);
setRecapArticleList(getTableNumber(10, res.data?.data));
// setTopPagesTotalPage(res?.data?.meta?.totalPage);
onOpen();
};
return ( return (
<div className="px-2 lg:p-8 flex justify-center"> <div className="px-2 lg:p-8 flex justify-center">
<div className="w-full flex flex-col gap-6"> <div className="w-full flex flex-col gap-6">
@ -348,7 +375,7 @@ export default function DashboardContainer() {
<p className="font-semibold"> <p className="font-semibold">
Rekapitulasi Post Berita Polda/Polres Pada Website Rekapitulasi Post Berita Polda/Polres Pada Website
</p> </p>
<div className="w-[220px] flex flex-row gap-2 justify-between font-semibold"> <div className="w-[300px] flex flex-row gap-2 justify-between font-semibold items-center">
<Popover <Popover
placement="bottom" placement="bottom"
classNames={{ content: ["!bg-transparent", "p-0"] }} classNames={{ content: ["!bg-transparent", "p-0"] }}
@ -394,11 +421,54 @@ export default function DashboardContainer() {
/> />
</PopoverContent> </PopoverContent>
</Popover> </Popover>
<Input
type="time"
variant="bordered"
className="w-fit "
value={timeValue}
onValueChange={setTimeValue}
endContent={
<a>
<CheckboxIcon />
</a>
}
classNames={{
inputWrapper: [
"border-none rounded-lg !h-[30px] lg:h-[40px]",
"dark:group-data-[focused=false]:bg-transparent border-none",
],
}}
/>
</div> </div>
</div> </div>
<div className="flex flex-row border-b-1 gap-1 py-1"> <div className="flex flex-row border-b-1 gap-1 py-1 items-center">
<div className="w-[5%]">NO</div> <div className="w-[5%]">NO</div>
<div className="w-[50%] lg:w-[70%]">POLDA/POLRES</div> <div className="w-[50%] lg:w-[70%]">
{Number(roleId) < 3 ? (
<Select
variant="underlined"
className="max-w-xs border-none"
label=""
selectedKeys={[selectedCategory]}
classNames={{
innerWrapper: "!border-none",
mainWrapper: "!border-none",
trigger: "border-none",
}}
onChange={(e) =>
e.target.value !== ""
? setSelectedCategory(e.target.value)
: ""
}
>
<SelectItem key="polda">POLDA</SelectItem>
<SelectItem key="polres">POLRES</SelectItem>
<SelectItem key="satker">SATKER MABES</SelectItem>
</Select>
) : (
"POLDA/POLRES"
)}
</div>
<div className="w-[45%] lg:w-[25%] text-right"> <div className="w-[45%] lg:w-[25%] text-right">
JUMLAH POST BERITA JUMLAH POST BERITA
</div> </div>
@ -423,9 +493,9 @@ export default function DashboardContainer() {
<div className="w-[5%]">{list?.no}</div> <div className="w-[5%]">{list?.no}</div>
<div className="w-[85%]">{list?.userLevelName}</div> <div className="w-[85%]">{list?.userLevelName}</div>
<div <div
className={`w-[10%] text-center ${ className={`w-[10%] text-center ${
list?.totalArticle === 0 && list?.totalArticle === 0 &&
"bg-red-600 text-white" "bg-red-600 text-white "
}`} }`}
> >
{list?.totalArticle} {list?.totalArticle}
@ -449,14 +519,20 @@ export default function DashboardContainer() {
<div className="w-[85%]"> <div className="w-[85%]">
{child?.userLevelName} {child?.userLevelName}
</div> </div>
<div <a
className={`w-[10%] text-start ${ onClick={() => {
if (list?.totalArticle !== 0) {
setSelectedUnit(child?.userLevelName);
openModalArticle(list?.totalArticle);
}
}}
className={`w-[10%] text-start cursor-pointer ${
list?.totalArticle === 0 && list?.totalArticle === 0 &&
"bg-red-600 text-white" "bg-red-600 text-white cursor-default"
}`} }`}
> >
{child?.totalArticle} {child?.totalArticle}
</div> </a>
</div> </div>
) )
) )
@ -711,6 +787,44 @@ export default function DashboardContainer() {
</div> </div>
</div> </div>
</div> </div>
<Modal isOpen={isOpen} onOpenChange={onOpenChange} size="3xl">
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">
{selectedUnit} List Content
</ModalHeader>
<ModalBody>
<div className="grid grid-cols-12 text-xs ">
<div className="col-span-1 font-bold">No</div>
<div className="col-span-9 text-center font-bold">Judul</div>
<div className="col-span-2 font-bold ">Dibuat</div>
<div className="col-span-12 grid grid-cols-12 max-h-[480px] overflow-auto">
{recapArticleList?.length > 0 &&
recapArticleList?.map((list: any) => (
<Fragment key={list.id}>
<div className="col-span-1 my-2">{list.no}</div>
<div className="col-span-9 my-2">
<Link
href={`/news/detail/${list.id}-${list.slug}`}
target="_blank"
className="hover:underline hover:text-primary"
>
{textEllipsis(list.title, 80)}
</Link>
</div>
<div className="my-2 col-span-2">
{convertDateFormat(list?.createdAt)}
</div>
</Fragment>
))}
</div>
</div>
</ModalBody>
</>
)}
</ModalContent>
</Modal>
</div> </div>
); );
} }

View File

@ -157,29 +157,33 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
</p> </p>
</div> </div>
<div className="flex justify-center my-2 lg:my-5"> <div className="flex justify-center my-2 lg:my-5">
{data.files[0].file_name.split(".")[1].includes("doc") || {data?.files ? (
data.files[0].file_name.split(".")[1].includes("pdf") ? ( data?.files[0]?.file_name.split(".")[1].includes("doc") ||
<Image data?.files[0]?.file_name.split(".")[1].includes("pdf") ? (
classNames={{
wrapper: "!w-full !max-w-full",
img: "!w-full",
}}
alt="Main Image"
src={data.thumbnailUrl}
className="object-cover w-[100%] rounded-md"
/>
) : (
data?.files?.length > 0 && (
<Image <Image
// classNames={{ classNames={{
// wrapper: "!w-full !max-w-full", wrapper: "!w-full !max-w-full",
// img: "!w-full", img: "!w-full",
// }} }}
alt="Main Image" alt="Main Image"
src={data?.files[imageNow]?.file_url} src={data.thumbnailUrl}
className="object-cover w-auto h-[360px] md:h-[480px] mx-auto rounded-md" className="object-cover w-[100%] rounded-md"
/> />
) : (
data?.files?.length > 0 && (
<Image
// classNames={{
// wrapper: "!w-full !max-w-full",
// img: "!w-full",
// }}
alt="Main Image"
src={data?.files[imageNow]?.file_url}
className="object-cover w-auto h-[360px] md:h-[480px] mx-auto rounded-md"
/>
)
) )
) : (
""
)} )}
</div> </div>
{data?.files?.length > 0 && {data?.files?.length > 0 &&

View File

@ -89,14 +89,14 @@ export const siteConfig = {
}, },
{ {
label: "Pelayanan Propam Presisi", label: "Pelayanan Propam Presisi",
href: "https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam&pli=1", href: "https://apps.apple.com/id/app/propam-presisi/id1560263690?l=id",
img: "/pm9.png", img: "/pm9.png",
blank: true, blank: true,
desc: "Pelayanan Untuk Masyarakat Agar Mudah Melaporkan Sesuatu Kejadian atau Kejahatan", desc: "Pelayanan Untuk Masyarakat Agar Mudah Melaporkan Sesuatu Kejadian atau Kejahatan",
}, },
{ {
label: "Pelayanan Dumas Presisi", label: "Pelayanan Dumas Presisi",
href: "https://dumaspresisi.polri.go.id/", href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi",
img: "/pm10.png", img: "/pm10.png",
blank: true, blank: true,
desc: "Layanan Pengaduan Masyarakat Terintegrasi Berbasis Online", desc: "Layanan Pengaduan Masyarakat Terintegrasi Berbasis Online",
@ -229,7 +229,7 @@ export const siteConfig = {
}, },
{ {
label: "Polisiku", label: "Polisiku",
href: "https://play.google.com/store/apps/details?id=id.co.qlue.polisiku&hl=id&gl=ID", href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi",
img: "/at3.png", img: "/at3.png",
blank: true, blank: true,
desc: "Membantu anggota Kepolisian untuk mengindetifikasi masalah di lapangan", desc: "Membantu anggota Kepolisian untuk mengindetifikasi masalah di lapangan",
@ -299,14 +299,14 @@ export const siteConfig = {
}, },
{ {
label: "Propam Presisi", label: "Propam Presisi",
href: "https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam", href: "https://apps.apple.com/id/app/propam-presisi/id1560263690?l=id",
img: "/pm9.png", img: "/pm9.png",
blank: true, blank: true,
desc: "Aplikasi Pelayanan Masyarakat untuk Melapor Secara Mudah", desc: "Aplikasi Pelayanan Masyarakat untuk Melapor Secara Mudah",
}, },
{ {
label: "Monitoring Presisi", label: "Monitoring Presisi",
href: "https://play.google.com/store/apps/details?id=com.stk.pengaduanpropam", href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi",
img: "/at14.png", img: "/at14.png",
blank: true, blank: true,
desc: "Aplikasi Anggota Binmas dan Satpam Polda Metro Jaya Melaporkan Tugas", desc: "Aplikasi Anggota Binmas dan Satpam Polda Metro Jaya Melaporkan Tugas",
@ -320,14 +320,14 @@ export const siteConfig = {
}, },
{ {
label: "Whistle Blowing System", label: "Whistle Blowing System",
href: "https://pengaduan-penerimaan.polri.go.id/", href: "https://wbs.polri.go.id/",
img: "/at16.png", img: "/at16.png",
blank: true, blank: true,
desc: "Website untuk Pengaduan Penerimaan Anggota POLRI", desc: "Website untuk Pengaduan Penerimaan Anggota POLRI",
}, },
{ {
label: "Dumas Presisi", label: "Dumas Presisi",
href: "https://play.google.com/store/apps/details?id=com.admasolusi.monitoringpresisi", href: "https://play.google.com/store/apps/details?id=superapps.polri.presisi.presisi",
img: "/pm10.png", img: "/pm10.png",
blank: true, blank: true,
desc: "Website Layanan Pengaduan Masyarakat Terintegrasi", desc: "Website Layanan Pengaduan Masyarakat Terintegrasi",