From fd34c280d39da5612d826a1720b2cd6a8bcdde0e Mon Sep 17 00:00:00 2001 From: sabdayagra Date: Sun, 5 Jan 2025 20:46:18 +0700 Subject: [PATCH] feat: add language on landing page and all filter page --- app/[locale]/(public)/all/filter/page.tsx | 265 ++++------------- .../(public)/audio/detail/[slug]/page.tsx | 237 +++++++++++++-- .../(public)/document/detail/[slug]/page.tsx | 237 +++++++++++++-- .../(public)/image/detail/[slug]/page.tsx | 238 +++++++++++++-- app/[locale]/(public)/image/filter/page.tsx | 2 +- app/[locale]/(public)/indeks/page.tsx | 4 +- .../(public)/video/detail/[slug]/page.tsx | 103 ++----- app/[locale]/(public)/video/filter/page.tsx | 274 +++--------------- components/landing-page/content-category.tsx | 21 +- components/landing-page/coverage.tsx | 30 +- components/landing-page/division.tsx | 22 +- .../filter-all/image-filter-card.tsx | 2 +- components/landing-page/hero.tsx | 52 +--- components/landing-page/navbar.tsx | 144 ++++----- components/landing-page/new-content.tsx | 236 ++++----------- components/landing-page/search-section.tsx | 62 +--- messages/en.json | 38 +++ messages/in.json | 38 +++ 18 files changed, 1067 insertions(+), 938 deletions(-) diff --git a/app/[locale]/(public)/all/filter/page.tsx b/app/[locale]/(public)/all/filter/page.tsx index 9b1a7c0c..0651dabc 100644 --- a/app/[locale]/(public)/all/filter/page.tsx +++ b/app/[locale]/(public)/all/filter/page.tsx @@ -5,25 +5,8 @@ import { Checkbox } from "@/components/ui/checkbox"; import { Icon } from "@iconify/react/dist/iconify.js"; import { getOnlyDate, getOnlyMonthAndYear } from "@/utils/globals"; import { useParams, usePathname, useSearchParams } from "next/navigation"; -import { - getUserLevelListByParent, - listCategory, - listData, - listDataAll, - listDataRegional, -} from "@/service/landing/landing"; -import { - ColumnDef, - ColumnFiltersState, - PaginationState, - SortingState, - VisibilityState, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from "@tanstack/react-table"; +import { getUserLevelListByParent, listCategory, listData, listDataAll, listDataRegional } from "@/service/landing/landing"; +import { ColumnDef, ColumnFiltersState, PaginationState, SortingState, VisibilityState, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table"; import { Reveal } from "@/components/landing-page/Reveal"; import { Link, useRouter } from "@/i18n/routing"; import { Input } from "@/components/ui/input"; @@ -45,11 +28,8 @@ export default function FilterPage() { const [totalData, setTotalData] = React.useState(1); const [totalPage, setTotalPage] = React.useState(1); const [sorting, setSorting] = React.useState([]); - const [columnFilters, setColumnFilters] = React.useState( - [] - ); - const [columnVisibility, setColumnVisibility] = - React.useState({}); + const [columnFilters, setColumnFilters] = React.useState([]); + const [columnVisibility, setColumnVisibility] = React.useState({}); const [rowSelection, setRowSelection] = React.useState({}); const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -71,9 +51,7 @@ export default function FilterPage() { const [categoryFilter, setCategoryFilter] = useState([]); const [monthYearFilter, setMonthYearFilter] = useState(); const [searchTitle, setSearchTitle] = useState(""); - const [sortByOpt, setSortByOpt] = useState( - sortBy === "popular" ? "clickCount" : "createdAt" - ); + const [sortByOpt, setSortByOpt] = useState(sortBy === "popular" ? "clickCount" : "createdAt"); const isRegional = asPath?.includes("regional"); const isSatker = asPath?.includes("satker"); const [formatFilter, setFormatFilter] = useState([]); @@ -110,14 +88,8 @@ export default function FilterPage() { useEffect(() => { if (categorie) { - setCategoryFilter( - categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] - ); - console.log( - "Kategori", - categorie, - categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] - ); + setCategoryFilter(categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]); + console.log("Kategori", categorie, categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]); } }, [categorie]); @@ -135,17 +107,7 @@ export default function FilterPage() { } console.log(monthYearFilter, "monthFilter"); initState(); - }, [ - change, - monthYearFilter, - sortBy, - sortByOpt, - title, - startDateString, - endDateString, - categorie, - formatFilter, - ]); + }, [change, monthYearFilter, sortBy, sortByOpt, title, startDateString, endDateString, categorie, formatFilter]); async function getCategories() { const category = await listCategory("1"); @@ -168,10 +130,7 @@ export default function FilterPage() { async function getData() { if (asPath?.includes("/polda/") == true) { if (asPath?.split("/")[2] !== "[polda_name]") { - const filter = - categoryFilter?.length > 0 - ? categoryFilter?.sort().join(",") - : categorie || ""; + const filter = categoryFilter?.length > 0 ? categoryFilter?.sort().join(",") : categorie || ""; const name = title == undefined ? "" : title; const format = formatFilter == undefined ? "" : formatFilter?.join(","); @@ -186,14 +145,8 @@ export default function FilterPage() { filterGroup, startDateString, endDateString, - monthYearFilter - ? getOnlyMonthAndYear(monthYearFilter) - ?.split("/")[0] - ?.replace("0", "") - : "", - monthYearFilter - ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] - : "" + monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("0", "") : "", + monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "" ); close(); // setGetTotalPage(response?.data?.data?.totalPages); @@ -208,10 +161,7 @@ export default function FilterPage() { setTotalContent(response?.data?.data?.totalElements); } } else { - const filter = - categoryFilter?.length > 0 - ? categoryFilter?.sort().join(",") - : categorie || ""; + const filter = categoryFilter?.length > 0 ? categoryFilter?.sort().join(",") : categorie || ""; const name = title == undefined ? "" : title; const format = formatFilter == undefined ? "" : formatFilter?.join(","); @@ -225,14 +175,8 @@ export default function FilterPage() { tag, startDateString, endDateString, - monthYearFilter - ? getOnlyMonthAndYear(monthYearFilter) - ?.split("/")[0] - ?.replace("0", "") - : "", - monthYearFilter - ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] - : "" + monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("0", "") : "", + monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "" ); close(); // setGetTotalPage(response?.data?.data?.totalPages); @@ -283,10 +227,7 @@ export default function FilterPage() { }; async function getDataRegional() { - const filter = - categoryFilter?.length > 0 - ? categoryFilter?.sort().join(",") - : categorie || ""; + const filter = categoryFilter?.length > 0 ? categoryFilter?.sort().join(",") : categorie || ""; const name = title == undefined ? "" : title; const format = formatFilter == undefined ? "" : formatFilter?.join(","); @@ -299,12 +240,8 @@ export default function FilterPage() { "", startDateString, endDateString, - monthYearFilter - ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") - : "", - monthYearFilter - ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] - : "", + monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "", + monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "", 12, pages, sortByOpt @@ -410,10 +347,7 @@ export default function FilterPage() {
-
+
{/* Comment */}
diff --git a/app/[locale]/(public)/image/detail/[slug]/page.tsx b/app/[locale]/(public)/image/detail/[slug]/page.tsx index 01b01766..48981fbc 100644 --- a/app/[locale]/(public)/image/detail/[slug]/page.tsx +++ b/app/[locale]/(public)/image/detail/[slug]/page.tsx @@ -1,12 +1,15 @@ "use client"; import { Textarea } from "@/components/ui/textarea"; -import Link from "next/link"; -import { useParams, usePathname, useRouter } from "next/navigation"; +import { useParams, usePathname } from "next/navigation"; import React, { useEffect, useState } from "react"; import { Icon } from "@iconify/react/dist/iconify.js"; -import { getDetail } from "@/service/landing/landing"; import NewContent from "@/components/landing-page/new-content"; +import { useToast } from "@/components/ui/use-toast"; +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"; const DetailInfo = () => { const [selectedSize, setSelectedSize] = useState("L"); @@ -14,20 +17,101 @@ const DetailInfo = () => { const router = useRouter(); const pathname = usePathname(); const params = useParams(); - const slug = params?.slug; + const slug = String(params?.slug); const [detailDataImage, setDetailDataImage] = useState(); const [selectedImage, setSelectedImage] = useState(0); + const [isSaved, setIsSaved] = useState(false); + const [wishlistId, setWishlistId] = useState(); + const { toast } = useToast(); + const [isDownloadAll, setIsDownloadAll] = useState(false); + const [downloadProgress, setDownloadProgress] = useState(0); + const [isFromSPIT, setIsFromSPIT] = useState(false); + const [main, setMain] = useState(); + const [resolutionSelected, setResolutionSelected] = useState("720"); + const [imageSizeSelected, setImageSizeSelected] = useState("l"); + + const userId = getCookiesDecrypt("uie"); useEffect(() => { initFetch(); + checkWishlist(); }, []); const initFetch = async () => { const response = await getDetail(String(slug)); console.log("detailImage", response); + setIsFromSPIT(response?.data?.data?.isFromSPIT); + setMain({ + id: response?.data?.data?.files[0]?.id, + type: response?.data?.data?.fileType.name, + url: + Number(response?.data?.data?.fileType?.id) == 4 + ? response?.data?.data?.files[0]?.secondaryUrl + : Number(response?.data?.data?.fileType?.id) == 2 + ? `${process.env.NEXT_PUBLIC_API}/media/view?id=${response?.data?.data?.files[0]?.id}&operation=file&type=video` + : response?.data?.data?.files[0]?.url, + thumbnailFileUrl: response?.data?.data?.files[0]?.thumbnailFileUrl, + names: response?.data?.data?.files[0]?.fileName, + format: response?.data?.data?.files[0]?.format, + widthPixel: response?.data?.data?.files[0]?.widthPixel, + heightPixel: response?.data?.data?.files[0]?.heightPixel, + size: response?.data?.data?.files[0]?.size, + caption: response?.data?.data?.files[0]?.caption, + }); setDetailDataImage(response?.data?.data); }; + const doBookmark = async () => { + if (userId) { + const data = { + mediaUploadId: slug?.split("-")?.[0], + }; + + loading(); + const res = await saveWishlist(data); + if (res?.error) { + error(res.message); + return false; + } + close(); + toast({ + title: "Konten berhasil disimpan", + }); + checkWishlist(); + } else { + router.push("/auth"); + } + }; + async function checkWishlist() { + if (userId) { + const res = await checkWishlistStatus(slug.split("-")?.[0]); + console.log(res?.data?.data); + const isAlreadyOnWishlist = res?.data?.data !== "-1"; + setWishlistId(res?.data?.data); + setIsSaved(isAlreadyOnWishlist); + } + } + + const handleDeleteWishlist = async () => { + if (userId) { + loading(); + const res = await deleteWishlist(wishlistId); + + if (res?.error) { + error(res.message); + return false; + } + + toast({ + title: "Konten berhasil dihapus", + }); + close(); + checkWishlist(); + } else { + router.push("/auth"); + } + }; + const sizes = [ { label: "XL", value: "3198 x 1798 px" }, { label: "L", value: "2399 x 1349 px" }, @@ -36,6 +120,105 @@ const DetailInfo = () => { { label: "XS", value: "800 x 450 px" }, ]; + async function sendActivityLog(activityTypeId: number) { + const data = { + activityTypeId, + mediaId: slug.split("-")?.[0], + url: window.location.href, + }; + // set activity + // const response = await postActivityLog(data, token); + // console.log(response); + } + + const handleDownload = () => { + if (downloadProgress === 0) { + if (!userId) { + router.push("/auth/login"); + } else { + sendActivityLog(2); + sendActivityLog(3); + + if (isDownloadAll) { + let url: string; + const baseId = slug.split("-")?.[0]; + + // if (type === "1") { + // url = `${process.env.NEXT_PUBLIC_API}/media/file/download-zip?id=${baseId}&resolution=${resolutionSelected}`; + // } else if (type === "2") { + url = `${process.env.NEXT_PUBLIC_API}/media/file/download-zip?id=${baseId}&resolution=${imageSizeSelected}`; + // } else { + // url = `${process.env.NEXT_PUBLIC_API}/media/file/download-zip?id=${baseId}`; + // } + + downloadFile(url, "FileDownload.zip"); + } else { + if (isFromSPIT && main?.url?.includes("spit.humas")) { + downloadFile(`${main?.url}`, `${main.names}`); + } else { + // const url = `${process.env.NEXT_PUBLIC_API}/media/view?id=${main?.id}&operation=file&type=video&resolution=${resolutionSelected}p`; + // downloadFile(url, `${main.names}`); + const url = `${process.env.NEXT_PUBLIC_API}/media/view?id=${main?.id}&operation=file&type=image&resolution=${imageSizeSelected}`; + downloadFile(url, `${main.names}`); + } + } + // } else if (type === "1" && resolutionSelected?.length > 0) { + // if (isFromSPIT && main?.url?.includes("spit.humas")) { + // downloadFile(`${main?.url}`, `${main.names}`); + // } else { + // const url = `${process.env.NEXT_PUBLIC_API}/media/view?id=${main?.id}&operation=file&type=video&resolution=${resolutionSelected}p`; + // downloadFile(url, `${main.names}`); + // } + // } else if (type === "2" && imageSizeSelected?.length > 0) { + // const url = `${process.env.NEXT_PUBLIC_API}/media/view?id=${main?.id}&operation=file&type=image&resolution=${imageSizeSelected}`; + // downloadFile(url, `${main.names}`); + // } else if (type === "3" || type === "4") { + // downloadFile(`${main?.url}`, `${main.names}`); + // } + } + } + }; + + const downloadFile = (fileUrl: string, name: string) => { + const xhr = new XMLHttpRequest(); + + xhr.open("GET", fileUrl, true); + xhr.responseType = "blob"; + + xhr.addEventListener("progress", (event) => { + if (event.lengthComputable) { + const percentCompleted = Math.round((event.loaded / event.total) * 100); + setDownloadProgress(percentCompleted); + } + }); + + xhr.addEventListener("readystatechange", () => { + if (xhr.readyState === 4 && xhr.status === 200) { + const contentType = xhr.getResponseHeader("content-type") || "application/octet-stream"; + const extension = contentType.split("/")[1]; + const filename = `${name}.${extension}`; + + const blob = new Blob([xhr.response], { + type: contentType, + }); + const downloadUrl = URL.createObjectURL(blob); + const a = document.createElement("a"); + + a.href = downloadUrl; + a.download = filename; + document.body.append(a); + a.click(); + a.remove(); + } + }); + + xhr.onloadend = () => { + setDownloadProgress(0); + }; + + xhr.send(); + }; + return ( <>
@@ -76,22 +259,30 @@ const DetailInfo = () => { {/* Bagian Kanan */}
-
- - - - -
+ {isSaved ? ( + handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer"> + +

Hapus

+
+ ) : ( + doBookmark()} className="flex flex-col mb-3 items-center justify-center cursor-pointer"> + +

Simpan

+
+ )} + {/* garis */}
- + {detailDataImage?.category?.name}
- {detailDataImage?.tags?.split(",").map((tag: string, index: number) => ( -

{tag}

+ {detailDataImage?.tags?.split(",").map((tag: string) => ( + router.push(`/all/filter?tag=${tag}`)} key={tag} className="bg-gray-200 text-gray-700 text-xs px-3 py-1 rounded-full cursor-pointer hover:bg-gray-500"> + {tag} + ))}
@@ -99,30 +290,32 @@ const DetailInfo = () => { {/* Opsi Ukuran Foto */}

Opsi Ukuran Foto

-
- {sizes.map((size) => ( -
+
{/* Comment */}
diff --git a/app/[locale]/(public)/image/filter/page.tsx b/app/[locale]/(public)/image/filter/page.tsx index 9dc22441..f7de461e 100644 --- a/app/[locale]/(public)/image/filter/page.tsx +++ b/app/[locale]/(public)/image/filter/page.tsx @@ -366,7 +366,7 @@ const FilterPage = () => { {/* Left */}
-
+

Filter diff --git a/app/[locale]/(public)/indeks/page.tsx b/app/[locale]/(public)/indeks/page.tsx index cf0057ab..ebf34670 100644 --- a/app/[locale]/(public)/indeks/page.tsx +++ b/app/[locale]/(public)/indeks/page.tsx @@ -66,7 +66,7 @@ const Indeks: React.FC = () => { (indeksRight: any, index: number) => (index == count + 1 || index == count + 2) && (
- image + image
{indeksRight?.categoryName} @@ -96,7 +96,7 @@ const Indeks: React.FC = () => { (indeksBottom: any, index: number) => index < 3 && (
- +

{indeksBottom?.date}

diff --git a/app/[locale]/(public)/video/detail/[slug]/page.tsx b/app/[locale]/(public)/video/detail/[slug]/page.tsx index 39c2a507..8100da31 100644 --- a/app/[locale]/(public)/video/detail/[slug]/page.tsx +++ b/app/[locale]/(public)/video/detail/[slug]/page.tsx @@ -3,12 +3,7 @@ import { useParams, usePathname } from "next/navigation"; import React, { useEffect, useState } from "react"; import { Icon } from "@iconify/react/dist/iconify.js"; -import { - checkWishlistStatus, - deleteWishlist, - getDetail, - saveWishlist, -} from "@/service/landing/landing"; +import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing"; import VideoPlayer from "@/utils/video-player"; import NewContent from "@/components/landing-page/new-content"; import { Link, useRouter } from "@/i18n/routing"; @@ -196,8 +191,7 @@ const DetailVideo = () => { xhr.addEventListener("readystatechange", () => { if (xhr.readyState === 4 && xhr.status === 200) { - const contentType = - xhr.getResponseHeader("content-type") || "application/octet-stream"; + const contentType = xhr.getResponseHeader("content-type") || "application/octet-stream"; const extension = contentType.split("/")[1]; const filename = `${name}.${extension}`; @@ -238,11 +232,8 @@ const DetailVideo = () => {

oleh  - - {detailDataVideo?.uploadedBy?.userLevel?.name} - -  | Diupdate pada {detailDataVideo?.updatedAt}{" "} - WIB |  + {detailDataVideo?.uploadedBy?.userLevel?.name} +  | Diupdate pada {detailDataVideo?.updatedAt} WIB |    {detailDataVideo?.clickCount} @@ -252,9 +243,7 @@ const DetailVideo = () => { {/* Keterangan */}

-

- {detailDataVideo?.title} -

+

{detailDataVideo?.title}

{ {/* Bagian Kanan */}
{isSaved ? ( - handleDeleteWishlist()} - className="flex flex-col mb-3 items-center justify-center cursor-pointer" - > + handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">

Hapus

) : ( - doBookmark()} - className="flex flex-col mb-3 items-center justify-center cursor-pointer" - > + doBookmark()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">

Simpan

@@ -287,20 +270,13 @@ const DetailVideo = () => { {/* garis */}
- + {detailDataVideo?.categoryName}
{detailDataVideo?.tags.split(",").map((tag: string) => ( - router.push(`/all/filter?tag=${tag}`)} - key={tag} - className="bg-gray-200 text-gray-700 text-xs px-3 py-1 rounded-full cursor-pointer hover:bg-gray-500 hover:text-white" - > + router.push(`/all/filter?tag=${tag}`)} key={tag} className="bg-gray-200 text-gray-700 text-xs px-3 py-1 rounded-full cursor-pointer hover:bg-gray-500 hover:text-white"> {tag} ))} @@ -309,60 +285,36 @@ const DetailVideo = () => {
{/* Opsi Ukuran Foto */} -

- Opsi Ukuran Foto -

+

Opsi Ukuran Audio Visual

- {sizes.map((size) => ( -