418 lines
13 KiB
TypeScript
418 lines
13 KiB
TypeScript
"use client";
|
|
import { useTranslations } from "next-intl";
|
|
import React, { useEffect, useState } from "react";
|
|
import {
|
|
ChevronDownIcon,
|
|
ChevronLeftIcon,
|
|
ChevronRightIcon,
|
|
ChevronUpIcon,
|
|
FbIconNav,
|
|
IdnIcon,
|
|
IgIcon,
|
|
SearchIcon,
|
|
SearchIcons,
|
|
TtIcon,
|
|
TwIcon,
|
|
UKIcon,
|
|
YtIcon,
|
|
} from "../icons";
|
|
import Link from "next/link";
|
|
import {
|
|
Dropdown,
|
|
DropdownTrigger,
|
|
DropdownMenu,
|
|
DropdownItem,
|
|
Button,
|
|
Input,
|
|
Modal,
|
|
ModalContent,
|
|
ModalHeader,
|
|
ModalBody,
|
|
useDisclosure,
|
|
Popover,
|
|
PopoverTrigger,
|
|
PopoverContent,
|
|
Accordion,
|
|
AccordionItem,
|
|
Image,
|
|
} from "@heroui/react";
|
|
import storedLanguage from "@/store/language-store";
|
|
import { ThemeSwitch } from "../theme-switch";
|
|
import { siteConfig, SiteConfig } from "@/config/site";
|
|
import { getAdvertise } from "@/service/advertisement";
|
|
|
|
const images = [
|
|
"/landing-1.jpg",
|
|
"/landing-2.jpg",
|
|
"/landing-3.jpg",
|
|
"/landing-4.jpg",
|
|
];
|
|
|
|
interface Jumbotron {
|
|
id: number;
|
|
title: string;
|
|
description: string;
|
|
redirectLink: string;
|
|
}
|
|
|
|
export default function BannerHumasNew() {
|
|
const t = useTranslations("Banner");
|
|
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
|
|
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
const [resetTimer, setResetTimer] = useState(0);
|
|
const [onOpenDropdown, setOnOpenDropdown] = useState(false);
|
|
const [searchValue, setSearchValue] = useState("");
|
|
const [jumbotronList, setJumbotronList] = useState<Jumbotron[]>([]);
|
|
const language = storedLanguage((state) => state.locale);
|
|
const setLanguage = storedLanguage((state) => state.setLocale);
|
|
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
setCurrentIndex((prevIndex) => (prevIndex + 1) % jumbotronList?.length);
|
|
}, 25000);
|
|
|
|
return () => clearInterval(interval);
|
|
}, [resetTimer]);
|
|
const nextImage = () => {
|
|
setCurrentIndex((prevIndex) => (prevIndex + 1) % jumbotronList?.length);
|
|
setResetTimer((prev) => prev + 1);
|
|
};
|
|
|
|
const prevImage = () => {
|
|
setCurrentIndex(
|
|
(prevIndex) =>
|
|
(prevIndex - 1 + jumbotronList?.length) % jumbotronList?.length
|
|
);
|
|
setResetTimer((prev) => prev + 1);
|
|
};
|
|
|
|
useEffect(() => {
|
|
initFetch();
|
|
}, []);
|
|
|
|
const initFetch = async () => {
|
|
const req = { page: 1, limit: 5, placement: "jumbotron" };
|
|
const res = await getAdvertise(req);
|
|
setJumbotronList(res?.data?.data);
|
|
};
|
|
|
|
const MenuPopover = (props: {
|
|
title: string;
|
|
menus: any;
|
|
placement: "right" | "right-end" | "right-start";
|
|
withImage: boolean;
|
|
}) => {
|
|
const { title, placement, menus, withImage } = props;
|
|
return (
|
|
<Popover placement={placement} classNames={{ content: "w-fit" }}>
|
|
<PopoverTrigger>
|
|
<a className="cursor-pointer px-2 w-full font-semibold text-sm flex justify-between hover:underline">
|
|
{title}
|
|
<ChevronRightIcon />
|
|
</a>
|
|
</PopoverTrigger>
|
|
<PopoverContent className="ml-2 w-fit">
|
|
<div
|
|
className={` px-1 py-2 grid gap-2 ${
|
|
withImage ? " grid-cols-3" : "grid-cols-1 gap-2"
|
|
} `}
|
|
>
|
|
{menus?.map((menu: any) => (
|
|
<Link
|
|
key={menu.label}
|
|
className={` flex flex-row gap-2 items-center group`}
|
|
href={menu.href}
|
|
target="_blank"
|
|
>
|
|
{withImage && (
|
|
<Image
|
|
alt="logo"
|
|
src={menu.img}
|
|
className="w-[45px] h-[45px]"
|
|
/>
|
|
)}
|
|
|
|
<div
|
|
className={
|
|
withImage ? `flex flex-col` : "flex justify-between w-full"
|
|
}
|
|
>
|
|
<p className="text-[14px] font-semibold group-hover:underline">
|
|
{menu.label}
|
|
</p>
|
|
{withImage && (
|
|
<p className="text-[10px] font-light overflow-hidden">
|
|
{menu.desc}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</PopoverContent>
|
|
</Popover>
|
|
);
|
|
};
|
|
|
|
const MenuPopoverMobile = (props: {
|
|
title: string;
|
|
menus: any;
|
|
placement: "right" | "right-end" | "right-start";
|
|
withImage: boolean;
|
|
}) => {
|
|
const { title, placement, menus, withImage } = props;
|
|
|
|
return (
|
|
<Accordion className="w-full">
|
|
<AccordionItem
|
|
key={title}
|
|
aria-label={title}
|
|
title={title}
|
|
classNames={{ title: "font-semibold" }}
|
|
>
|
|
<div
|
|
className={` px-1 py-2 text-black grid gap-2 ${
|
|
withImage ? " grid-cols-2 " : "grid-cols-2"
|
|
} `}
|
|
>
|
|
{menus?.map((menu: any) => (
|
|
<Link
|
|
key={menu.label}
|
|
className={` flex flex-row gap-2 items-center group`}
|
|
href={menu.href}
|
|
target="_blank"
|
|
>
|
|
{withImage && (
|
|
<Image
|
|
alt="logo"
|
|
src={menu.img}
|
|
className="w-[35px] h-[35px]"
|
|
/>
|
|
)}
|
|
|
|
<div
|
|
className={
|
|
withImage ? `flex flex-col` : "flex justify-between w-full"
|
|
}
|
|
>
|
|
<p className="text-[14px] group-hover:underline">
|
|
{menu.label}
|
|
</p>
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</AccordionItem>
|
|
</Accordion>
|
|
);
|
|
};
|
|
|
|
const [hasMounted, setHasMounted] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setHasMounted(true);
|
|
}, []);
|
|
|
|
// Render
|
|
if (!hasMounted) return null;
|
|
return (
|
|
<div className="h-fit relative text-white overflow-hidden">
|
|
<div
|
|
className="flex w-full h-[45vh] lg:h-[93vh] transition-transform duration-700 ease-in-out"
|
|
style={{ transform: `translateX(-${currentIndex * 100}%)` }}
|
|
>
|
|
{jumbotronList?.map((img, index) => (
|
|
<Link
|
|
href={img?.redirectLink}
|
|
key={img?.id}
|
|
className="w-full shrink-0"
|
|
>
|
|
<Image
|
|
src={images[index % 4]}
|
|
alt={`humasbanner-${index}`}
|
|
className="w-screen h-[45vh] lg:h-[93vh] object-cover object-center opacity-[25] dark:opacity-70 rounded-none"
|
|
/>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
<div className="absolute inset-0 bg-black bg-opacity-40 pointer-events-none" />
|
|
<div className="absolute z-50 lg:mt-[50px] top-48 lg:top-1/3 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-center w-full lg:w-[75%]">
|
|
<div className="flex flex-col gap-3 justify-between p-5">
|
|
<div className="flex justify-between items-center mb-10">
|
|
<div className="flex flex-col gap-1 justify-start items-start">
|
|
<p className="text-lg lg:text-5xl font-bold text-left leading-0">
|
|
{t("welcome")}
|
|
</p>
|
|
<p className="text-xs lg:text-base">
|
|
OBYEKTIF - DIPERCAYA - PARTISIPASI
|
|
</p>
|
|
</div>
|
|
<Image src="/divhumas.png" alt="logo-humas" className="w-[200px]" />
|
|
</div>
|
|
<div className="flex flex-col lg:flex-row lg:justify-between gap-4 mt-10 lg:mt-24">
|
|
<div className="flex flex-row gap-6">
|
|
<Popover
|
|
placement="bottom"
|
|
isOpen={onOpenDropdown}
|
|
onOpenChange={setOnOpenDropdown}
|
|
>
|
|
<PopoverTrigger>
|
|
<Button
|
|
className="w-full lg:w-[225px] bg-white dark:bg-stone-900"
|
|
radius="sm"
|
|
endContent={
|
|
onOpenDropdown ? <ChevronUpIcon /> : <ChevronDownIcon />
|
|
}
|
|
>
|
|
<p className="text-left w-full font-bold text-md">Menu</p>
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent className="w-full lg:w-[225px] py-3 px-2">
|
|
<div className="space-y-1 hidden lg:block">
|
|
<MenuPopover
|
|
title="Pelayanan Masyarakat"
|
|
menus={siteConfig.humasMenuItems[0].submenu}
|
|
placement="right"
|
|
withImage={true}
|
|
/>
|
|
<MenuPopover
|
|
title="Informasi Publik"
|
|
menus={siteConfig.humasMenuItems[2].submenu}
|
|
placement="right-start"
|
|
withImage={false}
|
|
/>
|
|
<MenuPopover
|
|
title="Tentang"
|
|
menus={siteConfig.humasMenuItems[3].submenu}
|
|
placement="right-start"
|
|
withImage={false}
|
|
/>
|
|
<MenuPopover
|
|
title="Aplikasi Polri"
|
|
menus={siteConfig.humasMenuItems[4].submenu}
|
|
placement="right"
|
|
withImage={true}
|
|
/>
|
|
</div>
|
|
<div className="space-y-1 lg:hidden w-[90vw] max-h-[50vh] overflow-auto">
|
|
<MenuPopoverMobile
|
|
title="Pelayanan Masyarakat"
|
|
menus={siteConfig.humasMenuItems[0].submenu}
|
|
placement="right"
|
|
withImage={true}
|
|
/>
|
|
<MenuPopoverMobile
|
|
title="Informasi Publik"
|
|
menus={siteConfig.humasMenuItems[2].submenu}
|
|
placement="right-start"
|
|
withImage={false}
|
|
/>
|
|
<MenuPopoverMobile
|
|
title="Tentang"
|
|
menus={siteConfig.humasMenuItems[3].submenu}
|
|
placement="right-start"
|
|
withImage={false}
|
|
/>
|
|
<MenuPopoverMobile
|
|
title="Aplikasi Polri"
|
|
menus={siteConfig.humasMenuItems[4].submenu}
|
|
placement="right"
|
|
withImage={true}
|
|
/>
|
|
</div>
|
|
</PopoverContent>
|
|
</Popover>
|
|
<Link href={`https://eppid.polri.go.id/`}>
|
|
<Button className="bg-white dark:bg-stone-900" radius="sm">
|
|
<p className="font-bold w-full ">e-PPID Polri</p>
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
<Input
|
|
label=""
|
|
placeholder="Temukkan Informasi Publik Terkini Dari Polri"
|
|
type="text"
|
|
value={searchValue}
|
|
onValueChange={setSearchValue}
|
|
className="max-w-md"
|
|
endContent={
|
|
<Link
|
|
href={`/news/all?search=${searchValue}`}
|
|
className="text-black"
|
|
>
|
|
<SearchIcons />
|
|
</Link>
|
|
}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button
|
|
onClick={() => prevImage()}
|
|
className=" absolute z-50 left-4 lg:left-10 top-1/2 transform -translate-y-1/2 bg-black/50 text-white px-2 py-2 rounded-full hover:bg-black/70 transition"
|
|
>
|
|
<ChevronLeftIcon size={36} />
|
|
</button>
|
|
<button
|
|
onClick={() => nextImage()}
|
|
className="absolute z-50 right-4 lg:right-10 top-1/2 transform -translate-y-1/2 bg-black/50 text-white px-2 py-2 rounded-full hover:bg-black/70 transition"
|
|
>
|
|
<ChevronRightIcon size={36} />
|
|
</button>
|
|
<div className="absolute bottom-4 right-5 lg:right-60 lg:mx-5">
|
|
<div className="flex">
|
|
<div className="flex gap-1 lg:gap-3 items-center">
|
|
<Link
|
|
href="https://www.facebook.com/DivHumasPolri?_rdc=1&_rdr"
|
|
target="_blank"
|
|
>
|
|
<div className="bg-white p-1.5 rounded-md">
|
|
<FbIconNav size={16} />
|
|
</div>
|
|
</Link>
|
|
<Link
|
|
href="https://www.instagram.com/divisihumaspolri/"
|
|
target="_blank"
|
|
>
|
|
<div className="bg-white p-0.5 rounded-md">
|
|
<IgIcon size={24} />
|
|
</div>
|
|
</Link>
|
|
<Link
|
|
href="https://www.youtube.com/user/pidhumaspolri"
|
|
target="_blank"
|
|
>
|
|
<div className="bg-white p-0.5 rounded-md">
|
|
<YtIcon size={24} />
|
|
</div>
|
|
</Link>
|
|
<Link href="https://twitter.com/DivHumas_Polri" target="_blank">
|
|
<div className="bg-white p-1 rounded-md">
|
|
<TwIcon size={20} />
|
|
</div>
|
|
</Link>
|
|
<Link href="https://www.tiktok.com/@divhumas_polri" target="_blank">
|
|
<div className="bg-white p-0.5 rounded-md">
|
|
<TtIcon size={24} />
|
|
</div>
|
|
</Link>
|
|
|
|
<div className="bg-white rounded-md py-0.5 px-1">
|
|
<ThemeSwitch />
|
|
</div>
|
|
{/* <a
|
|
className="cursor-pointer"
|
|
onClick={() =>
|
|
language === "id" ? setLanguage("en") : setLanguage("id")
|
|
}
|
|
>
|
|
{language === "id" ? <IdnIcon /> : <UKIcon />}
|
|
</a> */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|