diff --git a/app/(admin)/admin/advertise/page.tsx b/app/(admin)/admin/advertise/page.tsx index 96cc2b8..d943c07 100644 --- a/app/(admin)/admin/advertise/page.tsx +++ b/app/(admin)/admin/advertise/page.tsx @@ -30,12 +30,13 @@ import withReactContent from "sweetalert2-react-content"; import { useDropzone } from "react-dropzone"; import { close, error, loading } from "@/config/swal"; import Image from "next/image"; +import { createAdvertise } from "@/service/advertisement"; const createArticleSchema = z.object({ title: z.string().min(2, { message: "Judul harus diisi", }), - url: z.string().min(2, { + url: z.string().min(1, { message: "Link harus diisi", }), description: z.string().min(2, { @@ -79,19 +80,24 @@ export default function AdvertisePage() { title: values.title, description: values.description, placement: placement, - url: values.url, + redirectLink: values.url, }; + const res = await createAdvertise(formData); + if (res?.error) { + error(res?.message); + return false; + } close(); - // setRefresh(!refresh); - // MySwal.fire({ - // title: "Sukses", - // icon: "success", - // confirmButtonColor: "#3085d6", - // confirmButtonText: "OK", - // }).then((result) => { - // if (result.isConfirmed) { - // } - // }); + setRefresh(!refresh); + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + } + }); }; const handleRemoveFile = (file: File) => { @@ -275,7 +281,7 @@ export default function AdvertisePage() { diff --git a/app/auth/page.tsx b/app/auth/page.tsx index 300e6a1..de266f6 100644 --- a/app/auth/page.tsx +++ b/app/auth/page.tsx @@ -1,19 +1,5 @@ import Login from "@/components/form/login"; export default function AuthPage() { - // const isAuthenticated = Cookies.get("is_authenticated") || "false"; - - // console.log("isAuthenticated : ", isAuthenticated); - - // const [hasMounted, setHasMounted] = useState(false); - - // useEffect(() => { - // setHasMounted(true); - // }, []); - - // // Render - // if (!hasMounted) return null; - - // return isAuthenticated == "true" ? : ; return ; } diff --git a/app/layout.tsx b/app/layout.tsx index ea6067e..0afa8cb 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -53,6 +53,9 @@ export default function RootLayout({ children }: { children: ReactNode }) { return ( + + DIVISI HUMAS POLRI - Pengelolaan Informasi & Dokumentasi Polri + + + { const res = await getUserLevels(String(userLevel)); - console.log("res", res?.data?.data?.isApprovalActive); return res?.data?.data?.isApprovalActive; }; @@ -354,10 +353,14 @@ export default function CreateArticleForm() { } close(); - successSubmit("/admin/article"); + successSubmit("/admin/article", articleId, values.slug); }; - function successSubmit(redirect: string) { + function successSubmit(redirect: string, id: number, slug: string) { + const url = + `${window.location.protocol}//${window.location.host}` + + "/news/detail/" + + `${id}-${slug}`; MySwal.fire({ title: "Sukses", icon: "success", @@ -366,6 +369,10 @@ export default function CreateArticleForm() { }).then((result) => { if (result.isConfirmed) { router.push(redirect); + successToast("Article Url", url); + } else { + router.push(redirect); + successToast("Article Url", url); } }); } diff --git a/components/form/login.tsx b/components/form/login.tsx index b04f621..32f8e8e 100644 --- a/components/form/login.tsx +++ b/components/form/login.tsx @@ -236,6 +236,7 @@ export default function Login() { label="" placeholder="" className="my-2" + classNames={{ input: "rounded-md", inputWrapper: "rounded-md" }} value={username} onChange={(e: any) => { setValUsername(e.target.value.trim()); @@ -251,6 +252,7 @@ export default function Login() { ); +export const CopyIcon = ({ + size, + height = 24, + width = 24, + fill = "currentColor", + ...props +}: IconSvgProps) => ( + + + + + +); diff --git a/components/landing/HeaderNews.tsx b/components/landing/HeaderNews.tsx index f9da124..437918c 100644 --- a/components/landing/HeaderNews.tsx +++ b/components/landing/HeaderNews.tsx @@ -66,7 +66,7 @@ export default function HeaderNews() { return (
-
+
{article ? ( @@ -107,7 +107,7 @@ export default function HeaderNews() { ? "/no-image.jpg" : newsItem?.thumbnailUrl } - className="w-[90%] !h-[200px] object-cover" + className="!w-[90vh] md:!w-[95vh] !h-[200px] md:!h-[400px] object-cover" /> diff --git a/components/landing/adds-carousel.tsx b/components/landing/adds-carousel.tsx index 6aad4f0..b727c88 100644 --- a/components/landing/adds-carousel.tsx +++ b/components/landing/adds-carousel.tsx @@ -13,17 +13,38 @@ import { Swiper, SwiperSlide, useSwiper } from "swiper/react"; import "swiper/css"; import "swiper/css/navigation"; import Link from "next/link"; - import { Autoplay, Pagination, Navigation, Controller } from "swiper/modules"; +import { useEffect, useState } from "react"; +import { getAdvertise } from "@/service/advertisement"; + const datas = [ - { id: 1, src: "/props-1.png" }, - { id: 2, src: "/props-2.png" }, - { id: 2, src: "/props-3.png" }, + { id: 1, src: "/sample-banner.png" }, + { id: 2, src: "/sample-banner-2.png" }, + { id: 2, src: "/sample-banner-3.jpg" }, ]; + +interface Jumbotron { + id: number; + title: string; + description: string; + redirectLink: string; +} + export default function AddsCarousel() { + const [jumbotronList, setJumbotronList] = useState([]); + + useEffect(() => { + initFetch(); + }, []); + + const initFetch = async () => { + const req = { page: 1, limit: 5, placement: "banner" }; + const res = await getAdvertise(req); + setJumbotronList(res?.data?.data); + }; return (
- {datas ? ( + {jumbotronList ? ( - {datas?.map((newsItem: any, index: number) => ( + {jumbotronList?.map((newsItem, index) => ( diff --git a/components/landing/banner-new.tsx b/components/landing/banner-new.tsx index 700cb1a..c65be66 100644 --- a/components/landing/banner-new.tsx +++ b/components/landing/banner-new.tsx @@ -39,6 +39,7 @@ import { 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", @@ -47,6 +48,13 @@ const images = [ "/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(); @@ -55,28 +63,40 @@ export default function BannerHumasNew() { const [resetTimer, setResetTimer] = useState(0); const [onOpenDropdown, setOnOpenDropdown] = useState(false); const [searchValue, setSearchValue] = useState(""); + const [jumbotronList, setJumbotronList] = useState([]); const language = storedLanguage((state) => state.locale); const setLanguage = storedLanguage((state) => state.setLocale); useEffect(() => { const interval = setInterval(() => { - setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length); + setCurrentIndex((prevIndex) => (prevIndex + 1) % jumbotronList?.length); }, 25000); return () => clearInterval(interval); }, [resetTimer]); const nextImage = () => { - setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length); + setCurrentIndex((prevIndex) => (prevIndex + 1) % jumbotronList?.length); setResetTimer((prev) => prev + 1); }; const prevImage = () => { setCurrentIndex( - (prevIndex) => (prevIndex - 1 + images.length) % images.length + (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; @@ -193,12 +213,16 @@ export default function BannerHumasNew() { className="flex w-full h-[45vh] lg:h-[93vh] transition-transform duration-700 ease-in-out" style={{ transform: `translateX(-${currentIndex * 100}%)` }} > - {images.map((img, index) => ( - + {jumbotronList.map((img, index) => ( + {`humasbanner-${index}`} ))} diff --git a/components/landing/drawer.tsx b/components/landing/drawer.tsx index 49bc072..c87be16 100644 --- a/components/landing/drawer.tsx +++ b/components/landing/drawer.tsx @@ -17,7 +17,17 @@ export default function AnalyticDrawer() { <>
+ diff --git a/components/table/article-table.tsx b/components/table/article-table.tsx index f00e704..d58f72c 100644 --- a/components/table/article-table.tsx +++ b/components/table/article-table.tsx @@ -1,13 +1,14 @@ "use client"; import { BannerIcon, + CopyIcon, CreateIconIon, DeleteIcon, DotsYIcon, EyeIconMdi, SearchIcon, } from "@/components/icons"; -import { error, success } from "@/config/swal"; +import { error, success, successToast } from "@/config/swal"; import { deleteArticle, getArticleByCategory, @@ -158,6 +159,20 @@ export default function ArticleTable() { console.log("vbanner", id, status); }; + const copyUrlArticle = async (id: number, slug: string) => { + const url = + `${window.location.protocol}//${window.location.host}` + + "/news/detail/" + + `${id}-${slug}`; + try { + await navigator.clipboard.writeText(url); + successToast("Success", "Article Copy to Clipboard"); + setTimeout(() => {}, 1500); + } catch (err) { + ("Failed to copy!"); + } + }; + const renderCell = useCallback( (article: any, columnKey: Key) => { const cellValue = article[columnKey as keyof any]; @@ -199,6 +214,13 @@ export default function ArticleTable() { + copyUrlArticle(article.id, article.slug)} + > + + Copy Url Article + diff --git a/public/props-1.png b/public/props-1.png deleted file mode 100644 index 8b868ef..0000000 Binary files a/public/props-1.png and /dev/null differ diff --git a/public/props-2.png b/public/props-2.png deleted file mode 100644 index 50c7b3c..0000000 Binary files a/public/props-2.png and /dev/null differ diff --git a/public/props-3.png b/public/props-3.png deleted file mode 100644 index 09a76e7..0000000 Binary files a/public/props-3.png and /dev/null differ diff --git a/public/sample-banner-2.png b/public/sample-banner-2.png new file mode 100644 index 0000000..3ecfb06 Binary files /dev/null and b/public/sample-banner-2.png differ diff --git a/public/sample-banner-3.jpg b/public/sample-banner-3.jpg new file mode 100644 index 0000000..e3587d5 Binary files /dev/null and b/public/sample-banner-3.jpg differ diff --git a/public/sample-banner.png b/public/sample-banner.png new file mode 100644 index 0000000..8d2bfc3 Binary files /dev/null and b/public/sample-banner.png differ diff --git a/service/advertisement.ts b/service/advertisement.ts new file mode 100644 index 0000000..21f9cb3 --- /dev/null +++ b/service/advertisement.ts @@ -0,0 +1,44 @@ +import { + httpDeleteInterceptor, + httpGet, + httpPost, + httpPut, +} from "./http-config/axios-base-service"; +import Cookies from "js-cookie"; + +const token = Cookies.get("access_token"); + +export async function createAdvertise(data: any) { + const headers = { + "content-type": "application/json", + Authorization: `Bearer ${token}`, + }; + const pathUrl = `/advertisement`; + return await httpPost(pathUrl, headers, data); +} + +export async function getAdvertise(data: any) { + const headers = { + "content-type": "application/json", + }; + const pathUrl = `/advertisement?page=${data?.page || 1}&limit=${ + data?.limit || "" + }&placement=${data?.placement || ""}`; + return await httpGet(pathUrl, headers); +} + +export async function createAdvertiseById(id: number) { + const headers = { + "content-type": "application/json", + }; + const pathUrl = `/advertisement/${id}`; + return await httpGet(pathUrl, headers); +} + +export async function editAdvertise(data: any) { + const headers = { + "content-type": "application/json", + }; + const pathUrl = `/advertisement/${data?.id}`; + return await httpPut(pathUrl, headers, data); +}