merge
This commit is contained in:
commit
386419ff1a
|
|
@ -1,24 +1,41 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import NewContent from "@/components/landing-page/new-content";
|
import NewContent from "@/components/landing-page/new-content";
|
||||||
import { Link, useRouter } from "@/i18n/routing";
|
import { Link, useRouter } from "@/i18n/routing";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { BarWave } from "react-cssfx-loading";
|
import { BarWave } from "react-cssfx-loading";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing";
|
import { checkWishlistStatus, createPublicSuggestion, deletePublicSuggestion, deleteWishlist, getDetail, getPublicSuggestionList, saveWishlist } from "@/service/landing/landing";
|
||||||
import { getCookiesDecrypt } from "@/lib/utils";
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
import { close, error, loading, successCallback } from "@/config/swal";
|
import { close, error, loading, successCallback, warning } from "@/config/swal";
|
||||||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||||
|
import parse from "html-react-parser";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
|
const formWaveSurferOptions = (ref: any) => ({
|
||||||
|
container: ref,
|
||||||
|
waveColor: "#eee",
|
||||||
|
progressColor: "OrangeRed",
|
||||||
|
cursorColor: "OrangeRed",
|
||||||
|
barWidth: 3,
|
||||||
|
barRadius: 3,
|
||||||
|
responsive: true,
|
||||||
|
height: 150, // If true, normalize by the maximum peak instead of 1.0.
|
||||||
|
normalize: true, // Use the PeakCache to improve rendering speed of large waveforms.
|
||||||
|
partialRender: true,
|
||||||
|
});
|
||||||
|
|
||||||
const DetailAudio = () => {
|
const DetailAudio = () => {
|
||||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||||
const [selectedTab, setSelectedTab] = useState("video");
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
|
@ -42,8 +59,16 @@ const DetailAudio = () => {
|
||||||
const [width, setWidth] = useState<any>();
|
const [width, setWidth] = useState<any>();
|
||||||
const [content, setContent] = useState<any>([]);
|
const [content, setContent] = useState<any>([]);
|
||||||
const userRoleId = getCookiesDecrypt("urie");
|
const userRoleId = getCookiesDecrypt("urie");
|
||||||
|
const [playing, setPlaying] = useState(false);
|
||||||
|
const wavesurfer = useRef<any>(null);
|
||||||
|
const waveformRef = useRef(null);
|
||||||
|
const [audioLoaded, setAudioLoaded] = useState(false);
|
||||||
|
const [volume, setVolume] = useState<any>(0.5);
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [listSuggestion, setListSuggestion] = useState<any>();
|
||||||
|
const MySwal = withReactContent(Swal);
|
||||||
|
|
||||||
let typeString = "video";
|
let typeString = "audio";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
initFetch();
|
||||||
|
|
@ -53,9 +78,12 @@ const DetailAudio = () => {
|
||||||
const initFetch = async () => {
|
const initFetch = async () => {
|
||||||
const response = await getDetail(String(slug));
|
const response = await getDetail(String(slug));
|
||||||
console.log("detailAudio", response);
|
console.log("detailAudio", response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
|
||||||
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
||||||
setWidth(window.innerWidth);
|
setWidth(window.innerWidth);
|
||||||
setContent(response?.data.data);
|
setContent(response?.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
setMain({
|
setMain({
|
||||||
id: response?.data?.data?.files[0]?.id,
|
id: response?.data?.data?.files[0]?.id,
|
||||||
type: response?.data?.data?.fileType.name,
|
type: response?.data?.data?.fileType.name,
|
||||||
|
|
@ -268,6 +296,11 @@ const DetailAudio = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handlePlayPause = () => {
|
||||||
|
setPlaying(!playing);
|
||||||
|
wavesurfer?.current?.playPause();
|
||||||
|
};
|
||||||
|
|
||||||
const handleEmailList = (e: any) => {
|
const handleEmailList = (e: any) => {
|
||||||
const arrayEmail: any = [];
|
const arrayEmail: any = [];
|
||||||
for (let i = 0; i < emailShareList?.length; i += 1) {
|
for (let i = 0; i < emailShareList?.length; i += 1) {
|
||||||
|
|
@ -284,6 +317,190 @@ const DetailAudio = () => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function initState() {
|
||||||
|
if (typeString == "audio" && main?.url != undefined) {
|
||||||
|
const init = async () => {
|
||||||
|
const { default: WaveSurfer } = await import("wavesurfer.js");
|
||||||
|
|
||||||
|
setPlaying(false);
|
||||||
|
|
||||||
|
const formatTime = function (time: any) {
|
||||||
|
return [
|
||||||
|
Math.floor((time % 3600) / 60),
|
||||||
|
// minutes
|
||||||
|
`00${Math.floor(time % 60)}`.slice(-2), // seconds
|
||||||
|
].join(":");
|
||||||
|
};
|
||||||
|
console.log("AUDIO", main?.url);
|
||||||
|
|
||||||
|
const options = formWaveSurferOptions(waveformRef.current);
|
||||||
|
|
||||||
|
wavesurfer.current = WaveSurfer.create(options);
|
||||||
|
|
||||||
|
wavesurfer.current.load(main?.url);
|
||||||
|
|
||||||
|
wavesurfer.current.on("ready", () => {
|
||||||
|
// https://wavesurfer-js.org/docs/methods.html
|
||||||
|
// wavesurfer.current.playPause();
|
||||||
|
// setPlaying(true);
|
||||||
|
setAudioLoaded(true);
|
||||||
|
// make sure object stillavailable when file loaded
|
||||||
|
if (wavesurfer.current) {
|
||||||
|
wavesurfer.current.setVolume(volume);
|
||||||
|
let volumeNow = volume;
|
||||||
|
setVolume(volumeNow);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".waveform__duration").text(formatTime(wavesurfer.current.getDuration()));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show current time
|
||||||
|
wavesurfer.current.on("audioprocess", () => {
|
||||||
|
$(".waveform__counter").text(formatTime(wavesurfer.current.getCurrentTime()));
|
||||||
|
});
|
||||||
|
|
||||||
|
wavesurfer.current.on("finish", () => {
|
||||||
|
setPlaying(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
// Removes events, elements and disconnects Web Audio nodes.
|
||||||
|
// when component unmount
|
||||||
|
|
||||||
|
return () => wavesurfer?.current?.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initState();
|
||||||
|
}, [main?.url]);
|
||||||
|
|
||||||
|
const onVolumeChange = (e: any) => {
|
||||||
|
const { target } = e;
|
||||||
|
const newVolume = +target?.value;
|
||||||
|
|
||||||
|
if (newVolume) {
|
||||||
|
setVolume(newVolume);
|
||||||
|
wavesurfer?.current?.setVolume(newVolume || 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function sendSuggestionChild(parentId: any) {
|
||||||
|
const inputElement = document.querySelector(`#input-comment-${parentId}`) as HTMLInputElement;
|
||||||
|
|
||||||
|
if (inputElement && inputElement.value.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message: inputElement.value,
|
||||||
|
parentId,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet: any = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
|
||||||
|
// Reset input field
|
||||||
|
inputElement.value = "";
|
||||||
|
|
||||||
|
// document.querySelector("#comment-id-" + parentId)?.style.display = "none";
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function deleteDataSuggestion(dataId: any) {
|
||||||
|
loading();
|
||||||
|
const response = await deletePublicSuggestion(dataId);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
const deleteData = (dataId: any) => {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Delete Comment",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonColor: "#3085d6",
|
||||||
|
confirmButtonColor: "#d33",
|
||||||
|
confirmButtonText: "Delete",
|
||||||
|
}).then((result: any) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
deleteDataSuggestion(dataId);
|
||||||
|
console.log(dataId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const showInput = (e: any) => {
|
||||||
|
console.log(document.querySelector(`#${e}`)?.classList);
|
||||||
|
document.querySelector(`#${e}`)?.classList.toggle("hidden");
|
||||||
|
};
|
||||||
|
function addDefaultProfile(ev: any) {
|
||||||
|
ev.target.src = "/assets/avatar-profile.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendSuggestionParent() {
|
||||||
|
if (message?.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message,
|
||||||
|
parentId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
setMessage("");
|
||||||
|
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet?.data?.data);
|
||||||
|
setListSuggestion(responseGet?.data?.data);
|
||||||
|
|
||||||
|
// Hapus nilai semua input secara manual jika perlu
|
||||||
|
const inputs = document.querySelectorAll("input");
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
input.value = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const getInputValue = (e: any) => {
|
||||||
|
const message = e.target.value;
|
||||||
|
console.log(message);
|
||||||
|
setMessage(message);
|
||||||
|
};
|
||||||
|
const postData = () => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionParent();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const postDataChild = (id: any) => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionChild(id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="min-h-screen px-4 md:px-24 py-4">
|
<div className="min-h-screen px-4 md:px-24 py-4">
|
||||||
|
|
@ -291,11 +508,48 @@ const DetailAudio = () => {
|
||||||
<div className="rounded-md overflow-hidden md:flex">
|
<div className="rounded-md overflow-hidden md:flex">
|
||||||
{/* Bagian Kiri */}
|
{/* Bagian Kiri */}
|
||||||
<div className="md:w-3/4">
|
<div className="md:w-3/4">
|
||||||
<div className="relative flex justify-center">
|
<div className="relative flex flex-row">
|
||||||
<img src="/assets/audio-btn.png" />
|
<button onClick={handlePlayPause}>
|
||||||
<BarWave color="#ffc831" width="60px" height="25px" duration="2s" />
|
<img src={`/assets/${playing ? "stop-icon.png" : "play-icon.png"}`} />
|
||||||
<div className="absolute top-4 left-4"></div>
|
</button>
|
||||||
|
<div
|
||||||
|
className="flex items-center "
|
||||||
|
style={
|
||||||
|
audioLoaded
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<BarWave color="#ffc831" width="60px" height="25px" duration="2s " />
|
||||||
|
</div>
|
||||||
|
<div id="waveform" ref={waveformRef} className="w-[700px] ml-12" />
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-row mt-2"
|
||||||
|
style={
|
||||||
|
audioLoaded
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none !important",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Icon icon="fa:volume-up" />
|
||||||
|
{/* <Slider onChange={onVolumeChange} defaultValue={volume} /> */}
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
id="volume"
|
||||||
|
name="volume"
|
||||||
|
min="0.01"
|
||||||
|
max="1"
|
||||||
|
step=".025"
|
||||||
|
onChange={onVolumeChange}
|
||||||
|
defaultValue={volume}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Footer Informasi */}
|
{/* Footer Informasi */}
|
||||||
<div className="p-4 text-sm text-gray-500 flex justify-between items-center border-t mt-4">
|
<div className="p-4 text-sm text-gray-500 flex justify-between items-center border-t mt-4">
|
||||||
<p className="flex flex-row items-center">
|
<p className="flex flex-row items-center">
|
||||||
|
|
@ -307,7 +561,7 @@ const DetailAudio = () => {
|
||||||
<p>Kreator: {detailDataAudio?.creatorName}</p>
|
<p>Kreator: {detailDataAudio?.creatorName}</p>
|
||||||
</div>
|
</div>
|
||||||
{/* Keterangan */}
|
{/* Keterangan */}
|
||||||
<div className="md:w-3/4">
|
<div className="w-full">
|
||||||
<h1 className="flex flex-row font-bold text-2xl mx-5 my-8">{detailDataAudio?.title}</h1>
|
<h1 className="flex flex-row font-bold text-2xl mx-5 my-8">{detailDataAudio?.title}</h1>
|
||||||
<div className="font-light text-justify" dangerouslySetInnerHTML={{ __html: detailDataAudio?.htmlDescription }} />
|
<div className="font-light text-justify" dangerouslySetInnerHTML={{ __html: detailDataAudio?.htmlDescription }} />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -417,10 +671,175 @@ const DetailAudio = () => {
|
||||||
|
|
||||||
<div className="w-full mb-8">
|
<div className="w-full mb-8">
|
||||||
{/* Comment */}
|
{/* Comment */}
|
||||||
<div className="flex flex-col my-16 gap-5 p-10 bg-gray-300">
|
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
||||||
<p className="flex items-start text-lg">Berikan Komentar</p>
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<Textarea placeholder="Type your comments here." className="flex items-start justify-center" />
|
<p className="flex items-start text-lg">Berikan Komentar</p>
|
||||||
<button className="flex items-start bg-[#bb3523] rounded-lg w-fit px-4 py-1">Kirim</button>
|
<Textarea placeholder="Type your comments here." className="flex w-full py-8" onChange={getInputValue} />
|
||||||
|
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
|
||||||
|
Kirim
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border-b-2 border-slate-300 mt-4 w-auto"></div>
|
||||||
|
|
||||||
|
<div className="overflow-y-auto">
|
||||||
|
{listSuggestion?.map((data: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-14">
|
||||||
|
<img src={data?.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{Number(data.suggestionFrom?.roleId) == 2 || Number(data.suggestionFrom?.roleId) == 3 || Number(data.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : data.suggestionFrom?.fullname}
|
||||||
|
{getPublicLocaleTimestamp(new Date(data.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{data?.message}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(data.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${data.id}`)}
|
||||||
|
className="mr-2"
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
{Number(data.suggestionFrom?.id) == Number(userId) || Number(userRoleId) == 2 ? (
|
||||||
|
<a onClick={() => deleteData(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${data.id}`} className="px-4 lg:px-28 mt-2">
|
||||||
|
<Textarea id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 mt-2 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${data.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg mt-2 w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{data.children.length > 0
|
||||||
|
? data.children?.map((child1: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-32">
|
||||||
|
<img src={child1.suggestionFrom?.profilePictureUrl} onError={addDefaultProfile} alt="" className="h-16 w-16 mr-2" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child1.suggestionFrom?.roleId) == 2 || Number(child1.suggestionFrom?.roleId) == 3 || Number(child1.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child1.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child1.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child1?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child1.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child1.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${child1.id}`} className="px-4 lg:px-40">
|
||||||
|
<Textarea name="" className="mt-2 " id={`input-comment-${child1.id}`} placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row mt-2 gap-3">
|
||||||
|
<a onClick={() => postDataChild(child1.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child1.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{child1.children.length > 0
|
||||||
|
? child1.children?.map((child2: any) => (
|
||||||
|
<div className="">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-48">
|
||||||
|
<img src={child2.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child2.suggestionFrom?.roleId) == 2 || Number(child2.suggestionFrom?.roleId) == 3 || Number(child2.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child2.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child2.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child2?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child2.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child2.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id={`comment-id-${child2.id}`} className="px-4 lg:px-52">
|
||||||
|
<Textarea name="" id={`input-comment-${child2.id}`} className="my-2" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(child2.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child2.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Konten Serupa */}
|
{/* Konten Serupa */}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react";
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import { formatDateToIndonesian, getOnlyDate, getOnlyMonthAndYear } from "@/utils/globals";
|
import { formatDateToIndonesian, getOnlyDate, getOnlyMonthAndYear, secondToTimes } from "@/utils/globals";
|
||||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||||
import { getUserLevelListByParent, listCategory, listData, listDataRegional } from "@/service/landing/landing";
|
import { getUserLevelListByParent, listCategory, listData, listDataRegional } from "@/service/landing/landing";
|
||||||
import { ColumnDef, ColumnFiltersState, PaginationState, SortingState, VisibilityState, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
|
import { ColumnDef, ColumnFiltersState, PaginationState, SortingState, VisibilityState, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
|
||||||
|
|
@ -155,7 +155,8 @@ const FilterPage = () => {
|
||||||
startDateString,
|
startDateString,
|
||||||
endDateString,
|
endDateString,
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : ""
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "",
|
||||||
|
locale == "en" ? true : false
|
||||||
);
|
);
|
||||||
close();
|
close();
|
||||||
// setGetTotalPage(response?.data?.data?.totalPages);
|
// setGetTotalPage(response?.data?.data?.totalPages);
|
||||||
|
|
@ -187,7 +188,8 @@ const FilterPage = () => {
|
||||||
startDateString,
|
startDateString,
|
||||||
endDateString,
|
endDateString,
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : ""
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "",
|
||||||
|
locale == "en" ? true : false
|
||||||
);
|
);
|
||||||
close();
|
close();
|
||||||
// setGetTotalPage(response?.data?.data?.totalPages);
|
// setGetTotalPage(response?.data?.data?.totalPages);
|
||||||
|
|
@ -243,7 +245,7 @@ const FilterPage = () => {
|
||||||
const format = formatFilter == undefined ? "" : formatFilter?.join(",");
|
const format = formatFilter == undefined ? "" : formatFilter?.join(",");
|
||||||
loading();
|
loading();
|
||||||
const response = await listDataRegional(
|
const response = await listDataRegional(
|
||||||
"1",
|
"4",
|
||||||
name,
|
name,
|
||||||
filter,
|
filter,
|
||||||
format,
|
format,
|
||||||
|
|
@ -425,7 +427,7 @@ const FilterPage = () => {
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-sm font-medium text-gray-700 dark:text-white">{t("categories")}</h3>
|
<h3 className="text-sm font-medium text-gray-700 dark:text-white">{t("categories")}</h3>
|
||||||
<ul className="mt-2 space-y-2">
|
<ul className="mt-2 space-y-2">
|
||||||
{categories.map((category: any) => (
|
{categories?.map((category: any) => (
|
||||||
<li key={category?.id}>
|
<li key={category?.id}>
|
||||||
<label className="inline-flex items-center" htmlFor={`${category.id}`}>
|
<label className="inline-flex items-center" htmlFor={`${category.id}`}>
|
||||||
<Checkbox id={`${category.id}`} value={category.id} checked={categoryFilter.includes(String(category.id))} onCheckedChange={(e) => handleCategoryFilter(Boolean(e), category.id)} />
|
<Checkbox id={`${category.id}`} value={category.id} checked={categoryFilter.includes(String(category.id))} onCheckedChange={(e) => handleCategoryFilter(Boolean(e), category.id)} />
|
||||||
|
|
@ -465,59 +467,63 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Konten Kanan */}
|
{/* Konten Kanan */}
|
||||||
<Reveal>
|
<div className="w-[75%]">
|
||||||
<div className="flex-1">
|
<div className="flex flex-col items-end mb-4">
|
||||||
<div className="flex flex-col items-end mb-4">
|
<h2 className="text-lg font-semibold">{t("sortBy")} </h2>
|
||||||
<h2 className="text-lg font-semibold">{t("sortBy")} </h2>
|
<select defaultValue={sortBy == "popular" ? "terpopuler" : "terbaru"} onChange={(e) => handleSorting(e)} className="border rounded-md py-2 px-3 focus:ring-red-500 focus:border-red-500">
|
||||||
<select defaultValue={sortBy == "popular" ? "terpopuler" : "terbaru"} onChange={(e) => handleSorting(e)} className="border rounded-md py-2 px-3 focus:ring-red-500 focus:border-red-500">
|
<option value="latest">{t("latest")}</option>
|
||||||
<option value="latest">{t("latest")}</option>
|
<option value="popular">{t("mostPopular")}</option>
|
||||||
<option value="popular">{t("mostPopular")}</option>
|
</select>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{audioData?.length > 0 ? (
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
||||||
{audioData?.map((image: any) => (
|
|
||||||
<Carousel className="w-full max-w-7xl mx-auto">
|
|
||||||
<CarouselContent>
|
|
||||||
{audioData?.map((audio: any) => (
|
|
||||||
<CarouselItem key={audio?.id} className="md:basis-1/2 lg:basis-1/3">
|
|
||||||
<div className="flex flex-row gap-6">
|
|
||||||
<Link href={`/audio/detail/${audio?.slug}`} className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer 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-16 h-8 lg:h-16">
|
|
||||||
<svg width="32" height="34" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path
|
|
||||||
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
|
|
||||||
fill="white"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col flex-1">
|
|
||||||
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
|
|
||||||
{formatDateToIndonesian(new Date(audio?.createdAt))} {audio?.timezone ? audio?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {audio?.clickCount}{" "}
|
|
||||||
</div>
|
|
||||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{audio?.title}</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<p className="flex items-center justify-center text-black">
|
|
||||||
<img src="/assets/empty-data.png" alt="empty" className="h-60 w-60 my-4" />
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<LandingPagination table={table} totalData={totalData} totalPage={totalPage} />
|
|
||||||
</div>
|
</div>
|
||||||
</Reveal>
|
|
||||||
|
{audioData?.length > 0 ? (
|
||||||
|
<div className="">
|
||||||
|
{audioData?.map((audio: any) => (
|
||||||
|
<div key={audio?.id}>
|
||||||
|
<Link href={`/audio/detail/${audio?.slug}`} className="flex flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
|
||||||
|
<div className="flex justify-between w-full gap-6">
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<div className="flex items-center justify-center bg-red-500 text-white rounded-lg w-16 h-8 lg:h-16">
|
||||||
|
<svg width="32" height="34" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm items-center">
|
||||||
|
{formatDateToIndonesian(new Date(audio?.createdAt))} {audio?.timezone ? audio?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" />
|
||||||
|
{audio?.clickCount}{" "}
|
||||||
|
</div>
|
||||||
|
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{audio?.title}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-row items-center place-content-end gap-3">
|
||||||
|
<img src="/assets/wave.svg" alt="wave" className="h-16" />
|
||||||
|
<svg width="17" height="20" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<p className="text-sm text-center"> {audio?.duration ? secondToTimes(Number(audio?.duration)) : "00:00:00"}</p>
|
||||||
|
<Icon icon="ph:download-fill" className="text-red-500" fontSize={20} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p className="flex items-center justify-center text-black">
|
||||||
|
<img src="/assets/empty-data.png" alt="empty" className="h-60 w-60 my-4" />
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<LandingPagination table={table} totalData={totalData} totalPage={totalPage} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import ImageBlurry from "@/components/ui/image-blurry";
|
||||||
|
|
||||||
const Galery = (props: any) => {
|
const Galery = (props: any) => {
|
||||||
const [profile, setProfile] = useState<any>();
|
const [profile, setProfile] = useState<any>();
|
||||||
const [selectedTab, setSelectedTab] = useState("video");
|
const [selectedTab, setSelectedTab] = useState("image");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
@ -336,11 +336,15 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<Link href={`/content-management/rewrite/create/${video?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex items-center gap-3">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -359,7 +363,7 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(video?.id)} className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<a onClick={() => handleDelete(video?.id)} className="flex items-center gap-3 hover:text-red-800 w-full rounded-lg">
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
<Icon icon="fa:trash" fontSize={20} />
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
<p className="text-base font-semibold">Hapus</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -414,11 +418,15 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<Link href={`/content-management/rewrite/create/${audio?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex items-center gap-3">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -437,7 +445,7 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(audio?.id)} className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<a onClick={() => handleDelete(audio?.id)} className="flex items-center gap-3 hover:text-red-800 w-full rounded-lg">
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
<Icon icon="fa:trash" fontSize={20} />
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
<p className="text-base font-semibold">Hapus</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -470,11 +478,15 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<Link href={`/content-management/rewrite/create/${image?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex items-center gap-3">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -493,7 +505,7 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(image?.id)} className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<a onClick={() => handleDelete(image?.id)} className="flex items-center gap-3 hover:text-red-800 w-full rounded-lg">
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
<Icon icon="fa:trash" fontSize={20} />
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
<p className="text-base font-semibold">Hapus</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -538,11 +550,15 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<Link href={`/content-management/rewrite/create/${document?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex items-center gap-3">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -561,7 +577,7 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(document?.id)} className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<a onClick={() => handleDelete(document?.id)} className="flex items-center gap-3 hover:text-red-800 w-full rounded-lg">
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
<Icon icon="fa:trash" fontSize={20} />
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
<p className="text-base font-semibold">Hapus</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import ImageBlurry from "@/components/ui/image-blurry";
|
||||||
|
|
||||||
const Galery = (props: any) => {
|
const Galery = (props: any) => {
|
||||||
const [profile, setProfile] = useState<any>();
|
const [profile, setProfile] = useState<any>();
|
||||||
const [selectedTab, setSelectedTab] = useState("video");
|
const [selectedTab, setSelectedTab] = useState("image");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
@ -342,13 +342,21 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<div onClick={() => handleSaveWishlist(video?.mediaUpload?.id)} className="cursor-pointer flex flex-row gap-2 hover:text-red-800">
|
||||||
|
<Icon icon="material-symbols:bookmark-outline" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Simpan</p>
|
||||||
|
</div>
|
||||||
|
<Link href={`/content-management/rewrite/create/${video?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex flex-row items-center gap-3">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base items-center font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-1">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent>
|
<PopoverContent>
|
||||||
|
|
@ -365,10 +373,6 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(video?.id)} className="flex items-center gap-2 hover:text-red-800 w-full rounded-lg">
|
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
|
||||||
</a>
|
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -418,13 +422,21 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<div onClick={() => handleSaveWishlist(audio?.mediaUpload?.id)} className="cursor-pointer flex flex-row gap-2 hover:text-red-800">
|
||||||
|
<Icon icon="material-symbols:bookmark-outline" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Simpan</p>
|
||||||
|
</div>
|
||||||
|
<Link href={`/content-management/rewrite/create/${audio?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex items-center gap-2">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-2">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent>
|
<PopoverContent>
|
||||||
|
|
@ -441,10 +453,6 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(audio?.id)} className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
|
||||||
</a>
|
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -474,13 +482,21 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<div onClick={() => handleSaveWishlist(image?.mediaUpload?.id)} className="cursor-pointer flex flex-row gap-2 hover:text-red-800">
|
||||||
|
<Icon icon="material-symbols:bookmark-outline" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Simpan</p>
|
||||||
|
</div>
|
||||||
|
<Link href={`/content-management/rewrite/create/${image?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex items-center gap-2">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-2">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent>
|
<PopoverContent>
|
||||||
|
|
@ -497,10 +513,6 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(image?.id)} className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
|
||||||
</a>
|
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
@ -542,13 +554,21 @@ const Galery = (props: any) => {
|
||||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-40">
|
<PopoverContent className="w-52">
|
||||||
|
<div onClick={() => handleSaveWishlist(document?.mediaUpload?.id)} className="cursor-pointer flex flex-row gap-2 hover:text-red-800">
|
||||||
|
<Icon icon="material-symbols:bookmark-outline" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Simpan</p>
|
||||||
|
</div>
|
||||||
|
<Link href={`/content-management/rewrite/create/${document?.mediaUpload?.id}`} className="flex flex-row hover:text-red-800 gap-2">
|
||||||
|
<Icon icon="jam:write" fontSize={25} />
|
||||||
|
<p className="text-base font-semibold mb-2">Content Rewrite</p>
|
||||||
|
</Link>
|
||||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="w-full flex items-center gap-2">
|
<button className="w-full flex items-center gap-2">
|
||||||
<Icon icon="oi:share" fontSize={20} />
|
<Icon icon="oi:share" fontSize={20} />
|
||||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
<p className="text-base font-semibold mb-2">Bagikan</p>
|
||||||
</button>
|
</button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent>
|
<PopoverContent>
|
||||||
|
|
@ -565,10 +585,6 @@ const Galery = (props: any) => {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={() => handleDelete(document?.id)} className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
|
||||||
<Icon icon="fa:trash" fontSize={20} />
|
|
||||||
<p className="text-base font-semibold">Hapus</p>
|
|
||||||
</a>
|
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,15 @@ import HeaderManagement from "@/components/landing-page/header-management";
|
||||||
import SidebarManagement from "@/components/landing-page/sidebar-management";
|
import SidebarManagement from "@/components/landing-page/sidebar-management";
|
||||||
import { close, error, loading } from "@/config/swal";
|
import { close, error, loading } from "@/config/swal";
|
||||||
import { getCookiesDecrypt } from "@/lib/utils";
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
import { getInfoProfile, getUsersTeams } from "@/service/landing/landing";
|
import { getInfoProfile, getUsersTeams, saveUserReports } from "@/service/landing/landing";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
import { saveUserReports } from "@/service/content/content";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
|
import { ToastAction } from "@/components/ui/toast";
|
||||||
|
|
||||||
const page = () => {
|
const page = () => {
|
||||||
const [user, setUser] = useState<any>();
|
const [user, setUser] = useState<any>();
|
||||||
|
|
@ -19,6 +21,8 @@ const page = () => {
|
||||||
const [userSelected, setUserSelected] = useState();
|
const [userSelected, setUserSelected] = useState();
|
||||||
const [reportMessage, setReportMessage] = useState<string>();
|
const [reportMessage, setReportMessage] = useState<string>();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
|
const { toast } = useToast();
|
||||||
|
const [reportMessageOpen, setReportMessageOpen] = useState(false);
|
||||||
|
|
||||||
// const launchModal = (user: any) => {
|
// const launchModal = (user: any) => {
|
||||||
// setUserSelected(user);
|
// setUserSelected(user);
|
||||||
|
|
@ -41,6 +45,8 @@ const page = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
|
setReportMessageOpen(false);
|
||||||
|
|
||||||
loading();
|
loading();
|
||||||
const data = {
|
const data = {
|
||||||
userId: user?.id,
|
userId: user?.id,
|
||||||
|
|
@ -50,13 +56,24 @@ const page = () => {
|
||||||
const response = await saveUserReports(data);
|
const response = await saveUserReports(data);
|
||||||
|
|
||||||
if (response?.error) {
|
if (response?.error) {
|
||||||
error(response?.message);
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "Uh oh! Something went wrong.",
|
||||||
|
});
|
||||||
|
// error(response?.message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
|
||||||
successSubmit();
|
toast({
|
||||||
|
title: "Success !!",
|
||||||
|
});
|
||||||
|
|
||||||
|
// toast.success("SUKSES !!", {
|
||||||
|
// position: "top-right",
|
||||||
|
// });
|
||||||
|
// successSubmit();
|
||||||
}
|
}
|
||||||
|
|
||||||
function successSubmit() {
|
function successSubmit() {
|
||||||
|
|
@ -136,9 +153,9 @@ const page = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-black w-full"></div>
|
<div className="border-b border-black w-full"></div>
|
||||||
<div className="place-items-end">
|
<div className="place-items-end">
|
||||||
<Dialog>
|
<Dialog open={reportMessageOpen} onOpenChange={setReportMessageOpen}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="outline" className="bg-red-500 rounded-md">
|
<Button variant="outline" className="bg-red-500 rounded-md text-white hover:bg-white hover:text-red-500">
|
||||||
Report
|
Report
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
@ -150,13 +167,28 @@ const page = () => {
|
||||||
<div className="border-b border-black w-full"></div>
|
<div className="border-b border-black w-full"></div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<h1 className="text-red-600 mb-2">Alasan Report Akun</h1>
|
<h1 className="text-red-600 mb-2">Alasan Report Akun</h1>
|
||||||
<textarea id="formControlTextarea1" rows={4} className="border border-black font-light" onChange={(e) => setReportMessage(e.target.value)} />
|
<textarea id="formControlTextarea1" rows={4} className="border border-black font-light" onChange={(e: any) => setReportMessage(e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button className="bg-red-500 text-white" type="submit" onClick={() => onSubmit()}>
|
<Dialog>
|
||||||
Kirim
|
<DialogTrigger asChild>
|
||||||
</Button>
|
<Button className="bg-red-500 text-white" type="submit">
|
||||||
|
Kirim
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent>
|
||||||
|
<h1>Simpan Data?</h1>
|
||||||
|
<DialogFooter>
|
||||||
|
<DialogClose>
|
||||||
|
<Button onClick={save}>Simpan</Button>
|
||||||
|
</DialogClose>
|
||||||
|
<DialogClose>
|
||||||
|
<Button>Cancel</Button>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,18 @@ import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import NewContent from "@/components/landing-page/new-content";
|
import NewContent from "@/components/landing-page/new-content";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { getCookiesDecrypt } from "@/lib/utils";
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing";
|
import { checkWishlistStatus, createPublicSuggestion, deletePublicSuggestion, deleteWishlist, getDetail, getPublicSuggestionList, saveWishlist } from "@/service/landing/landing";
|
||||||
import { close, error, loading, successCallback } from "@/config/swal";
|
import { close, error, loading, successCallback, warning } from "@/config/swal";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { Link, useRouter } from "@/i18n/routing";
|
import { Link, useRouter } from "@/i18n/routing";
|
||||||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import parse from "html-react-parser";
|
||||||
|
|
||||||
const DetailDocument = () => {
|
const DetailDocument = () => {
|
||||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||||
|
|
@ -42,8 +46,11 @@ const DetailDocument = () => {
|
||||||
const [width, setWidth] = useState<any>();
|
const [width, setWidth] = useState<any>();
|
||||||
const [content, setContent] = useState<any>([]);
|
const [content, setContent] = useState<any>([]);
|
||||||
const userRoleId = getCookiesDecrypt("urie");
|
const userRoleId = getCookiesDecrypt("urie");
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [listSuggestion, setListSuggestion] = useState<any>();
|
||||||
|
const MySwal = withReactContent(Swal);
|
||||||
|
|
||||||
let typeString = "video";
|
let typeString = "document";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
initFetch();
|
||||||
|
|
@ -53,9 +60,12 @@ const DetailDocument = () => {
|
||||||
const initFetch = async () => {
|
const initFetch = async () => {
|
||||||
const response = await getDetail(String(slug));
|
const response = await getDetail(String(slug));
|
||||||
console.log("detailDocument", response);
|
console.log("detailDocument", response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
|
||||||
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
||||||
setWidth(window.innerWidth);
|
setWidth(window.innerWidth);
|
||||||
setContent(response?.data.data);
|
setContent(response?.data.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
setMain({
|
setMain({
|
||||||
id: response?.data?.data?.files[0]?.id,
|
id: response?.data?.data?.files[0]?.id,
|
||||||
type: response?.data?.data?.fileType.name,
|
type: response?.data?.data?.fileType.name,
|
||||||
|
|
@ -284,6 +294,121 @@ const DetailDocument = () => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function sendSuggestionChild(parentId: any) {
|
||||||
|
const inputElement = document.querySelector(`#input-comment-${parentId}`) as HTMLInputElement;
|
||||||
|
|
||||||
|
if (inputElement && inputElement.value.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message: inputElement.value,
|
||||||
|
parentId,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet: any = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
|
||||||
|
// Reset input field
|
||||||
|
inputElement.value = "";
|
||||||
|
|
||||||
|
// document.querySelector("#comment-id-" + parentId)?.style.display = "none";
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function deleteDataSuggestion(dataId: any) {
|
||||||
|
loading();
|
||||||
|
const response = await deletePublicSuggestion(dataId);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
const deleteData = (dataId: any) => {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Delete Comment",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonColor: "#3085d6",
|
||||||
|
confirmButtonColor: "#d33",
|
||||||
|
confirmButtonText: "Delete",
|
||||||
|
}).then((result: any) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
deleteDataSuggestion(dataId);
|
||||||
|
console.log(dataId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const showInput = (e: any) => {
|
||||||
|
console.log(document.querySelector(`#${e}`)?.classList);
|
||||||
|
document.querySelector(`#${e}`)?.classList.toggle("hidden");
|
||||||
|
};
|
||||||
|
function addDefaultProfile(ev: any) {
|
||||||
|
ev.target.src = "/assets/avatar-profile.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendSuggestionParent() {
|
||||||
|
if (message?.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message,
|
||||||
|
parentId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
setMessage("");
|
||||||
|
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet?.data?.data);
|
||||||
|
setListSuggestion(responseGet?.data?.data);
|
||||||
|
|
||||||
|
// Hapus nilai semua input secara manual jika perlu
|
||||||
|
const inputs = document.querySelectorAll("input");
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
input.value = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const getInputValue = (e: any) => {
|
||||||
|
const message = e.target.value;
|
||||||
|
console.log(message);
|
||||||
|
setMessage(message);
|
||||||
|
};
|
||||||
|
const postData = () => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionParent();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const postDataChild = (id: any) => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionChild(id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="px-4 md:px-24 py-4">
|
<div className="px-4 md:px-24 py-4">
|
||||||
|
|
@ -306,8 +431,8 @@ const DetailDocument = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Keterangan */}
|
{/* Keterangan */}
|
||||||
<div className="md:w-3/4">
|
<div className="">
|
||||||
<h1 className="flex flex-row font-bold text-2xl my-8">{detailDataDocument?.title}</h1>
|
<h1 className="flex flex-row font-bold text-2xl my-8 text-justify">{detailDataDocument?.title}</h1>
|
||||||
<div dangerouslySetInnerHTML={{ __html: detailDataDocument?.htmlDescription }} />
|
<div dangerouslySetInnerHTML={{ __html: detailDataDocument?.htmlDescription }} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -415,10 +540,173 @@ const DetailDocument = () => {
|
||||||
<div className="w-full mb-8">
|
<div className="w-full mb-8">
|
||||||
{/* Comment */}
|
{/* Comment */}
|
||||||
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-16">
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<p className="flex items-start text-lg">Berikan Komentar</p>
|
<p className="flex items-start text-lg">Berikan Komentar</p>
|
||||||
<Textarea placeholder="Type your comments here." className="flex w-full" />
|
<Textarea placeholder="Type your comments here." className="flex w-full py-8" onChange={getInputValue} />
|
||||||
<button className="flex items-start bg-[#bb3523] rounded-lg text-white w-fit px-4 py-1">Kirim</button>
|
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
|
||||||
|
Kirim
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border-b-2 border-slate-300 mt-4 w-auto"></div>
|
||||||
|
|
||||||
|
<div className="overflow-y-auto">
|
||||||
|
{listSuggestion?.map((data: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-14">
|
||||||
|
<img src={data?.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{Number(data.suggestionFrom?.roleId) == 2 || Number(data.suggestionFrom?.roleId) == 3 || Number(data.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : data.suggestionFrom?.fullname}
|
||||||
|
{getPublicLocaleTimestamp(new Date(data.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{data?.message}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(data.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${data.id}`)}
|
||||||
|
className="mr-2"
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
{Number(data.suggestionFrom?.id) == Number(userId) || Number(userRoleId) == 2 ? (
|
||||||
|
<a onClick={() => deleteData(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${data.id}`} className="px-4 lg:px-28 mt-2">
|
||||||
|
<Textarea id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 mt-2 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${data.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg mt-2 w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{data.children.length > 0
|
||||||
|
? data.children?.map((child1: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-32">
|
||||||
|
<img src={child1.suggestionFrom?.profilePictureUrl} onError={addDefaultProfile} alt="" className="h-16 w-16 mr-2" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child1.suggestionFrom?.roleId) == 2 || Number(child1.suggestionFrom?.roleId) == 3 || Number(child1.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child1.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child1.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child1?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child1.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child1.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${child1.id}`} className="px-4 lg:px-40">
|
||||||
|
<Textarea name="" className="mt-2 " id={`input-comment-${child1.id}`} placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row mt-2 gap-3">
|
||||||
|
<a onClick={() => postDataChild(child1.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child1.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{child1.children.length > 0
|
||||||
|
? child1.children?.map((child2: any) => (
|
||||||
|
<div className="">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-48">
|
||||||
|
<img src={child2.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child2.suggestionFrom?.roleId) == 2 || Number(child2.suggestionFrom?.roleId) == 3 || Number(child2.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child2.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child2.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child2?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child2.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child2.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id={`comment-id-${child2.id}`} className="px-4 lg:px-52">
|
||||||
|
<Textarea name="" id={`input-comment-${child2.id}`} className="my-2" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(child2.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child2.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,8 @@ const FilterPage = () => {
|
||||||
startDateString,
|
startDateString,
|
||||||
endDateString,
|
endDateString,
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : ""
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "",
|
||||||
|
locale == "en" ? true : false
|
||||||
);
|
);
|
||||||
close();
|
close();
|
||||||
// setGetTotalPage(response?.data?.data?.totalPages);
|
// setGetTotalPage(response?.data?.data?.totalPages);
|
||||||
|
|
@ -185,7 +186,8 @@ const FilterPage = () => {
|
||||||
startDateString,
|
startDateString,
|
||||||
endDateString,
|
endDateString,
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : ""
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "",
|
||||||
|
locale == "en" ? true : false
|
||||||
);
|
);
|
||||||
close();
|
close();
|
||||||
// setGetTotalPage(response?.data?.data?.totalPages);
|
// setGetTotalPage(response?.data?.data?.totalPages);
|
||||||
|
|
@ -282,20 +284,20 @@ const FilterPage = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
initFetch();
|
// initFetch();
|
||||||
}, [page]);
|
// }, [page]);
|
||||||
|
|
||||||
const initFetch = async () => {
|
// const initFetch = async () => {
|
||||||
const response = await getListContent({ page: page - 1, size: 6, sortBy: "createdAt", contentTypeId: "3", isInt: locale == "en" ? true : false });
|
// const response = await getListContent({ page: page - 1, size: 6, sortBy: "createdAt", contentTypeId: "3", isInt: locale == "en" ? true : false });
|
||||||
console.log(response);
|
// console.log(response);
|
||||||
setDocumentData(response?.data?.data?.content);
|
// setDocumentData(response?.data?.data?.content);
|
||||||
const data = response?.data?.data;
|
// const data = response?.data?.data;
|
||||||
const contentData = data?.content;
|
// const contentData = data?.content;
|
||||||
setDocumentData(contentData);
|
// setDocumentData(contentData);
|
||||||
setTotalData(data?.totalElements);
|
// setTotalData(data?.totalElements);
|
||||||
setTotalPage(data?.totalPages);
|
// setTotalPage(data?.totalPages);
|
||||||
};
|
// };
|
||||||
|
|
||||||
function getSelectedCategory() {
|
function getSelectedCategory() {
|
||||||
const filter = [];
|
const filter = [];
|
||||||
|
|
@ -382,7 +384,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
||||||
<div className="lg:w-[25%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
<div className="lg:w-[45%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
||||||
<Icon icon="stash:filter-light" fontSize={30} />
|
<Icon icon="stash:filter-light" fontSize={30} />
|
||||||
Filter
|
Filter
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,20 @@ import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import NewContent from "@/components/landing-page/new-content";
|
import NewContent from "@/components/landing-page/new-content";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { getCookiesDecrypt } from "@/lib/utils";
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
import { close, error, loading, successCallback } from "@/config/swal";
|
import { close, error, loading, successCallback, warning } from "@/config/swal";
|
||||||
import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing";
|
import { checkWishlistStatus, createPublicSuggestion, deletePublicSuggestion, deleteWishlist, getDetail, getPublicSuggestionList, saveWishlist } from "@/service/landing/landing";
|
||||||
import { Link, useRouter } from "@/i18n/routing";
|
import { Link, useRouter } from "@/i18n/routing";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||||
|
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import parse from "html-react-parser";
|
||||||
|
|
||||||
const DetailInfo = () => {
|
const DetailInfo = () => {
|
||||||
|
const MySwal = withReactContent(Swal);
|
||||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||||
const [selectedTab, setSelectedTab] = useState("video");
|
const [selectedTab, setSelectedTab] = useState("video");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
@ -39,11 +44,12 @@ const DetailInfo = () => {
|
||||||
const [emailShareInput, setEmailShareInput] = useState<any>();
|
const [emailShareInput, setEmailShareInput] = useState<any>();
|
||||||
const [emailMessageInput, setEmailMessageInput] = useState();
|
const [emailMessageInput, setEmailMessageInput] = useState();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const id = searchParams?.get("id");
|
|
||||||
const [width, setWidth] = useState<any>();
|
const [width, setWidth] = useState<any>();
|
||||||
const userRoleId = getCookiesDecrypt("urie");
|
const userRoleId = getCookiesDecrypt("urie");
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [listSuggestion, setListSuggestion] = useState<any>();
|
||||||
|
|
||||||
let typeString = "video";
|
let typeString = "image";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
initFetch();
|
||||||
|
|
@ -53,9 +59,12 @@ const DetailInfo = () => {
|
||||||
const initFetch = async () => {
|
const initFetch = async () => {
|
||||||
const response = await getDetail(String(slug));
|
const response = await getDetail(String(slug));
|
||||||
console.log("detailImage", response);
|
console.log("detailImage", response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
|
||||||
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
||||||
setWidth(window.innerWidth);
|
setWidth(window.innerWidth);
|
||||||
setContent(response?.data.data);
|
setContent(response?.data.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
setMain({
|
setMain({
|
||||||
id: response?.data?.data?.files[0]?.id,
|
id: response?.data?.data?.files[0]?.id,
|
||||||
type: response?.data?.data?.fileType.name,
|
type: response?.data?.data?.fileType.name,
|
||||||
|
|
@ -255,7 +264,7 @@ const DetailInfo = () => {
|
||||||
router.push("/auth/login");
|
router.push("/auth/login");
|
||||||
} else {
|
} else {
|
||||||
const data = {
|
const data = {
|
||||||
mediaUploadId: id?.split("-")?.[0],
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
email: emailShareList || [emailShareInput],
|
email: emailShareList || [emailShareInput],
|
||||||
message: emailMessageInput,
|
message: emailMessageInput,
|
||||||
url: window.location.href,
|
url: window.location.href,
|
||||||
|
|
@ -287,6 +296,128 @@ const DetailInfo = () => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function addDefaultProfile(ev: any) {
|
||||||
|
ev.target.src = "/assets/avatar-profile.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
const showInput = (e: any) => {
|
||||||
|
console.log(document.querySelector(`#${e}`)?.classList);
|
||||||
|
document.querySelector(`#${e}`)?.classList.toggle("hidden");
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInputValue = (e: any) => {
|
||||||
|
const message = e.target.value;
|
||||||
|
console.log(message);
|
||||||
|
setMessage(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
async function sendSuggestionParent() {
|
||||||
|
if (message?.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message,
|
||||||
|
parentId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
setMessage("");
|
||||||
|
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet?.data?.data);
|
||||||
|
setListSuggestion(responseGet?.data?.data);
|
||||||
|
|
||||||
|
// Hapus nilai semua input secara manual jika perlu
|
||||||
|
const inputs = document.querySelectorAll("input");
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
input.value = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendSuggestionChild(parentId: any) {
|
||||||
|
const inputElement = document.querySelector(`#input-comment-${parentId}`) as HTMLInputElement;
|
||||||
|
|
||||||
|
if (inputElement && inputElement.value.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message: inputElement.value,
|
||||||
|
parentId,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet: any = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
|
||||||
|
// Reset input field
|
||||||
|
inputElement.value = "";
|
||||||
|
|
||||||
|
// document.querySelector("#comment-id-" + parentId)?.style.display = "none";
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const postData = () => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionParent();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const postDataChild = (id: any) => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionChild(id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function deleteDataSuggestion(dataId: any) {
|
||||||
|
loading();
|
||||||
|
const response = await deletePublicSuggestion(dataId);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteData = (dataId: any) => {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Delete Comment",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonColor: "#3085d6",
|
||||||
|
confirmButtonColor: "#d33",
|
||||||
|
confirmButtonText: "Delete",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
deleteDataSuggestion(dataId);
|
||||||
|
console.log(dataId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="min-h-screen px-4 md:px-24 py-4">
|
<div className="min-h-screen px-4 md:px-24 py-4">
|
||||||
|
|
@ -431,8 +562,171 @@ const DetailInfo = () => {
|
||||||
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<p className="flex items-start text-lg">Berikan Komentar</p>
|
<p className="flex items-start text-lg">Berikan Komentar</p>
|
||||||
<Textarea placeholder="Type your comments here." className="flex w-full" />
|
<Textarea placeholder="Type your comments here." className="flex w-full py-8" onChange={getInputValue} />
|
||||||
<button className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">Kirim</button>
|
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
|
||||||
|
Kirim
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border-b-2 border-slate-300 mt-4 w-auto"></div>
|
||||||
|
|
||||||
|
<div className="overflow-y-auto">
|
||||||
|
{listSuggestion?.map((data: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-14">
|
||||||
|
<img src={data?.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{Number(data.suggestionFrom?.roleId) == 2 || Number(data.suggestionFrom?.roleId) == 3 || Number(data.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : data.suggestionFrom?.fullname}
|
||||||
|
{getPublicLocaleTimestamp(new Date(data.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{data?.message}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(data.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${data.id}`)}
|
||||||
|
className="mr-2"
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
{Number(data.suggestionFrom?.id) == Number(userId) || Number(userRoleId) == 2 ? (
|
||||||
|
<a onClick={() => deleteData(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${data.id}`} className="px-4 lg:px-28 mt-2">
|
||||||
|
<Textarea id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 mt-2 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${data.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg mt-2 w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{data.children.length > 0
|
||||||
|
? data.children?.map((child1: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-32">
|
||||||
|
<img src={child1.suggestionFrom?.profilePictureUrl} onError={addDefaultProfile} alt="" className="h-16 w-16 mr-2" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child1.suggestionFrom?.roleId) == 2 || Number(child1.suggestionFrom?.roleId) == 3 || Number(child1.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child1.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child1.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child1?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child1.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child1.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${child1.id}`} className="px-4 lg:px-40">
|
||||||
|
<Textarea name="" className="mt-2 " id={`input-comment-${child1.id}`} placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row mt-2 gap-3">
|
||||||
|
<a onClick={() => postDataChild(child1.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child1.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{child1.children.length > 0
|
||||||
|
? child1.children?.map((child2: any) => (
|
||||||
|
<div className="">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-48">
|
||||||
|
<img src={child2.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child2.suggestionFrom?.roleId) == 2 || Number(child2.suggestionFrom?.roleId) == 3 || Number(child2.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child2.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child2.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child2?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child2.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child2.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id={`comment-id-${child2.id}`} className="px-4 lg:px-52">
|
||||||
|
<Textarea name="" id={`input-comment-${child2.id}`} className="my-2" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(child2.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child2.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
||||||
<div className="lg:w-96 h-fit w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
<div className="lg:w-[30%] h-fit w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
||||||
<Icon icon="stash:filter-light" fontSize={30} />
|
<Icon icon="stash:filter-light" fontSize={30} />
|
||||||
Filter
|
Filter
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ const InboxSection = () => {
|
||||||
<div className="flex flex-col justify-center items-center gap-3">
|
<div className="flex flex-col justify-center items-center gap-3">
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
<div className="flex flex-row gap-10 items-center justify-center">
|
<div className="flex flex-row gap-10 items-center justify-center">
|
||||||
<div>
|
<div className="">
|
||||||
<p className="bg-[#bb3523] py-1 px-3 rounded-full">Pesan Masuk</p>
|
<p className="bg-[#bb3523] py-1 px-3 rounded-full">Pesan Masuk</p>
|
||||||
</div>
|
</div>
|
||||||
<Link href={`/inbox/update`}>Update</Link>
|
<Link href={`/inbox/update`}>Update</Link>
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,20 @@
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Calendar } from "@/components/ui/calendar";
|
import { Calendar } from "@/components/ui/calendar";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
import { Popover, PopoverArrow, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
import { CalendarIcon } from "lucide-react";
|
import { CalendarIcon } from "lucide-react";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import { detailSchedule, listSchedule, listScheduleNextPublic, listSchedulePrevPublic, listScheduleTodayPublic } from "@/service/schedule/schedule";
|
import { detailSchedule, listSchedule, listScheduleNextPublic, listSchedulePrevPublic, listScheduleTodayPublic, searchSchedules } from "@/service/schedule/schedule";
|
||||||
import { useRouter } from "@/i18n/routing";
|
import { usePathname, useRouter } from "@/i18n/routing";
|
||||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
|
||||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||||
import { close, loading } from "@/config/swal";
|
import { close, loading } from "@/config/swal";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
const timeList = [
|
const timeList = [
|
||||||
{
|
{
|
||||||
|
|
@ -115,8 +116,57 @@ const timeList = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const city = [
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
id: "metro-jaya",
|
||||||
|
name: "Polda Metro Jaya",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 2,
|
||||||
|
id: "jawa-barat",
|
||||||
|
name: "Polda Jawa Barat",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3,
|
||||||
|
id: "banten",
|
||||||
|
name: "Polda Banten",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 4,
|
||||||
|
id: "jawa-tengah",
|
||||||
|
name: "Polda Jawa Tengah",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 5,
|
||||||
|
id: "daerah-istimewa-yogyakarta",
|
||||||
|
name: "Polda D.I Yogyakarta",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 6,
|
||||||
|
id: "jawa-timur",
|
||||||
|
name: "Polda Jawa Timur",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 7,
|
||||||
|
id: "aceh",
|
||||||
|
name: "Polda Aceh",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 8,
|
||||||
|
id: "sumatera-utara",
|
||||||
|
name: "Polda Sumatera Utara",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 9,
|
||||||
|
id: "sumatera-barat",
|
||||||
|
name: "Polda Sumatera Barat",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const Schedule = (props: any) => {
|
const Schedule = (props: any) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const asPath = usePathname();
|
||||||
const [startDate, setStartDate] = useState<Date | undefined>(new Date());
|
const [startDate, setStartDate] = useState<Date | undefined>(new Date());
|
||||||
const [dateAWeek, setDateAWeek] = useState<string[]>([]);
|
const [dateAWeek, setDateAWeek] = useState<string[]>([]);
|
||||||
const [todayList, setTodayList] = useState([]);
|
const [todayList, setTodayList] = useState([]);
|
||||||
|
|
@ -128,6 +178,31 @@ const Schedule = (props: any) => {
|
||||||
const [content, setContent] = useState();
|
const [content, setContent] = useState();
|
||||||
const { id } = props;
|
const { id } = props;
|
||||||
const t = useTranslations("LandingPage");
|
const t = useTranslations("LandingPage");
|
||||||
|
const [search, setSearch] = useState<any>();
|
||||||
|
const [scheduleSearch, setScheduleSearch] = useState<any>();
|
||||||
|
let typingTimer: any;
|
||||||
|
const doneTypingInterval = 1500;
|
||||||
|
const [regionFilter, setRegionFilter] = useState<any>([]);
|
||||||
|
const [regionName, setRegionName] = useState<any>([]);
|
||||||
|
const isPolda = asPath.includes("/polda");
|
||||||
|
|
||||||
|
async function doneTyping() {
|
||||||
|
if (search?.length > 2) {
|
||||||
|
const resSchedule = await searchSchedules(search);
|
||||||
|
setScheduleSearch(resSchedule.data?.data);
|
||||||
|
} else {
|
||||||
|
setScheduleSearch([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleKeyUp = () => {
|
||||||
|
clearTimeout(typingTimer);
|
||||||
|
typingTimer = setTimeout(doneTyping, doneTypingInterval);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyDown = () => {
|
||||||
|
clearTimeout(typingTimer);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getDataSchedule() {
|
async function getDataSchedule() {
|
||||||
|
|
@ -139,6 +214,23 @@ const Schedule = (props: any) => {
|
||||||
getDataSchedule();
|
getDataSchedule();
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function initState() {
|
||||||
|
const group = isPolda ? asPath.split("/")[2] : regionFilter?.join(",");
|
||||||
|
const resSchedule = await listSchedule(group);
|
||||||
|
setSchedules(resSchedule.data?.data);
|
||||||
|
console.log(resSchedule);
|
||||||
|
setDateAWeek(dateList);
|
||||||
|
getDataByDate(); // let today = new Date();
|
||||||
|
// if (!dateList.includes(today.getDate())){
|
||||||
|
// changeNextWeek();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
initState();
|
||||||
|
console.log("Filter ::", regionFilter);
|
||||||
|
}, [regionName]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
getDataByDate();
|
getDataByDate();
|
||||||
|
|
@ -279,6 +371,57 @@ const Schedule = (props: any) => {
|
||||||
setOpenDialog(true);
|
setOpenDialog(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRegionFilter = (e: any) => {
|
||||||
|
let regions = [...regionFilter];
|
||||||
|
|
||||||
|
if (e.target.checked) {
|
||||||
|
regions = [...regionFilter, e.target.value];
|
||||||
|
} else {
|
||||||
|
regions.splice(regionFilter.indexOf(e.target.value), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(regions);
|
||||||
|
setRegionFilter(regions);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getListDataCity = () => {
|
||||||
|
let filteredReg: any = [];
|
||||||
|
let regName = "";
|
||||||
|
|
||||||
|
for (const element of regionFilter) {
|
||||||
|
for (const element_ of city) {
|
||||||
|
if (element == element_.id) {
|
||||||
|
regName = element_.name;
|
||||||
|
filteredReg = [
|
||||||
|
...filteredReg,
|
||||||
|
{
|
||||||
|
id: element_.id,
|
||||||
|
key: element_.key,
|
||||||
|
name: regName,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(filteredReg);
|
||||||
|
setRegionName(filteredReg);
|
||||||
|
filteredReg = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const doFilter = () => {
|
||||||
|
getListDataCity();
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteFilterhandler = (filterId: any) => {
|
||||||
|
console.log("hapus", filterId);
|
||||||
|
const deletedReg = regionName.filter((list: any) => list.id !== filterId);
|
||||||
|
const filtered = regionFilter.filter((list: any) => list !== filterId);
|
||||||
|
|
||||||
|
setRegionName(deletedReg);
|
||||||
|
setRegionFilter(filtered);
|
||||||
|
};
|
||||||
|
|
||||||
function setItemSchedule(id: string, date: string) {
|
function setItemSchedule(id: string, date: string) {
|
||||||
const itemFound: any = schedules?.filter((s: any) => s.dateInRange.includes(date) && s.timeIndex.split(",").includes(id));
|
const itemFound: any = schedules?.filter((s: any) => s.dateInRange.includes(date) && s.timeIndex.split(",").includes(id));
|
||||||
|
|
||||||
|
|
@ -358,8 +501,8 @@ const Schedule = (props: any) => {
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
||||||
<div className="container relative py-4">
|
<div className="container relative py-4">
|
||||||
<DropdownMenu>
|
<Popover>
|
||||||
<DropdownMenuTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<a className="text-black flex flex-row w-fit gap-2 py-4 items-center cursor-pointer">
|
<a className="text-black flex flex-row w-fit gap-2 py-4 items-center cursor-pointer">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||||
<path fill="#000" d="M20 3H4a1 1 0 0 0-1 1v2.227l.008.223a3 3 0 0 0 .772 1.795L8 12.886V21a1 1 0 0 0 1.316.949l6-2l.108-.043A1 1 0 0 0 16 19v-6.586l4.121-4.12A3 3 0 0 0 21 6.171V4a1 1 0 0 0-1-1" />
|
<path fill="#000" d="M20 3H4a1 1 0 0 0-1 1v2.227l.008.223a3 3 0 0 0 .772 1.795L8 12.886V21a1 1 0 0 0 1.316.949l6-2l.108-.043A1 1 0 0 0 16 19v-6.586l4.121-4.12A3 3 0 0 0 21 6.171V4a1 1 0 0 0-1-1" />
|
||||||
|
|
@ -369,56 +512,39 @@ const Schedule = (props: any) => {
|
||||||
<path fill="currentColor" fill-rule="evenodd" d="m6 7l6 6l6-6l2 2l-8 8l-8-8z" />
|
<path fill="currentColor" fill-rule="evenodd" d="m6 7l6 6l6-6l2 2l-8 8l-8-8z" />
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</DropdownMenuTrigger>
|
</PopoverTrigger>
|
||||||
<DropdownMenuContent align="start" className="flex p-0 rounded-md">
|
<PopoverContent align="start" className="flex p-0 rounded-md w-fit">
|
||||||
<DropdownMenuItem className="flex flex-col items-center justify-between gap-1.5 p-2 border-b text-default-600 rounded-none">
|
<div className="flex flex-col items-center justify-between gap-1.5 p-2 border-b text-default-600 rounded-none">
|
||||||
<div className="gap-6 flex flex-row justify-end">
|
<div className="gap-6 flex flex-row justify-end">
|
||||||
<div> Filter</div>
|
<p className="font-semibold">Filter</p>
|
||||||
<button className="text-blue-400">Simpan</button>
|
<button className="text-blue-400" onClick={doFilter}>
|
||||||
|
Simpan
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="border w-full border-t border-slate-500"></div>
|
<div className="border w-full border-t border-slate-500"></div>
|
||||||
<div className="overflow-y-auto flex flex-col gap-2 h-[200px] ">
|
<div className="overflow-y-auto flex flex-col gap-2 h-[200px]">
|
||||||
<p>Region Filter</p>
|
<p className="text-center font-semibold">Region Filter</p>
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
{city?.map((list) => (
|
||||||
<Checkbox id="terms" />
|
<div className="mt-2 gap-2 flex flex-row">
|
||||||
<p>POLDA METRO JAYA</p>
|
{" "}
|
||||||
</div>
|
<input type="checkbox" className="" id={`filterCategory-${list.key}`} value={list.id} checked={regionFilter?.includes(list.id)} onChange={handleRegionFilter} />
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
<p>{list?.name}</p>
|
||||||
<Checkbox id="terms" />
|
</div>
|
||||||
<p>POLDA METRO JAYA</p>
|
))}
|
||||||
</div>
|
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
|
||||||
<Checkbox id="terms" />
|
|
||||||
<p>POLDA METRO JAYA</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
|
||||||
<Checkbox id="terms" />
|
|
||||||
<p>POLDA METRO JAYA</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
|
||||||
<Checkbox id="terms" />
|
|
||||||
<p>POLDA METRO JAYA</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
|
||||||
<Checkbox id="terms" />
|
|
||||||
<p>POLDA METRO JAYA</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
|
||||||
<Checkbox id="terms" />
|
|
||||||
<p>POLDA METRO JAYA</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
|
||||||
<Checkbox id="terms" />
|
|
||||||
<p>POLDA METRO JAYA</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-2 gap-2 flex flex-row">
|
|
||||||
<Checkbox id="terms" />
|
|
||||||
<p>POLDA METRO JAYA</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenuItem>
|
</div>
|
||||||
</DropdownMenuContent>
|
</PopoverContent>
|
||||||
</DropdownMenu>
|
</Popover>
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
{regionName?.map((list: any) => (
|
||||||
|
<div className="text-left ">
|
||||||
|
<button onClick={() => deleteFilterhandler(list.id)} key={list.key} id={list.id} className="text-black bg-yellow-300 w-fit p-3 flex justify-center items-center rounded-lg">
|
||||||
|
{list.name}
|
||||||
|
<Icon icon="icon-park-outline:delete-two" className="items-center" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col lg:flex-row gap-6">
|
<div className="flex flex-col lg:flex-row gap-6">
|
||||||
<div className="h-[500px] overflow-y-auto w-3/4 ">
|
<div className="h-[500px] overflow-y-auto w-3/4 ">
|
||||||
|
|
@ -514,7 +640,14 @@ const Schedule = (props: any) => {
|
||||||
{/* komponen Kanan */}
|
{/* komponen Kanan */}
|
||||||
<div className="w-1/4 flex flex-col gap-6">
|
<div className="w-1/4 flex flex-col gap-6">
|
||||||
<div className="relative text-gray-600 dark:text-white">
|
<div className="relative text-gray-600 dark:text-white">
|
||||||
<input type="text" placeholder={t("titleSchedule")} className="pl-8 pr-4 py-1 w-full border rounded-full text-sm focus:outline-none" />
|
<input
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
onKeyUp={handleKeyUp}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
type="text"
|
||||||
|
placeholder={t("titleSchedule")}
|
||||||
|
className="pl-8 pr-4 py-1 w-full border rounded-full text-sm focus:outline-none"
|
||||||
|
/>
|
||||||
<span className="absolute left-2 top-1/2 transform -translate-y-1/2">
|
<span className="absolute left-2 top-1/2 transform -translate-y-1/2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
|
@ -557,7 +690,7 @@ const Schedule = (props: any) => {
|
||||||
</CollapsibleContent>
|
</CollapsibleContent>
|
||||||
))}
|
))}
|
||||||
</Collapsible> */}
|
</Collapsible> */}
|
||||||
|
|
||||||
<Accordion type="single" collapsible className="w-full">
|
<Accordion type="single" collapsible className="w-full">
|
||||||
<AccordionItem value="item-1">
|
<AccordionItem value="item-1">
|
||||||
<AccordionTrigger>Jadwal Hari ini</AccordionTrigger>
|
<AccordionTrigger>Jadwal Hari ini</AccordionTrigger>
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,22 @@
|
||||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing";
|
import { checkWishlistStatus, createPublicSuggestion, deletePublicSuggestion, deleteWishlist, getDetail, getPublicSuggestionList, saveWishlist } from "@/service/landing/landing";
|
||||||
import VideoPlayer from "@/utils/video-player";
|
import VideoPlayer from "@/utils/video-player";
|
||||||
import NewContent from "@/components/landing-page/new-content";
|
import NewContent from "@/components/landing-page/new-content";
|
||||||
import { Link, useRouter } from "@/i18n/routing";
|
import { Link, useRouter } from "@/i18n/routing";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { getCookiesDecrypt } from "@/lib/utils";
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
import { close, error, loading, successCallback } from "@/config/swal";
|
import { close, error, loading, successCallback, warning } from "@/config/swal";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import parse from "html-react-parser";
|
||||||
|
|
||||||
const DetailVideo = () => {
|
const DetailVideo = () => {
|
||||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||||
|
|
@ -41,6 +45,9 @@ const DetailVideo = () => {
|
||||||
const [width, setWidth] = useState<any>();
|
const [width, setWidth] = useState<any>();
|
||||||
const [content, setContent] = useState<any>([]);
|
const [content, setContent] = useState<any>([]);
|
||||||
const userRoleId = getCookiesDecrypt("urie");
|
const userRoleId = getCookiesDecrypt("urie");
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [listSuggestion, setListSuggestion] = useState<any>();
|
||||||
|
const MySwal = withReactContent(Swal);
|
||||||
|
|
||||||
let typeString = "video";
|
let typeString = "video";
|
||||||
|
|
||||||
|
|
@ -52,9 +59,12 @@ const DetailVideo = () => {
|
||||||
const initFetch = async () => {
|
const initFetch = async () => {
|
||||||
const response = await getDetail(String(slug));
|
const response = await getDetail(String(slug));
|
||||||
console.log("detailVideo", response);
|
console.log("detailVideo", response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
|
||||||
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
setIsFromSPIT(response?.data?.data?.isFromSPIT);
|
||||||
setWidth(window.innerWidth);
|
setWidth(window.innerWidth);
|
||||||
setContent(response?.data.data);
|
setContent(response?.data.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
setMain({
|
setMain({
|
||||||
id: response?.data?.data?.files[0]?.id,
|
id: response?.data?.data?.files[0]?.id,
|
||||||
type: response?.data?.data?.fileType.name,
|
type: response?.data?.data?.fileType.name,
|
||||||
|
|
@ -284,6 +294,121 @@ const DetailVideo = () => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function sendSuggestionChild(parentId: any) {
|
||||||
|
const inputElement = document.querySelector(`#input-comment-${parentId}`) as HTMLInputElement;
|
||||||
|
|
||||||
|
if (inputElement && inputElement.value.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message: inputElement.value,
|
||||||
|
parentId,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet: any = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
|
||||||
|
// Reset input field
|
||||||
|
inputElement.value = "";
|
||||||
|
|
||||||
|
// document.querySelector("#comment-id-" + parentId)?.style.display = "none";
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function deleteDataSuggestion(dataId: any) {
|
||||||
|
loading();
|
||||||
|
const response = await deletePublicSuggestion(dataId);
|
||||||
|
console.log(response);
|
||||||
|
const responseGet = await getPublicSuggestionList(slug.split("-")?.[0]);
|
||||||
|
console.log(responseGet.data?.data);
|
||||||
|
setListSuggestion(responseGet.data?.data);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
const deleteData = (dataId: any) => {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Delete Comment",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonColor: "#3085d6",
|
||||||
|
confirmButtonColor: "#d33",
|
||||||
|
confirmButtonText: "Delete",
|
||||||
|
}).then((result: any) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
deleteDataSuggestion(dataId);
|
||||||
|
console.log(dataId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const showInput = (e: any) => {
|
||||||
|
console.log(document.querySelector(`#${e}`)?.classList);
|
||||||
|
document.querySelector(`#${e}`)?.classList.toggle("hidden");
|
||||||
|
};
|
||||||
|
function addDefaultProfile(ev: any) {
|
||||||
|
ev.target.src = "/assets/avatar-profile.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendSuggestionParent() {
|
||||||
|
if (message?.length > 3) {
|
||||||
|
loading();
|
||||||
|
const data = {
|
||||||
|
mediaUploadId: slug?.split("-")?.[0],
|
||||||
|
message,
|
||||||
|
parentId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await createPublicSuggestion(data);
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
setMessage("");
|
||||||
|
|
||||||
|
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
|
||||||
|
console.log(responseGet?.data?.data);
|
||||||
|
setListSuggestion(responseGet?.data?.data);
|
||||||
|
|
||||||
|
// Hapus nilai semua input secara manual jika perlu
|
||||||
|
const inputs = document.querySelectorAll("input");
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
input.value = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const getInputValue = (e: any) => {
|
||||||
|
const message = e.target.value;
|
||||||
|
console.log(message);
|
||||||
|
setMessage(message);
|
||||||
|
};
|
||||||
|
const postData = () => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionParent();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const postDataChild = (id: any) => {
|
||||||
|
const checkMessage = checkMaliciousText(message);
|
||||||
|
if (checkMessage == "") {
|
||||||
|
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||||
|
router.push("/auth");
|
||||||
|
} else {
|
||||||
|
sendSuggestionChild(id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(checkMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="px-4 md:px-24 py-4">
|
<div className="px-4 md:px-24 py-4">
|
||||||
|
|
@ -427,8 +552,171 @@ const DetailVideo = () => {
|
||||||
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<p className="flex items-start text-lg">Berikan Komentar</p>
|
<p className="flex items-start text-lg">Berikan Komentar</p>
|
||||||
<Textarea placeholder="Type your comments here." className="flex w-full" />
|
<Textarea placeholder="Type your comments here." className="flex w-full py-8" onChange={getInputValue} />
|
||||||
<button className="flex items-start bg-[#bb3523] text-white rounded-lg w-fit px-4 py-1">Kirim</button>
|
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
|
||||||
|
Kirim
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border-b-2 border-slate-300 mt-4 w-auto"></div>
|
||||||
|
|
||||||
|
<div className="overflow-y-auto">
|
||||||
|
{listSuggestion?.map((data: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-14">
|
||||||
|
<img src={data?.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{Number(data.suggestionFrom?.roleId) == 2 || Number(data.suggestionFrom?.roleId) == 3 || Number(data.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : data.suggestionFrom?.fullname}
|
||||||
|
{getPublicLocaleTimestamp(new Date(data.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{data?.message}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(data.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${data.id}`)}
|
||||||
|
className="mr-2"
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
{Number(data.suggestionFrom?.id) == Number(userId) || Number(userRoleId) == 2 ? (
|
||||||
|
<a onClick={() => deleteData(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${data.id}`} className="px-4 lg:px-28 mt-2">
|
||||||
|
<Textarea id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(data.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 mt-2 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${data.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg mt-2 w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{data.children.length > 0
|
||||||
|
? data.children?.map((child1: any) => (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-32">
|
||||||
|
<img src={child1.suggestionFrom?.profilePictureUrl} onError={addDefaultProfile} alt="" className="h-16 w-16 mr-2" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child1.suggestionFrom?.roleId) == 2 || Number(child1.suggestionFrom?.roleId) == 3 || Number(child1.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child1.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child1.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child1?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child1.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child1.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child1.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id={`comment-id-${child1.id}`} className="px-4 lg:px-40">
|
||||||
|
<Textarea name="" className="mt-2 " id={`input-comment-${child1.id}`} placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row mt-2 gap-3">
|
||||||
|
<a onClick={() => postDataChild(child1.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child1.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{child1.children.length > 0
|
||||||
|
? child1.children?.map((child2: any) => (
|
||||||
|
<div className="">
|
||||||
|
<div className="flex flex-row mt-2 px-4 lg:px-48">
|
||||||
|
<img src={child2.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||||
|
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
|
||||||
|
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
|
||||||
|
{" "}
|
||||||
|
<b>{Number(child2.suggestionFrom?.roleId) == 2 || Number(child2.suggestionFrom?.roleId) == 3 || Number(child2.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child2.suggestionFrom?.fullname}</b>{" "}
|
||||||
|
{getPublicLocaleTimestamp(new Date(child2.createdAt))}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-500 text-sm mb-4">{parse(String(child2?.message))}</p>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
onClick={() => showInput(`comment-id-${child2.id}`)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={
|
||||||
|
Number(child2.suggestionFrom?.id) == Number(userId)
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClick={() => deleteData(child2.id)}
|
||||||
|
>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id={`comment-id-${child2.id}`} className="px-4 lg:px-52">
|
||||||
|
<Textarea name="" id={`input-comment-${child2.id}`} className="my-2" placeholder="Masukkan balasan anda" />
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<a onClick={() => postDataChild(child2.id)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
|
||||||
|
</a>
|
||||||
|
<a onClick={() => showInput(`comment-id-${child2.id}`)}>
|
||||||
|
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,10 +96,6 @@ const FilterPage = () => {
|
||||||
}
|
}
|
||||||
}, [categorie]);
|
}, [categorie]);
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// fetchData();
|
|
||||||
// }, [page, sortBy, sortByOpt, title]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
if (isRegional) {
|
if (isRegional) {
|
||||||
|
|
@ -108,7 +104,6 @@ const FilterPage = () => {
|
||||||
getDataAll();
|
getDataAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(monthYearFilter, "monthFilter");
|
|
||||||
initState();
|
initState();
|
||||||
}, [change, asPath, monthYearFilter, page, sortBy, sortByOpt, title, startDateString, endDateString, categorie, formatFilter]);
|
}, [change, asPath, monthYearFilter, page, sortBy, sortByOpt, title, startDateString, endDateString, categorie, formatFilter]);
|
||||||
|
|
||||||
|
|
@ -152,7 +147,8 @@ const FilterPage = () => {
|
||||||
startDateString,
|
startDateString,
|
||||||
endDateString,
|
endDateString,
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : ""
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "",
|
||||||
|
locale == "en" ? true : false
|
||||||
);
|
);
|
||||||
close();
|
close();
|
||||||
// setGetTotalPage(response?.data?.data?.totalPages);
|
// setGetTotalPage(response?.data?.data?.totalPages);
|
||||||
|
|
@ -167,7 +163,6 @@ const FilterPage = () => {
|
||||||
}
|
}
|
||||||
} else {
|
} 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 name = title == undefined ? "" : title;
|
||||||
const format = formatFilter == undefined ? "" : formatFilter?.join(",");
|
const format = formatFilter == undefined ? "" : formatFilter?.join(",");
|
||||||
loading();
|
loading();
|
||||||
|
|
@ -184,7 +179,8 @@ const FilterPage = () => {
|
||||||
startDateString,
|
startDateString,
|
||||||
endDateString,
|
endDateString,
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[0]?.replace("", "") : "",
|
||||||
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : ""
|
monthYearFilter ? getOnlyMonthAndYear(monthYearFilter)?.split("/")[1] : "",
|
||||||
|
locale == "en" ? true : false
|
||||||
);
|
);
|
||||||
close();
|
close();
|
||||||
// setGetTotalPage(response?.data?.data?.totalPages);
|
// setGetTotalPage(response?.data?.data?.totalPages);
|
||||||
|
|
@ -281,25 +277,25 @@ const FilterPage = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
initFetch();
|
// initFetch();
|
||||||
}, [page]);
|
// }, [page]);
|
||||||
const initFetch = async () => {
|
// const initFetch = async () => {
|
||||||
const response = await getListContent({
|
// const response = await getListContent({
|
||||||
page: page - 1,
|
// page: page - 1,
|
||||||
size: 6,
|
// size: 6,
|
||||||
sortBy: "createdAt",
|
// sortBy: "createdAt",
|
||||||
contentTypeId: "2",
|
// contentTypeId: "2",
|
||||||
isInt: locale == "en" ? true : false,
|
// isInt: locale == "en" ? true : false,
|
||||||
});
|
// });
|
||||||
console.log(response);
|
// console.log(response);
|
||||||
setVideoData(response?.data?.data?.content);
|
// setVideoData(response?.data?.data?.content);
|
||||||
const data = response?.data?.data;
|
// const data = response?.data?.data;
|
||||||
const contentData = data?.content;
|
// const contentData = data?.content;
|
||||||
setVideoData(contentData);
|
// setVideoData(contentData);
|
||||||
setTotalData(data?.totalElements);
|
// setTotalData(data?.totalElements);
|
||||||
setTotalPage(data?.totalPages);
|
// setTotalPage(data?.totalPages);
|
||||||
};
|
// };
|
||||||
|
|
||||||
function getSelectedCategory() {
|
function getSelectedCategory() {
|
||||||
const filter = [];
|
const filter = [];
|
||||||
|
|
@ -389,7 +385,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
||||||
<div className="lg:w-[25%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
<div className="lg:w-[55%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
||||||
<Icon icon="stash:filter-light" fontSize={30} />
|
<Icon icon="stash:filter-light" fontSize={30} />
|
||||||
Filter
|
Filter
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,20 @@
|
||||||
import { Link } from '@/i18n/routing';
|
import { Link } from "@/i18n/routing";
|
||||||
import ForgotPass from "@/components/partials/auth/forgot-pass";
|
import ForgotPass from "@/components/partials/auth/forgot-pass";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Copyright from "@/components/partials/auth/copyright";
|
|
||||||
import Logo from "@/components/partials/auth/logo";
|
import Logo from "@/components/partials/auth/logo";
|
||||||
|
|
||||||
const ForgotPassPage = () => {
|
const ForgotPassPage = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full items-center overflow-hidden min-h-dvh h-dvh basis-full">
|
<div className="flex w-full items-center overflow-hidden min-h-dvh h-dvh basis-full">
|
||||||
<div className="overflow-y-auto flex flex-wrap w-full h-dvh">
|
<div className="overflow-y-auto flex flex-wrap w-full h-dvh">
|
||||||
<div
|
<div className="lg:block hidden flex-1 overflow-hidden text-[40px] leading-[48px] text-default-600 relative z-[1] bg-default-50">
|
||||||
className="lg:block hidden flex-1 overflow-hidden text-[40px] leading-[48px] text-default-600
|
<div className="max-w-[520px] pt-16 ps-20 ">
|
||||||
relative z-[1] bg-default-50"
|
|
||||||
>
|
|
||||||
<div className="max-w-[520px] pt-20 ps-20">
|
|
||||||
<Link href="/" className="mb-6 inline-block">
|
<Link href="/" className="mb-6 inline-block">
|
||||||
<Logo />
|
<Image src="/assets/mediahub-logo.png" alt="" width={250} height={250} className="mb-10 w-full h-full" />
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<h4>
|
|
||||||
Unlock your Project{" "}
|
|
||||||
<span className="text-default-800 font-bold ms-2">
|
|
||||||
performance
|
|
||||||
</span>
|
|
||||||
</h4>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute left-0 bottom-[-130px] h-full w-full z-[-1]">
|
<div className="absolute left-0 2xl:bottom-[-160px] bottom-[-130px] h-full w-full z-[-1]">
|
||||||
<Image
|
<Image src="/assets/vector-login.svg" alt="" width={300} height={300} className="mb-10 w-full h-full" />
|
||||||
width={300}
|
|
||||||
height={300}
|
|
||||||
src="/images/auth/ils1.svg"
|
|
||||||
alt=""
|
|
||||||
className="h-full w-full object-contain"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 relative dark:bg-default-100 bg-white">
|
<div className="flex-1 relative dark:bg-default-100 bg-white">
|
||||||
|
|
@ -44,29 +27,18 @@ const ForgotPassPage = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center 2xl:mb-10 mb-5">
|
<div className="text-center 2xl:mb-10 mb-5">
|
||||||
<h4 className="font-medium mb-4">Forgot Your Password?</h4>
|
<h4 className="font-medium mb-4">Forgot Your Password?</h4>
|
||||||
<div className="text-default-500 text-base">
|
|
||||||
Reset Password with Dashcode.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="font-normal text-base text-default-500 text-center px-2 bg-default-100 rounded py-3 mb-4 mt-10">
|
|
||||||
Enter your Email and instructions will be sent to you!
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="font-normal text-base text-default-500 text-center px-2 bg-default-100 rounded py-3 mb-4 mt-10">Enter your Username and instructions will be sent to you!</div>
|
||||||
|
|
||||||
<ForgotPass />
|
<ForgotPass />
|
||||||
<div className="md:max-w-[345px] mx-auto font-normal text-default-500 2xl:mt-12 mt-8 uppercase text-sm">
|
<div className="md:max-w-[345px] mx-auto font-normal text-default-500 2xl:mt-12 mt-8 uppercase text-sm">
|
||||||
Forget It,
|
Forget It,
|
||||||
<Link
|
<Link href="/auth" className="text-default-900 font-medium hover:underline">
|
||||||
href="/"
|
|
||||||
className="text-default-900 font-medium hover:underline"
|
|
||||||
>
|
|
||||||
Send me Back
|
Send me Back
|
||||||
</Link>
|
</Link>
|
||||||
to The Sign In
|
to The Sign In
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs font-normal text-default-500 z-[999] pb-10 text-center">
|
|
||||||
<Copyright />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
import { close, error, loading, registerConfirm } from "@/config/swal";
|
import { close, error, loading, registerConfirm } from "@/config/swal";
|
||||||
import { Link, useRouter } from "@/i18n/routing";
|
import { Link, useRouter } from "@/i18n/routing";
|
||||||
import { getDataByNIK, getDataByNRP, getDataJournalist, getDataPersonil, listCity, listDistricts, listInstitusi, listProvince, postRegistration, saveInstitutes } from "@/service/auth";
|
import { getDataByNIK, getDataByNRP, getDataJournalist, getDataPersonil, listCity, listDistricts, listInstitusi, listProvince, postRegistration, requestOTP, saveInstitutes, verifyOTP } from "@/service/auth";
|
||||||
import { requestOTP, verifyOTP } from "@/service/landing/landing";
|
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import { useParams, useSearchParams } from "next/navigation";
|
import { useParams, useSearchParams } from "next/navigation";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
@ -21,8 +20,7 @@ import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "@/comp
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { Icon } from "@/components/ui/icon";
|
import { Icon } from "@/components/ui/icon";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import ReactPasswordChecklist from "react-password-checklist";
|
import sanitizeHtml from "sanitize-html";
|
||||||
import { Select } from "@/components/ui/select";
|
|
||||||
|
|
||||||
type Inputs = {
|
type Inputs = {
|
||||||
example: string;
|
example: string;
|
||||||
|
|
@ -52,7 +50,6 @@ const page = () => {
|
||||||
const [emailValidate, setEmailValidate] = useState("");
|
const [emailValidate, setEmailValidate] = useState("");
|
||||||
const [otpValidate, setOtpValidate] = useState("");
|
const [otpValidate, setOtpValidate] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [passwordConf, setPasswordConf] = useState("");
|
|
||||||
const [city, setCity] = useState([]);
|
const [city, setCity] = useState([]);
|
||||||
const [isValidPassword, setIsValidPassword] = useState(false);
|
const [isValidPassword, setIsValidPassword] = useState(false);
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
|
|
@ -80,6 +77,14 @@ const page = () => {
|
||||||
const nSecondInMiliseconds = 1000;
|
const nSecondInMiliseconds = 1000;
|
||||||
const [, setRefreshTimer] = useState(false);
|
const [, setRefreshTimer] = useState(false);
|
||||||
|
|
||||||
|
const [passwordType, setPasswordType] = React.useState("password");
|
||||||
|
const [passwordConf, setPasswordConf] = React.useState("password");
|
||||||
|
|
||||||
|
const togglePasswordType = () => {
|
||||||
|
setPasswordType((prevType) => (prevType === "password" ? "text" : "password"));
|
||||||
|
setPasswordConf((prevType) => (prevType === "same password" ? "text" : "same password"));
|
||||||
|
};
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
firstName: Yup.string().required("Nama Lengkap tidak boleh kosong"),
|
firstName: Yup.string().required("Nama Lengkap tidak boleh kosong"),
|
||||||
username: Yup.string().required("Username tidak boleh kosong"),
|
username: Yup.string().required("Username tidak boleh kosong"),
|
||||||
|
|
@ -106,22 +111,6 @@ const page = () => {
|
||||||
let [timerCount, setTimerCount] = useState(convertMinutesToMiliseconds(1));
|
let [timerCount, setTimerCount] = useState(convertMinutesToMiliseconds(1));
|
||||||
let interval: any;
|
let interval: any;
|
||||||
|
|
||||||
const showPass = () => {
|
|
||||||
setTypePass("text");
|
|
||||||
};
|
|
||||||
|
|
||||||
const hidePass = () => {
|
|
||||||
setTypePass("password");
|
|
||||||
};
|
|
||||||
|
|
||||||
const showPassConf = () => {
|
|
||||||
setTypePassConf("text");
|
|
||||||
};
|
|
||||||
|
|
||||||
const hidePassConf = () => {
|
|
||||||
setTypePassConf("password");
|
|
||||||
};
|
|
||||||
|
|
||||||
const setValUsername = (e: any) => {
|
const setValUsername = (e: any) => {
|
||||||
const uname = e.replaceAll(/[^\w.-]/g, "");
|
const uname = e.replaceAll(/[^\w.-]/g, "");
|
||||||
setValue("username", uname.toLowerCase());
|
setValue("username", uname.toLowerCase());
|
||||||
|
|
@ -166,37 +155,37 @@ const page = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const sanitizedFirstName = sanitizeHtml(data.firstName);
|
const sanitizedFirstName = sanitizeHtml(data.firstName);
|
||||||
|
|
||||||
// if (sanitizedFirstName == "") {
|
if (sanitizedFirstName == "") {
|
||||||
// error("Invalid Name");
|
error("Invalid Name");
|
||||||
// } else {
|
} else {
|
||||||
// const datas = {
|
const datas = {
|
||||||
// firstName: sanitizedFirstName,
|
firstName: sanitizedFirstName,
|
||||||
// lastName: "",
|
lastName: sanitizedFirstName,
|
||||||
// username: data.username,
|
username: data.username,
|
||||||
// phoneNumber: data.phoneNumber,
|
phoneNumber: data.phoneNumber,
|
||||||
// email,
|
email,
|
||||||
// address: data.address,
|
address: data.address,
|
||||||
// memberIdentity: userIdentity,
|
memberIdentity: userIdentity,
|
||||||
// provinceId: Number(data.provinsi),
|
provinceId: Number(data.provinsi),
|
||||||
// cityId: Number(data.kota),
|
cityId: Number(data.kota),
|
||||||
// districtId: Number(data.kecamatan),
|
districtId: Number(data.kecamatan),
|
||||||
// password: data.password,
|
password: data.password,
|
||||||
// instituteId: Number(institutionId),
|
instituteId: Number(institutionId),
|
||||||
// roleId: Number(category),
|
roleId: Number(category),
|
||||||
// };
|
};
|
||||||
|
|
||||||
// const response = await postRegistration(datas);
|
const response = await postRegistration(datas);
|
||||||
// console.log(response);
|
console.log(response);
|
||||||
// if (response?.error) {
|
if (response?.error) {
|
||||||
// error(response?.message);
|
error(response?.message);
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// registerConfirm();
|
registerConfirm();
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSendOTP = async () => {
|
const handleSendOTP = async () => {
|
||||||
|
|
@ -513,19 +502,6 @@ const page = () => {
|
||||||
initState();
|
initState();
|
||||||
}, [institusi]);
|
}, [institusi]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function initState() {
|
|
||||||
if (category != undefined) {
|
|
||||||
const resInstiution = await listInstitusi(category);
|
|
||||||
const res = await listProvince();
|
|
||||||
setInstitution(resInstiution?.data.data);
|
|
||||||
setProvince(res?.data.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initState();
|
|
||||||
}, [category]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-y-auto flex flex-wrap w-full h-dvh">
|
<div className="overflow-y-auto flex flex-wrap w-full h-dvh">
|
||||||
<div className="lg:block hidden flex-1 overflow-hidden bg-black text-[40px] leading-[48px] text-default-600 relative z-[1]">
|
<div className="lg:block hidden flex-1 overflow-hidden bg-black text-[40px] leading-[48px] text-default-600 relative z-[1]">
|
||||||
|
|
@ -618,10 +594,10 @@ const page = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<label htmlFor="association" className="mb-3">
|
<label htmlFor="association" className="mb-2">
|
||||||
<b>Jenis Keanggotaan</b> <span className="text-red-500">*</span>
|
Jenis Keanggotaan <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<select className={`py-3 rounded-md border border-black ${errors.association ? "block" : ""}`} {...register("association")} id="association" onChange={(e) => setAssociation(e.target.value)}>
|
<select className={`py-3 px-2 rounded-md border border-black ${errors.association ? "block" : ""}`} {...register("association")} id="association" onChange={(e) => setAssociation(e.target.value)}>
|
||||||
<option disabled selected>
|
<option disabled selected>
|
||||||
Pilih Asosiasi
|
Pilih Asosiasi
|
||||||
</option>
|
</option>
|
||||||
|
|
@ -645,7 +621,7 @@ const page = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{Number(category) == 7 ? (
|
{Number(category) == 7 ? (
|
||||||
<div className="px-8">
|
<div className="px-[34px]">
|
||||||
<label htmlFor="userIdentity" className="mb-3">
|
<label htmlFor="userIdentity" className="mb-3">
|
||||||
<b>Nomor Registrasi Polri (NRP)</b> <span className="text-red-500">*</span>
|
<b>Nomor Registrasi Polri (NRP)</b> <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -657,7 +633,7 @@ const page = () => {
|
||||||
)}
|
)}
|
||||||
{Number(category) == 6 ? (
|
{Number(category) == 6 ? (
|
||||||
<div
|
<div
|
||||||
className="px-8 mb-3"
|
className="px-[34px]"
|
||||||
style={
|
style={
|
||||||
Number(category) == 6
|
Number(category) == 6
|
||||||
? {}
|
? {}
|
||||||
|
|
@ -666,9 +642,9 @@ const page = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<label htmlFor="journalistCertificate">
|
<Label htmlFor="journalistCertificate">
|
||||||
<b>Nomor Sertifikasi Wartawan</b> <span className="text-red-500">*</span>
|
Nomor Sertifikasi Wartawan <span className="text-red-500">*</span>
|
||||||
</label>
|
</Label>
|
||||||
<Input className="rounded-md py-3" autoComplete="off" placeholder="Masukan Nomor Sertifikasi" type="text" onChange={(event: any) => setJournalistCertificate(event.target.value)} />
|
<Input className="rounded-md py-3" autoComplete="off" placeholder="Masukan Nomor Sertifikasi" type="text" onChange={(event: any) => setJournalistCertificate(event.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -715,17 +691,18 @@ const page = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`flex flex-col gap-3 my-4 px-12 ${formProfile == false ? "hidden" : ""}`}>
|
<div className={`flex flex-col px-12 ${formProfile == false ? "hidden" : ""}`}>
|
||||||
<div>
|
<div>
|
||||||
{Number(category) == 6 || Number(category) == 7 ? (
|
{Number(category) == 6 || Number(category) == 7 ? (
|
||||||
<div className="">
|
<div className="px-[34px]">
|
||||||
<label className="">
|
<label className="mb-2">
|
||||||
<b>{`${Number(category) == 6 ? "Nomor Sertifikasi Wartawan" : "NRP"}`}</b> <span className="text-red-500">*</span>
|
{`${Number(category) == 6 ? "Nomor Sertifikasi Wartawan" : "NRP"}`}
|
||||||
|
<span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
className={` ${errors.memberIdentity ? "block" : ""}`}
|
className={`mb-3 ${errors.memberIdentity ? "block" : ""}`}
|
||||||
{...register("memberIdentity")}
|
{...register("memberIdentity")}
|
||||||
placeholder="Masukan Nomor Identitas"
|
placeholder="Masukan Nomor Identitas"
|
||||||
onChange={(e) => handleIdentity(e.target.value)}
|
onChange={(e) => handleIdentity(e.target.value)}
|
||||||
|
|
@ -736,22 +713,22 @@ const page = () => {
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
<div className="mb-4">
|
<div className="mb-4 px-[34px]">
|
||||||
<label className="mb-2">
|
<label className="mb-2">
|
||||||
<b>Nama Lengkap</b> <span className="text-red-500">*</span>
|
Nama Lengkap <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Input type="text" autoComplete="off" className={` ${errors.firstName ? "block" : ""}`} {...register("firstName")} placeholder="Masukan Nama Lengkap Anda" />
|
<Input type="text" autoComplete="off" className={` ${errors.firstName ? "block" : ""}`} {...register("firstName")} placeholder="Masukan Nama Lengkap Anda" />
|
||||||
<div className="text-red-500">{errors.firstName?.message}</div>
|
<div className="text-red-500">{errors.firstName?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4 px-[34px]">
|
||||||
<label className="mb-2">
|
<label className="mb-2">
|
||||||
<b>Username</b> <span className="text-red-500">*</span>
|
Username <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
|
id="username"
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
className={`form-control ${errors.username ? "block" : ""}`}
|
className={`${errors.username ? "block" : ""}`}
|
||||||
{...register("username")}
|
|
||||||
placeholder="Masukan Username"
|
placeholder="Masukan Username"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setValUsername(e.target.value.trim());
|
setValUsername(e.target.value.trim());
|
||||||
|
|
@ -765,35 +742,35 @@ const page = () => {
|
||||||
/>
|
/>
|
||||||
<div className="text-red-500">{errors.username?.message}</div>
|
<div className="text-red-500">{errors.username?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4 px-[34px]">
|
||||||
<label className="mb-2">
|
<label className="mb-2">
|
||||||
<b>Email</b> <span className="text-red-500">*</span>
|
Email <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Input type="email" autoComplete="off" className={` ${errors.email ? "block" : ""}`} {...register("email")} placeholder="Masukan Email Anda" disabled />
|
<Input type="email" autoComplete="off" className={`${errors.email ? "block" : ""}`} {...register("email")} placeholder="Masukan Email Anda" disabled />
|
||||||
<div className="text-red-500">{errors.email?.message}</div>
|
<div className="text-red-500">{errors.email?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col px-[34px]">
|
||||||
<label className="mb-2">
|
<label className="mb-2">
|
||||||
<b>No. HP</b> <span className="text-red-500">*</span>
|
No. HP<span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Input type="number" autoComplete="off" className={` ${errors.phoneNumber ? "block" : ""}`} {...register("phoneNumber")} placeholder="Masukan Nomor Telepon Anda" />
|
<Input type="number" autoComplete="off" className={`mb-3 ${errors.phoneNumber ? "block" : ""}`} {...register("phoneNumber")} placeholder="Masukan Nomor Telepon Anda" />
|
||||||
<div className="text-red-500">{errors.phoneNumber?.message}</div>
|
<div className="text-red-500">{errors.phoneNumber?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4 px-[34px]">
|
||||||
<label htmlFor="address" className="mb-2">
|
<label htmlFor="address" className="mb-2">
|
||||||
<b>Alamat</b> <span className="text-red-500">*</span>
|
Alamat <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Textarea className={`form-control ${errors.address ? "block" : ""}`} {...register("address")} placeholder="Masukan Alamat Lengkap Anda" rows={3} />
|
<Textarea className={` ${errors.address ? "block" : ""}`} {...register("address")} placeholder="Masukan Alamat Lengkap Anda" rows={3} />
|
||||||
<div className="text-red-500">{errors.address?.message}</div>
|
<div className="text-red-500">{errors.address?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
{Number(category) == 6 ? (
|
{Number(category) == 6 ? (
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3 px-[34px]">
|
||||||
<div className="">
|
<div className="flex flex-col mb-2">
|
||||||
<label htmlFor="provinsi">
|
<label htmlFor="provinsi">
|
||||||
<b>Pilih Institusi</b> <span className="text-red-500">*</span>
|
Institusi <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<select className="" id="provinsi" onChange={(event) => handleInstituteOption(event)}>
|
<select className="mb-3 py-2" id="provinsi" onChange={(event) => handleInstituteOption(event)}>
|
||||||
<option disabled selected>
|
<option disabled selected>
|
||||||
Pilih Institusi
|
Pilih Institusi
|
||||||
</option>
|
</option>
|
||||||
|
|
@ -808,7 +785,7 @@ const page = () => {
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className=""
|
className="px-[34px]"
|
||||||
style={
|
style={
|
||||||
isCustomActive == false
|
isCustomActive == false
|
||||||
? {
|
? {
|
||||||
|
|
@ -818,25 +795,25 @@ const page = () => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<label htmlFor="alamat" className="mb-2">
|
<label htmlFor="alamat" className="mb-2">
|
||||||
<b>Nama Institusi</b> <span className="text-red-500">*</span>
|
Nama Institusi <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Input className="" autoComplete="off" placeholder="Masukan Nama Lengkap Institusi Anda" type="text" onChange={(event) => setCustomInstituteName(event.target.value)} />
|
<Input className="mb-3" autoComplete="off" placeholder="Masukan Nama Lengkap Institusi Anda" type="text" onChange={(event) => setCustomInstituteName(event.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
<div className="">
|
||||||
<label htmlFor="alamat" className="">
|
<label htmlFor="alamat" className="mb-2">
|
||||||
<b>Alamat Institusi</b> <span className="text-red-500">*</span>
|
Alamat Institusi <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<Textarea className="" placeholder="Masukan Alamat Lengkap Institusi Anda" rows={3} value={institusiAddress} onChange={(event) => setInstitusiAddress(event.target.value)} />
|
<Textarea className="mb-3" placeholder="Masukan Alamat Lengkap Institusi Anda" rows={3} value={institusiAddress} onChange={(event) => setInstitusiAddress(event.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col px-[34px]">
|
||||||
<label htmlFor="provinsi" className="mb-2">
|
<label htmlFor="provinsi" className="mb-2">
|
||||||
<b>Provinsi</b> <span className="text-red-500">*</span>
|
Provinsi <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<select className={` ${errors.provinsi ? "block" : ""}`} {...register("provinsi")} id="provinsi" name="provinsi" onChange={(event) => getCity(event.target.value)}>
|
<select className={`mb-3 py-2 ${errors.provinsi ? "block" : ""}`} {...register("provinsi")} id="provinsi" name="provinsi" onChange={(event) => getCity(event.target.value)}>
|
||||||
<option disabled selected>
|
<option disabled selected>
|
||||||
Pilih Provinsi
|
Pilih Provinsi
|
||||||
</option>
|
</option>
|
||||||
|
|
@ -848,11 +825,11 @@ const page = () => {
|
||||||
</select>
|
</select>
|
||||||
<div className="text-red-500">{errors.provinsi?.message}</div>
|
<div className="text-red-500">{errors.provinsi?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col px-[34px]">
|
||||||
<label htmlFor="kota" className="mb-2">
|
<label htmlFor="kota" className="mb-2">
|
||||||
<b>Kota/Kabupaten</b> <span className="text-red-500">*</span>
|
Kota/Kabupaten <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<select className={` ${errors.kota ? "block" : ""}`} {...register("kota")} id="kota" onChange={(event) => getDistricts(event.target.value)}>
|
<select className={`mb-3 py-2 ${errors.kota ? "block" : ""}`} {...register("kota")} id="kota" onChange={(event) => getDistricts(event.target.value)}>
|
||||||
<option disabled selected>
|
<option disabled selected>
|
||||||
Pilih Kota/Kabupaten
|
Pilih Kota/Kabupaten
|
||||||
</option>
|
</option>
|
||||||
|
|
@ -864,11 +841,11 @@ const page = () => {
|
||||||
</select>
|
</select>
|
||||||
<div className="text-red-500">{errors.kota?.message}</div>
|
<div className="text-red-500">{errors.kota?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col px-[34px]">
|
||||||
<label htmlFor="kecamatan" className="mb-2">
|
<label htmlFor="kecamatan" className="mb-2">
|
||||||
<b>Kecamatan</b> <span className="text-red-500">*</span>
|
Kecamatan <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<select className={` ${errors.kecamatan ? "block" : ""}`} {...register("kecamatan")} id="kecamatan">
|
<select className={`py-2 ${errors.kecamatan ? "block" : ""}`} {...register("kecamatan")} id="kecamatan">
|
||||||
<option disabled selected>
|
<option disabled selected>
|
||||||
Pilih Kecamatan
|
Pilih Kecamatan
|
||||||
</option>
|
</option>
|
||||||
|
|
@ -880,7 +857,7 @@ const page = () => {
|
||||||
</select>
|
</select>
|
||||||
<div className="text-red-500">{errors.kecamatan?.message}</div>
|
<div className="text-red-500">{errors.kecamatan?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
{/* <div className="flex flex-col">
|
||||||
<label htmlFor="password" className="mb-2">
|
<label htmlFor="password" className="mb-2">
|
||||||
<b>Kata Sandi</b> <span className="text-red-500">*</span>
|
<b>Kata Sandi</b> <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -900,16 +877,45 @@ const page = () => {
|
||||||
setValPassword(e.target.value.trim());
|
setValPassword(e.target.value.trim());
|
||||||
}}
|
}}
|
||||||
required
|
required
|
||||||
/>
|
/>{" "}
|
||||||
<div className="text-red-500">{errors.password?.message}</div>
|
<a className={`text-black place-items-end -top-44 ${typePass == "text" ? "hidden" : ""}`} onClick={showPass}>
|
||||||
<a className={`text-black ${typePass == "text" ? "hidden" : ""}`} onClick={showPass}>
|
|
||||||
<Icon icon="fa:eye" />
|
<Icon icon="fa:eye" />
|
||||||
</a>
|
</a>
|
||||||
<a className={`text-black ${typePass == "password" ? "hidden" : ""}`} onClick={hidePass}>
|
<a className={`text-black ${typePass == "password" ? "hidden" : ""}`} onClick={hidePass}>
|
||||||
<Icon icon="fa:eye-slash" />
|
<Icon icon="fa:eye-slash" />
|
||||||
</a>
|
</a>
|
||||||
|
<div className="text-red-500">{errors.password?.message}</div>
|
||||||
|
</div> */}
|
||||||
|
<div className="mt-3.5 space-y-2 px-[34px]">
|
||||||
|
<Label htmlFor="password" className="mb-2 font-medium text-default-600">
|
||||||
|
Kata Sandi <span className="text-red-500">*</span>
|
||||||
|
</Label>
|
||||||
|
<div className="relative">
|
||||||
|
<Input
|
||||||
|
size="lg"
|
||||||
|
type={passwordType}
|
||||||
|
autoComplete="off"
|
||||||
|
className={` ${errors.password ? "block" : ""}`}
|
||||||
|
{...register("password")}
|
||||||
|
placeholder="Masukan Kata Sandi"
|
||||||
|
onChange={(e) => {
|
||||||
|
setValPassword(e.target.value.trim());
|
||||||
|
}}
|
||||||
|
onPaste={(e: any) => {
|
||||||
|
setValPassword(e.target.value.trim());
|
||||||
|
}}
|
||||||
|
onCopy={(e: any) => {
|
||||||
|
setValPassword(e.target.value.trim());
|
||||||
|
}}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<div className="absolute top-1/2 -translate-y-1/2 ltr:right-4 rtl:left-4 cursor-pointer" onClick={togglePasswordType}>
|
||||||
|
{passwordType === "password" ? <Icon icon="heroicons:eye" className="w-5 h-5 text-default-400" /> : <Icon icon="heroicons:eye-slash" className="w-5 h-5 text-default-400" />}{" "}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{errors.password?.message && <div className="text-destructive mt-2 text-sm">{errors.password.message}</div>}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
{/* <div className="flex flex-col">
|
||||||
<label htmlFor="password" className="mb-2">
|
<label htmlFor="password" className="mb-2">
|
||||||
<b>Konfirmasi Kata Sandi</b> <span className="text-red-500">*</span>
|
<b>Konfirmasi Kata Sandi</b> <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -937,8 +943,37 @@ const page = () => {
|
||||||
<a className={`text-dark show-pass ${typePassConf == "password" ? "hidden" : ""}`} onClick={hidePassConf}>
|
<a className={`text-dark show-pass ${typePassConf == "password" ? "hidden" : ""}`} onClick={hidePassConf}>
|
||||||
<Icon icon="fa:eye-slash" />
|
<Icon icon="fa:eye-slash" />
|
||||||
</a>
|
</a>
|
||||||
|
</div> */}
|
||||||
|
<div className="mt-3.5 space-y-2 px-[34px]">
|
||||||
|
<Label htmlFor="password" className="mb-2 font-medium text-default-600">
|
||||||
|
Konfirmasi Kata Sandi <span className="text-red-500">*</span>
|
||||||
|
</Label>
|
||||||
|
<div className="relative">
|
||||||
|
<Input
|
||||||
|
size="lg"
|
||||||
|
type={passwordConf}
|
||||||
|
autoComplete="off"
|
||||||
|
className={` ${errors.passwordConf ? "block" : ""}`}
|
||||||
|
{...register("passwordConf")}
|
||||||
|
placeholder="Masukan Kata Sandi yang Sama"
|
||||||
|
onChange={(e) => {
|
||||||
|
setValPasswordConf(e.target.value.trim());
|
||||||
|
}}
|
||||||
|
onPaste={(e: any) => {
|
||||||
|
setValPasswordConf(e.target.value.trim());
|
||||||
|
}}
|
||||||
|
onCopy={(e: any) => {
|
||||||
|
setValPasswordConf(e.target.value.trim());
|
||||||
|
}}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<div className="absolute top-1/2 -translate-y-1/2 ltr:right-4 rtl:left-4 cursor-pointer" onClick={togglePasswordType}>
|
||||||
|
{passwordConf === "same password" ? <Icon icon="heroicons:eye" className="w-5 h-5 text-default-400" /> : <Icon icon="heroicons:eye-slash" className="w-5 h-5 text-default-400" />}{" "}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-red-500">{warningPassConf}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group px-[34px]">
|
||||||
<PasswordChecklist
|
<PasswordChecklist
|
||||||
rules={["minLength", "specialChar", "number", "capital", "match"]}
|
rules={["minLength", "specialChar", "number", "capital", "match"]}
|
||||||
minLength={8}
|
minLength={8}
|
||||||
|
|
@ -959,7 +994,7 @@ const page = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="flex flex-col mt-8 mb-2 px-12"
|
className="flex flex-col mt-8 mb-2"
|
||||||
style={
|
style={
|
||||||
(stepOneActive && !stepTwoActive) || stepThreeActive
|
(stepOneActive && !stepTwoActive) || stepThreeActive
|
||||||
? {}
|
? {}
|
||||||
|
|
@ -968,7 +1003,7 @@ const page = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="text-center mb-2">
|
<div className="text-center mb-2 px-[34px]">
|
||||||
<p>
|
<p>
|
||||||
Dengan mendaftar, saya telah menyetujui <br />{" "}
|
Dengan mendaftar, saya telah menyetujui <br />{" "}
|
||||||
<a href="/privacy" target="_blank" className="text-red-500">
|
<a href="/privacy" target="_blank" className="text-red-500">
|
||||||
|
|
@ -980,10 +1015,10 @@ const page = () => {
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={`mb-5 mt-7 w-full text-center flex justify-center ${formProfile == true || stepTwoActive ? "hidden" : ""}`}>
|
<div className={`mb-5 mt-7 px-[34px] w-full text-center flex justify-center ${formProfile == true || stepTwoActive ? "hidden" : ""}`}>
|
||||||
{/* <a className="border cursor-pointer border-red-500 px-4 py-3 rounded-lg text-white bg-[#dc3545] w-full" onClick={() => handleSendOTP()}> */}
|
{/* <a className="border cursor-pointer border-red-500 px-4 py-3 rounded-lg text-white bg-[#dc3545] w-full" onClick={() => handleSendOTP()}> */}
|
||||||
<a
|
<a
|
||||||
className="border cursor-pointer border-red-500 px-4 py-3 rounded-lg text-white bg-[#dc3545] w-[400px]"
|
className="border cursor-pointer border-red-500 px-4 py-3 rounded-lg text-white bg-[#dc3545] w-[550px]"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setStepOneActive(false);
|
setStepOneActive(false);
|
||||||
setStepTwoActive(true);
|
setStepTwoActive(true);
|
||||||
|
|
@ -994,7 +1029,7 @@ const page = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="flex flex-row mt-2 mb-4"
|
className="flex justify-center items-center mt-2 mb-4 px-[34px]"
|
||||||
style={
|
style={
|
||||||
formProfile == false
|
formProfile == false
|
||||||
? {
|
? {
|
||||||
|
|
@ -1003,11 +1038,9 @@ const page = () => {
|
||||||
: {}
|
: {}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="text-center">
|
<Button type="submit" className="border w-[550px] text-center bg-red-700 text-white hover:bg-white hover:text-red-700 ">
|
||||||
<button type="submit" className="border border-red-500 text-red-500">
|
Daftar
|
||||||
Daftar
|
</Button>
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,14 @@ import Division from "@/components/landing-page/division";
|
||||||
import Navbar from "@/components/landing-page/navbar";
|
import Navbar from "@/components/landing-page/navbar";
|
||||||
import { ReactLenis } from "@studio-freight/react-lenis";
|
import { ReactLenis } from "@studio-freight/react-lenis";
|
||||||
import MountedProvider from "@/providers/mounted.provider";
|
import MountedProvider from "@/providers/mounted.provider";
|
||||||
|
import NewsTicker from "@/components/landing-page/news-tickers";
|
||||||
|
|
||||||
const Home = ({ params: { locale } }: { params: { locale: string } }) => {
|
const Home = ({ params: { locale } }: { params: { locale: string } }) => {
|
||||||
return (
|
return (
|
||||||
<MountedProvider isProtected={false}>
|
<MountedProvider isProtected={false}>
|
||||||
<ReactLenis root>
|
<ReactLenis root>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
<NewsTicker />
|
||||||
<Hero />
|
<Hero />
|
||||||
<SearchSection />
|
<SearchSection />
|
||||||
<NewContent group="mabes" type="latest" />
|
<NewContent group="mabes" type="latest" />
|
||||||
|
|
|
||||||
|
|
@ -6,29 +6,39 @@ import { getHeroData } from "@/service/landing/landing";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useParams, usePathname, useRouter } from "next/navigation";
|
import { useParams, usePathname, useRouter } from "next/navigation";
|
||||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||||
|
import { Skeleton } from "../ui/skeleton";
|
||||||
|
|
||||||
const Hero: React.FC = () => {
|
const Hero: React.FC = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const locale = params?.locale;
|
const locale = params?.locale;
|
||||||
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
const [heroData, setHeroData] = useState<any>();
|
const [heroData, setHeroData] = useState<any>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchCategories() {
|
async function fetchCategories() {
|
||||||
const url = 'https://netidhub.com/api/csrf';
|
const url = "https://netidhub.com/api/csrf";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data; // Menampilkan data yang diterima dari API
|
return data; // Menampilkan data yang diterima dari API
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fetch error: ', error);
|
console.error("Fetch error: ", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,63 +53,113 @@ const Hero: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row items-start justify-center gap-8 px-4 lg:px-20 py-4 mx-auto w-auto mt-6">
|
<div className="flex flex-col lg:flex-row items-start justify-center gap-8 px-4 lg:px-20 py-4 mx-auto w-auto mt-6">
|
||||||
{/* Section Gambar Utama */}
|
{/* Section Gambar Utama */}
|
||||||
<Carousel className="lg:w-2/3 w-full lg:h-full ">
|
{isLoading ? (
|
||||||
<CarouselContent>
|
<div className="flex flex-col space-y-3 mx-auto w-full lg:w-2/3">
|
||||||
{heroData?.map((list: any) => (
|
<Skeleton className="h-[310px] lg:h-[420px] rounded-xl" />
|
||||||
<CarouselItem key={list?.id}>
|
<div className="space-y-2">
|
||||||
<div className="relative h-[310px] lg:h-[420px]">
|
<Skeleton className="h-4 w-[250px]" />
|
||||||
<img src={list?.thumbnailLink} alt="Gambar Utama" className="w-full h-[310px] lg:h-[420px] rounded-lg object-cover" />
|
<Skeleton className="h-4 w-[200px]" />
|
||||||
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm text-black dark:text-white p-4 rounded-b-lg">
|
</div>
|
||||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-sm px-4 py-1">{list?.categoryName}</span>
|
</div>
|
||||||
<Link href={`${locale}/image/detail/${list?.slug}`}>
|
) : (
|
||||||
<h2 className="text-lg font-bold mt-2">{list?.title}</h2>
|
<Carousel className="lg:w-2/3 lg:h-full ">
|
||||||
|
<CarouselContent>
|
||||||
|
{heroData?.map((list: any) => (
|
||||||
|
<CarouselItem key={list?.id}>
|
||||||
|
<div className="relative h-[310px] lg:h-[420px]">
|
||||||
|
<img src={list?.thumbnailLink} alt="Gambar Utama" className="w-full h-[310px] lg:h-[420px] rounded-lg object-cover" />
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm text-black dark:text-white p-4 rounded-b-lg">
|
||||||
|
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-sm px-4 py-1">{list?.categoryName}</span>
|
||||||
|
<Link href={`${locale}/image/detail/${list?.slug}`}>
|
||||||
|
<h2 className="text-lg font-bold mt-2">{list?.title}</h2>
|
||||||
|
</Link>
|
||||||
|
<p className="text-xs flex flex-row items-center gap-1 mt-1">
|
||||||
|
{formatDateToIndonesian(new Date(list?.createdAt))} {list?.timezone ? list?.timezone : "WIB"}|{" "}
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M11.5 18c4 0 7.46-2.22 9.24-5.5C18.96 9.22 15.5 7 11.5 7s-7.46 2.22-9.24 5.5C4.04 15.78 7.5 18 11.5 18m0-12c4.56 0 8.5 2.65 10.36 6.5C20 16.35 16.06 19 11.5 19S3 16.35 1.14 12.5C3 8.65 6.94 6 11.5 6m0 2C14 8 16 10 16 12.5S14 17 11.5 17S7 15 7 12.5S9 8 11.5 8m0 1A3.5 3.5 0 0 0 8 12.5a3.5 3.5 0 0 0 3.5 3.5a3.5 3.5 0 0 0 3.5-3.5A3.5 3.5 0 0 0 11.5 9"
|
||||||
|
/>
|
||||||
|
</svg>{" "}
|
||||||
|
{list?.clickCount}{" "}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CarouselItem>
|
||||||
|
))}
|
||||||
|
</CarouselContent>
|
||||||
|
<CarouselPrevious />
|
||||||
|
<CarouselNext />
|
||||||
|
</Carousel>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Section Kanan */}
|
||||||
|
<div>
|
||||||
|
{isLoading ? (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-4 max-w-sm mx-auto mb-3">
|
||||||
|
<Skeleton className="h-[73px] w-16 rounded-md" />
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Skeleton className="h-4 w-[250px]" />
|
||||||
|
<Skeleton className="h-4 w-[200px]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-4 max-w-sm mx-auto mb-3">
|
||||||
|
<Skeleton className="h-[73px] w-16 rounded-md" />
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Skeleton className="h-4 w-[250px]" />
|
||||||
|
<Skeleton className="h-4 w-[200px]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-4 max-w-sm mx-auto mb-3">
|
||||||
|
<Skeleton className="h-[73px] w-16 rounded-md" />
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Skeleton className="h-4 w-[250px]" />
|
||||||
|
<Skeleton className="h-4 w-[200px]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-4 max-w-sm mx-auto mb-3">
|
||||||
|
<Skeleton className="h-[73px] w-16 rounded-md" />
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Skeleton className="h-4 w-[250px]" />
|
||||||
|
<Skeleton className="h-4 w-[200px]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-4 max-w-sm mx-auto">
|
||||||
|
<Skeleton className="h-[73px] w-16 rounded-md" />
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Skeleton className="h-4 w-[250px]" />
|
||||||
|
<Skeleton className="h-4 w-[200px]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<ul className="py-4 lg:py-0 flex flex-row lg:flex-col gap-4 flex-nowrap w-[95vw] lg:w-auto overflow-x-auto">
|
||||||
|
{heroData?.map((item: any) => (
|
||||||
|
<li key={item?.id} className="flex gap-4 flex-row lg:w-full ">
|
||||||
|
<div className="flex-shrink-0 w-24 rounded-lg">
|
||||||
|
<img src={item?.thumbnailLink} alt={item?.title} className="w-full h-[73px] object-cover rounded-lg" />
|
||||||
|
</div>
|
||||||
|
<div className="w-[280px] lg:w-auto">
|
||||||
|
<span className="text-white bg-[#bb3523] px-4 py-1 rounded-lg flex text-[8px] font-bold uppercase w-fit">{item?.categoryName}</span>
|
||||||
|
<Link href={`${locale}/image/detail/${item?.slug}`}>
|
||||||
|
<h3 className="text-base font-bold mt-2">{textEllipsis(item?.title, 30)}</h3>
|
||||||
</Link>
|
</Link>
|
||||||
<p className="text-xs flex flex-row items-center gap-1 mt-1">
|
<p className="text-[10px] flex flex-row items-center gap-1 text-gray-500 mt-1">
|
||||||
{formatDateToIndonesian(new Date(list?.createdAt))} {list?.timezone ? list?.timezone : "WIB"}|{" "}
|
{formatDateToIndonesian(new Date(item?.createdAt))} {item?.timezone ? item?.timezone : "WIB"} |{" "}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
d="M11.5 18c4 0 7.46-2.22 9.24-5.5C18.96 9.22 15.5 7 11.5 7s-7.46 2.22-9.24 5.5C4.04 15.78 7.5 18 11.5 18m0-12c4.56 0 8.5 2.65 10.36 6.5C20 16.35 16.06 19 11.5 19S3 16.35 1.14 12.5C3 8.65 6.94 6 11.5 6m0 2C14 8 16 10 16 12.5S14 17 11.5 17S7 15 7 12.5S9 8 11.5 8m0 1A3.5 3.5 0 0 0 8 12.5a3.5 3.5 0 0 0 3.5 3.5a3.5 3.5 0 0 0 3.5-3.5A3.5 3.5 0 0 0 11.5 9"
|
d="M11.5 18c4 0 7.46-2.22 9.24-5.5C18.96 9.22 15.5 7 11.5 7s-7.46 2.22-9.24 5.5C4.04 15.78 7.5 18 11.5 18m0-12c4.56 0 8.5 2.65 10.36 6.5C20 16.35 16.06 19 11.5 19S3 16.35 1.14 12.5C3 8.65 6.94 6 11.5 6m0 2C14 8 16 10 16 12.5S14 17 11.5 17S7 15 7 12.5S9 8 11.5 8m0 1A3.5 3.5 0 0 0 8 12.5a3.5 3.5 0 0 0 3.5 3.5a3.5 3.5 0 0 0 3.5-3.5A3.5 3.5 0 0 0 11.5 9"
|
||||||
/>
|
/>
|
||||||
</svg>{" "}
|
</svg>{" "}
|
||||||
{list?.clickCount}{" "}
|
{item?.clickCount}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</CarouselItem>
|
))}
|
||||||
))}
|
</ul>
|
||||||
</CarouselContent>
|
)}
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
|
|
||||||
{/* Section Kanan */}
|
|
||||||
<div className=" ">
|
|
||||||
<ul className="py-4 lg:py-0 flex flex-row lg:flex-col gap-4 flex-nowrap w-full overflow-x-auto">
|
|
||||||
{heroData?.map((item: any) => (
|
|
||||||
<li key={item?.id} className="flex gap-4 flex-row lg:w-full ">
|
|
||||||
<div className="flex-shrink-0 w-24 rounded-lg">
|
|
||||||
<img src={item?.thumbnailLink} alt={item?.title} className="w-full h-[73px] object-cover rounded-lg" />
|
|
||||||
</div>
|
|
||||||
<div className="w-[280px] lg:w-auto">
|
|
||||||
<span className="text-white bg-[#bb3523] px-4 py-1 rounded-lg flex text-[8px] font-bold uppercase w-fit">{item?.categoryName}</span>
|
|
||||||
<Link href={`${locale}/image/detail/${item?.slug}`}>
|
|
||||||
<h3 className="text-base font-bold mt-2">{textEllipsis(item?.title, 30)}</h3>
|
|
||||||
</Link>
|
|
||||||
<p className="text-[10px] flex flex-row items-center gap-1 text-gray-500 mt-1">
|
|
||||||
{formatDateToIndonesian(new Date(item?.createdAt))} {item?.timezone ? item?.timezone : "WIB"} |{" "}
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M11.5 18c4 0 7.46-2.22 9.24-5.5C18.96 9.22 15.5 7 11.5 7s-7.46 2.22-9.24 5.5C4.04 15.78 7.5 18 11.5 18m0-12c4.56 0 8.5 2.65 10.36 6.5C20 16.35 16.06 19 11.5 19S3 16.35 1.14 12.5C3 8.65 6.94 6 11.5 6m0 2C14 8 16 10 16 12.5S14 17 11.5 17S7 15 7 12.5S9 8 11.5 8m0 1A3.5 3.5 0 0 0 8 12.5a3.5 3.5 0 0 0 3.5 3.5a3.5 3.5 0 0 0 3.5-3.5A3.5 3.5 0 0 0 11.5 9"
|
|
||||||
/>
|
|
||||||
</svg>{" "}
|
|
||||||
{item?.clickCount}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,23 +6,8 @@ import { FiFile, FiImage, FiMusic, FiYoutube } from "react-icons/fi";
|
||||||
import { useParams, usePathname } from "next/navigation";
|
import { useParams, usePathname } from "next/navigation";
|
||||||
import { generateLocalizedPath } from "@/utils/globals";
|
import { generateLocalizedPath } from "@/utils/globals";
|
||||||
import { Link } from "@/i18n/routing";
|
import { Link } from "@/i18n/routing";
|
||||||
import {
|
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle } from "@/components/ui/navigation-menu";
|
||||||
NavigationMenu,
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||||
NavigationMenuContent,
|
|
||||||
NavigationMenuItem,
|
|
||||||
NavigationMenuLink,
|
|
||||||
NavigationMenuList,
|
|
||||||
NavigationMenuTrigger,
|
|
||||||
navigationMenuTriggerStyle,
|
|
||||||
} from "@/components/ui/navigation-menu";
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuGroup,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "../ui/dropdown-menu";
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Icon } from "../ui/icon";
|
import { Icon } from "../ui/icon";
|
||||||
import { getCookiesDecrypt } from "@/lib/utils";
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
|
|
@ -32,23 +17,10 @@ import { useTranslations } from "next-intl";
|
||||||
import { useRouter } from "@/i18n/routing";
|
import { useRouter } from "@/i18n/routing";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import LocalSwitcher from "../partials/header/locale-switcher";
|
import LocalSwitcher from "../partials/header/locale-switcher";
|
||||||
import {
|
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
||||||
Dialog,
|
|
||||||
DialogClose,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogFooter,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import { getUserNotifications, listRole } from "@/service/landing/landing";
|
import { getUserNotifications, listRole } from "@/service/landing/landing";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import {
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/components/ui/popover";
|
|
||||||
|
|
||||||
type Detail = {
|
type Detail = {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -89,13 +61,8 @@ const Navbar = () => {
|
||||||
const [notificationsUpdate, setNotificationsUpdate] = useState([]);
|
const [notificationsUpdate, setNotificationsUpdate] = useState([]);
|
||||||
const [selectedTab, setSelectedTab] = useState("image");
|
const [selectedTab, setSelectedTab] = useState("image");
|
||||||
|
|
||||||
let prefixPath = poldaName
|
let prefixPath = poldaName ? `/polda/${poldaName}` : satkerName ? `/satker/${satkerName}` : "/";
|
||||||
? `/polda/${poldaName}`
|
|
||||||
: satkerName
|
|
||||||
? `/satker/${satkerName}`
|
|
||||||
: "/";
|
|
||||||
|
|
||||||
let active = "";
|
|
||||||
let menu = "";
|
let menu = "";
|
||||||
|
|
||||||
const onLogout = () => {
|
const onLogout = () => {
|
||||||
|
|
@ -179,41 +146,18 @@ const Navbar = () => {
|
||||||
<div className="flex items-center justify-between px-4 lg:px-20 py-4 gap-3">
|
<div className="flex items-center justify-between px-4 lg:px-20 py-4 gap-3">
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Link href={prefixPath} className="flex items-center">
|
<Link href={prefixPath} className="flex items-center">
|
||||||
<img
|
<img src="/assets/mediahub-logo.gif" alt="Media Hub Logo" className="object-contain h-20" />
|
||||||
src="/assets/mediahub-logo.gif"
|
|
||||||
alt="Media Hub Logo"
|
|
||||||
className="object-contain h-20"
|
|
||||||
/>
|
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* Mobile Menu Toggle */}
|
{/* Mobile Menu Toggle */}
|
||||||
<button
|
<button className="text-black dark:text-white right-0 size-20 h-10 w-10 lg:hidden" onClick={() => setMenuOpen(!menuOpen)}>
|
||||||
className="text-black dark:text-white right-0 size-20 h-10 w-10 lg:hidden"
|
|
||||||
onClick={() => setMenuOpen(!menuOpen)}
|
|
||||||
>
|
|
||||||
{menuOpen ? (
|
{menuOpen ? (
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<path fill="#000" d="m13.41 12l4.3-4.29a1 1 0 1 0-1.42-1.42L12 10.59l-4.29-4.3a1 1 0 0 0-1.42 1.42l4.3 4.29l-4.3 4.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0l4.29-4.3l4.29 4.3a1 1 0 0 0 1.42 0a1 1 0 0 0 0-1.42Z" />
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="#000"
|
|
||||||
d="m13.41 12l4.3-4.29a1 1 0 1 0-1.42-1.42L12 10.59l-4.29-4.3a1 1 0 0 0-1.42 1.42l4.3 4.29l-4.3 4.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0l4.29-4.3l4.29 4.3a1 1 0 0 0 1.42 0a1 1 0 0 0 0-1.42Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<path fill="#000" d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z" />
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="#000"
|
|
||||||
d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -226,14 +170,7 @@ const Navbar = () => {
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
<NavigationMenuTrigger>
|
<NavigationMenuTrigger>
|
||||||
<a className="dark:text-white text-black flex flex-row justify-center items-center cursor-pointer">
|
<a className="dark:text-white text-black flex flex-row justify-center items-center cursor-pointer">
|
||||||
<svg
|
<svg className="mx-2 dark:" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
className="mx-2 dark:"
|
|
||||||
width="25"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 25 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M20 7.5H5C4.6023 7.5004 4.221 7.65856 3.93978 7.93978C3.65856 8.221 3.5004 8.6023 3.5 9V19.5C3.5004 19.8977 3.65856 20.279 3.93978 20.5602C4.221 20.8414 4.6023 20.9996 5 21H20C20.3977 20.9996 20.779 20.8414 21.0602 20.5602C21.3414 20.279 21.4996 19.8977 21.5 19.5V9C21.4996 8.6023 21.3414 8.221 21.0602 7.93978C20.779 7.65856 20.3977 7.5004 20 7.5ZM10.25 17.25V11.25L15.5 14.25L10.25 17.25ZM5 4.5H20V6H5V4.5ZM6.5 1.5H18.5V3H6.5V1.5Z"
|
d="M20 7.5H5C4.6023 7.5004 4.221 7.65856 3.93978 7.93978C3.65856 8.221 3.5004 8.6023 3.5 9V19.5C3.5004 19.8977 3.65856 20.279 3.93978 20.5602C4.221 20.8414 4.6023 20.9996 5 21H20C20.3977 20.9996 20.779 20.8414 21.0602 20.5602C21.3414 20.279 21.4996 19.8977 21.5 19.5V9C21.4996 8.6023 21.3414 8.221 21.0602 7.93978C20.779 7.65856 20.3977 7.5004 20 7.5ZM10.25 17.25V11.25L15.5 14.25L10.25 17.25ZM5 4.5H20V6H5V4.5ZM6.5 1.5H18.5V3H6.5V1.5Z"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
|
|
@ -243,19 +180,13 @@ const Navbar = () => {
|
||||||
</a>
|
</a>
|
||||||
</NavigationMenuTrigger>
|
</NavigationMenuTrigger>
|
||||||
<NavigationMenuContent className="flex flex-col place-content-start rounded-md overflow-hidden ">
|
<NavigationMenuContent className="flex flex-col place-content-start rounded-md overflow-hidden ">
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(prefixPath + "/image/filter")} className="flex place-items-start gap-1.5 p-2 w-36">
|
||||||
onClick={() => router.push(prefixPath + "/image/filter")}
|
|
||||||
className="flex place-items-start gap-1.5 p-2 w-36"
|
|
||||||
>
|
|
||||||
<p className="text-slate-600 dark:text-white hover:text-[#bb3523] flex flex-row items-center py-2 cursor-pointer">
|
<p className="text-slate-600 dark:text-white hover:text-[#bb3523] flex flex-row items-center py-2 cursor-pointer">
|
||||||
<FiImage className="mr-2" />
|
<FiImage className="mr-2" />
|
||||||
{t("image")}
|
{t("image")}
|
||||||
</p>
|
</p>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(prefixPath + "/video/filter")} className="flex items-start gap-1.5 p-2 ">
|
||||||
onClick={() => router.push(prefixPath + "/video/filter")}
|
|
||||||
className="flex items-start gap-1.5 p-2 "
|
|
||||||
>
|
|
||||||
{pathname?.split("/")[1] == "in" ? (
|
{pathname?.split("/")[1] == "in" ? (
|
||||||
<>
|
<>
|
||||||
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-2 cursor-pointer">
|
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-2 cursor-pointer">
|
||||||
|
|
@ -272,19 +203,13 @@ const Navbar = () => {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(prefixPath + "/document/filter")} className="flex place-items-start gap-1.5 p-2">
|
||||||
onClick={() => router.push(prefixPath + "/document/filter")}
|
|
||||||
className="flex place-items-start gap-1.5 p-2"
|
|
||||||
>
|
|
||||||
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-2 cursor-pointer">
|
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-2 cursor-pointer">
|
||||||
<FiFile className="mr-2" />
|
<FiFile className="mr-2" />
|
||||||
{t("text")}
|
{t("text")}
|
||||||
</p>
|
</p>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(prefixPath + "/audio/filter")} className="flex place-items-start gap-1.5 p-2 ">
|
||||||
onClick={() => router.push(prefixPath + "/audio/filter")}
|
|
||||||
className="flex place-items-start gap-1.5 p-2 "
|
|
||||||
>
|
|
||||||
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-2 cursor-pointer">
|
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-2 cursor-pointer">
|
||||||
<FiMusic className="mr-2" />
|
<FiMusic className="mr-2" />
|
||||||
{t("audio")}{" "}
|
{t("audio")}{" "}
|
||||||
|
|
@ -296,14 +221,7 @@ const Navbar = () => {
|
||||||
<Link href={prefixPath + "/schedule"} legacyBehavior passHref>
|
<Link href={prefixPath + "/schedule"} legacyBehavior passHref>
|
||||||
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
<span>
|
<span>
|
||||||
<svg
|
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
className="mr-2"
|
|
||||||
width="25"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 25 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M19.5 4H18.5V3C18.5 2.4 18.1 2 17.5 2C16.9 2 16.5 2.4 16.5 3V4H8.5V3C8.5 2.4 8.1 2 7.5 2C6.9 2 6.5 2.4 6.5 3V4H5.5C3.8 4 2.5 5.3 2.5 7V8H22.5V7C22.5 5.3 21.2 4 19.5 4ZM2.5 19C2.5 20.7 3.8 22 5.5 22H19.5C21.2 22 22.5 20.7 22.5 19V10H2.5V19ZM17.5 12C18.1 12 18.5 12.4 18.5 13C18.5 13.6 18.1 14 17.5 14C16.9 14 16.5 13.6 16.5 13C16.5 12.4 16.9 12 17.5 12ZM17.5 16C18.1 16 18.5 16.4 18.5 17C18.5 17.6 18.1 18 17.5 18C16.9 18 16.5 17.6 16.5 17C16.5 16.4 16.9 16 17.5 16ZM12.5 12C13.1 12 13.5 12.4 13.5 13C13.5 13.6 13.1 14 12.5 14C11.9 14 11.5 13.6 11.5 13C11.5 12.4 11.9 12 12.5 12ZM12.5 16C13.1 16 13.5 16.4 13.5 17C13.5 17.6 13.1 18 12.5 18C11.9 18 11.5 17.6 11.5 17C11.5 16.4 11.9 16 12.5 16ZM7.5 12C8.1 12 8.5 12.4 8.5 13C8.5 13.6 8.1 14 7.5 14C6.9 14 6.5 13.6 6.5 13C6.5 12.4 6.9 12 7.5 12ZM7.5 16C8.1 16 8.5 16.4 8.5 17C8.5 17.6 8.1 18 7.5 18C6.9 18 6.5 17.6 6.5 17C6.5 16.4 6.9 16 7.5 16Z"
|
d="M19.5 4H18.5V3C18.5 2.4 18.1 2 17.5 2C16.9 2 16.5 2.4 16.5 3V4H8.5V3C8.5 2.4 8.1 2 7.5 2C6.9 2 6.5 2.4 6.5 3V4H5.5C3.8 4 2.5 5.3 2.5 7V8H22.5V7C22.5 5.3 21.2 4 19.5 4ZM2.5 19C2.5 20.7 3.8 22 5.5 22H19.5C21.2 22 22.5 20.7 22.5 19V10H2.5V19ZM17.5 12C18.1 12 18.5 12.4 18.5 13C18.5 13.6 18.1 14 17.5 14C16.9 14 16.5 13.6 16.5 13C16.5 12.4 16.9 12 17.5 12ZM17.5 16C18.1 16 18.5 16.4 18.5 17C18.5 17.6 18.1 18 17.5 18C16.9 18 16.5 17.6 16.5 17C16.5 16.4 16.9 16 17.5 16ZM12.5 12C13.1 12 13.5 12.4 13.5 13C13.5 13.6 13.1 14 12.5 14C11.9 14 11.5 13.6 11.5 13C11.5 12.4 11.9 12 12.5 12ZM12.5 16C13.1 16 13.5 16.4 13.5 17C13.5 17.6 13.1 18 12.5 18C11.9 18 11.5 17.6 11.5 17C11.5 16.4 11.9 16 12.5 16ZM7.5 12C8.1 12 8.5 12.4 8.5 13C8.5 13.6 8.1 14 7.5 14C6.9 14 6.5 13.6 6.5 13C6.5 12.4 6.9 12 7.5 12ZM7.5 16C8.1 16 8.5 16.4 8.5 17C8.5 17.6 8.1 18 7.5 18C6.9 18 6.5 17.6 6.5 17C6.5 16.4 6.9 16 7.5 16Z"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
|
|
@ -318,14 +236,7 @@ const Navbar = () => {
|
||||||
<Link href={prefixPath + "/indeks"} legacyBehavior passHref>
|
<Link href={prefixPath + "/indeks"} legacyBehavior passHref>
|
||||||
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
<span>
|
<span>
|
||||||
<svg
|
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
className="mr-2"
|
|
||||||
width="25"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 25 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
clip-rule="evenodd"
|
clip-rule="evenodd"
|
||||||
|
|
@ -341,16 +252,49 @@ const Navbar = () => {
|
||||||
</NavigationMenuList>
|
</NavigationMenuList>
|
||||||
</NavigationMenu>
|
</NavigationMenu>
|
||||||
|
|
||||||
|
{roleId == undefined ? (
|
||||||
|
""
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className="my-auto items-center cursor-pointer"
|
||||||
|
style={
|
||||||
|
Number(roleId) == 5 || Number(roleId) == 8
|
||||||
|
? {
|
||||||
|
display: "none",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
href="https://spit.humas.polri.go.id"
|
||||||
|
className=""
|
||||||
|
target="_blank"
|
||||||
|
style={
|
||||||
|
menuActive == "indeks"
|
||||||
|
? {
|
||||||
|
color: "#fff",
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
color: "#1F1A17",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
legacyBehavior
|
||||||
|
>
|
||||||
|
<div className="flex flex-row items-center gap-1">
|
||||||
|
<Icon icon="gravity-ui:database-fill" fontSize={25} />
|
||||||
|
<p className="text-xs font-semibold">Raw Data</p>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* <Link href="#" className="flex items-center space-x-1 text-red-600">
|
{/* <Link href="#" className="flex items-center space-x-1 text-red-600">
|
||||||
<span className="w-2 h-2 bg-red-500 rounded-full"></span>
|
<span className="w-2 h-2 bg-red-500 rounded-full"></span>
|
||||||
<span className="font-medium">{t("live")}</span>
|
<span className="font-medium">{t("live")}</span>
|
||||||
</Link> */}
|
</Link> */}
|
||||||
<div className="flex items-center space-x-1 ">
|
<div className="flex items-center space-x-1 ">
|
||||||
<a href="https://tvradio.polri.go.id/">
|
<a href="https://tvradio.polri.go.id/">
|
||||||
<img
|
<img src="/assets/polriTv.png" className="object-contain h-10 flex-auto " />
|
||||||
src="/assets/polriTv.png"
|
|
||||||
className="object-contain h-10 flex-auto "
|
|
||||||
/>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -372,12 +316,7 @@ const Navbar = () => {
|
||||||
className="pl-8 pr-4 py-1 w-28 text-[13px] border rounded-full focus:outline-none dark:text-white"
|
className="pl-8 pr-4 py-1 w-28 text-[13px] border rounded-full focus:outline-none dark:text-white"
|
||||||
/>
|
/>
|
||||||
<span className="absolute left-4 top-1/2 transform -translate-y-1/2">
|
<span className="absolute left-4 top-1/2 transform -translate-y-1/2">
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="13"
|
|
||||||
height="13"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
|
|
@ -433,37 +372,22 @@ const Navbar = () => {
|
||||||
)}
|
)}
|
||||||
</div> */}
|
</div> */}
|
||||||
|
|
||||||
{roleId === "5" ||
|
{roleId === "5" || roleId === "6" || roleId === "7" || roleId === "8" ? (
|
||||||
roleId === "6" ||
|
|
||||||
roleId === "7" ||
|
|
||||||
roleId === "8" ? (
|
|
||||||
<>
|
<>
|
||||||
{/* Inbox */}
|
{/* Inbox */}
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<a className="cursor-pointer" onClick={() => test()}>
|
<a className="cursor-pointer" onClick={() => test()}>
|
||||||
{" "}
|
{" "}
|
||||||
<Icon
|
<Icon icon="basil:envelope-outline" color="black" width="30" />
|
||||||
icon="basil:envelope-outline"
|
|
||||||
color="black"
|
|
||||||
width="30"
|
|
||||||
/>
|
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className=" p-0 flex flex-col mt-2" align="end">
|
<PopoverContent className="w-[320px] p-0 flex flex-col mt-2" align="end">
|
||||||
<Tabs
|
<Tabs value={selectedTab} onValueChange={setSelectedTab} className="flex flex-col">
|
||||||
value={selectedTab}
|
|
||||||
onValueChange={setSelectedTab}
|
|
||||||
className="flex flex-col"
|
|
||||||
>
|
|
||||||
<TabsList className="grid grid-cols-2 lg:flex lg:flex-row">
|
<TabsList className="grid grid-cols-2 lg:flex lg:flex-row">
|
||||||
<TabsTrigger value="notif-tab">
|
<TabsTrigger value="notif-tab" className="focus:bg-none">
|
||||||
<a
|
<a
|
||||||
className={`flex items-center justify-center cursor-pointer gap-4 rounded-lg p-3 text-sm mr-4 ${
|
className={`flex items-center justify-center cursor-pointer gap-4 rounded-lg p-3 text-sm ml-3 mr-4 ${selectedTab === "notif-tab" ? "bg-[#bb3523] text-white" : "bg-gray-200 text-black"}`}
|
||||||
selectedTab === "notif-tab"
|
|
||||||
? "bg-[#bb3523] text-white"
|
|
||||||
: "bg-gray-200 text-black"
|
|
||||||
}`}
|
|
||||||
id="notif-tab"
|
id="notif-tab"
|
||||||
data-toggle="tab"
|
data-toggle="tab"
|
||||||
role="tab"
|
role="tab"
|
||||||
|
|
@ -476,11 +400,7 @@ const Navbar = () => {
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="notifupdate-tab">
|
<TabsTrigger value="notifupdate-tab">
|
||||||
<a
|
<a
|
||||||
className={`flex items-center cursor-pointer gap-4 rounded-lg p-3 text-sm mr-4 ${
|
className={`flex items-center cursor-pointer gap-4 rounded-lg p-3 text-sm ml-3 mr-4 ${selectedTab === "notifupdate-tab" ? "bg-[#bb3523] text-white" : "bg-gray-200 text-black"}`}
|
||||||
selectedTab === "notifupdate-tab"
|
|
||||||
? "bg-[#bb3523] text-white"
|
|
||||||
: "bg-gray-200 text-black"
|
|
||||||
}`}
|
|
||||||
id="notifupdate-tab"
|
id="notifupdate-tab"
|
||||||
data-toggle="tab"
|
data-toggle="tab"
|
||||||
role="tab"
|
role="tab"
|
||||||
|
|
@ -496,43 +416,22 @@ const Navbar = () => {
|
||||||
<TabsContent value="notif-tab">
|
<TabsContent value="notif-tab">
|
||||||
<div className="flex flex-col justify-center my-3">
|
<div className="flex flex-col justify-center my-3">
|
||||||
{notifications?.map((list: any) => (
|
{notifications?.map((list: any) => (
|
||||||
<a
|
<a className="flex flex-row" href={list.redirectUrl} key={list.id}>
|
||||||
className="flex flex-row"
|
|
||||||
href={list.redirectUrl}
|
|
||||||
key={list.id}
|
|
||||||
>
|
|
||||||
<div className="ml-4">
|
<div className="ml-4">
|
||||||
<img
|
<img src="/assets/avatar-profile.png" alt="..." className="w-8 items-center mr-3" />
|
||||||
src="/assets/avatar-profile.png"
|
|
||||||
alt="..."
|
|
||||||
className="w-8 items-center mr-3"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
<div className="text-wrap text-left">{list?.message}</div>
|
||||||
<div className="text-wrap text-left">
|
<div>
|
||||||
{list?.message}
|
<small>
|
||||||
</div>
|
{`${new Date(list?.createdAt).getDate()}/${new Date(list?.createdAt).getMonth() + 1}/${new Date(list?.createdAt).getFullYear()} ${new Date(list?.createdAt).getHours()}:${new Date(
|
||||||
<div>
|
list?.createdAt
|
||||||
<small>
|
).getMinutes()}`}{" "}
|
||||||
{`${new Date(list?.createdAt).getDate()}/${
|
</small>
|
||||||
new Date(list?.createdAt).getMonth() + 1
|
|
||||||
}/${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getFullYear()} ${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getHours()}:${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getMinutes()}`}{" "}
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
<Link href="/inbox" legacyBehavior>
|
<Link href="/inbox" legacyBehavior>
|
||||||
<p
|
<p className="text-[15px] text-center py-2" role="button">
|
||||||
className="text-[15px] text-center py-2"
|
|
||||||
role="button"
|
|
||||||
>
|
|
||||||
Lihat semua
|
Lihat semua
|
||||||
</p>
|
</p>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
@ -541,31 +440,15 @@ const Navbar = () => {
|
||||||
<TabsContent value="notifupdate-tab">
|
<TabsContent value="notifupdate-tab">
|
||||||
<div className="">
|
<div className="">
|
||||||
{notificationsUpdate?.map((list: any) => (
|
{notificationsUpdate?.map((list: any) => (
|
||||||
<a
|
<a className="flex flex-row" href={list.redirectUrl} key={list.id}>
|
||||||
className="flex flex-row"
|
|
||||||
href={list.redirectUrl}
|
|
||||||
key={list.id}
|
|
||||||
>
|
|
||||||
<div className="ml-4">
|
<div className="ml-4">
|
||||||
<img
|
<img src="/assets/avatar-profile.png" alt="..." className="w-8 items-center mr-3" />
|
||||||
src="/assets/avatar-profile.png"
|
|
||||||
alt="..."
|
|
||||||
className="w-8 items-center mr-3"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="text-wrap text-left">
|
<div className="text-wrap text-left">{list?.message}</div>
|
||||||
{list?.message}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<small>
|
<small>
|
||||||
{`${new Date(list?.createdAt).getDate()}/${
|
{`${new Date(list?.createdAt).getDate()}/${new Date(list?.createdAt).getMonth() + 1}/${new Date(list?.createdAt).getFullYear()} ${new Date(list?.createdAt).getHours()}:${new Date(
|
||||||
new Date(list?.createdAt).getMonth() + 1
|
|
||||||
}/${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getFullYear()} ${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getHours()}:${new Date(
|
|
||||||
list?.createdAt
|
list?.createdAt
|
||||||
).getMinutes()}`}{" "}
|
).getMinutes()}`}{" "}
|
||||||
</small>
|
</small>
|
||||||
|
|
@ -574,10 +457,7 @@ const Navbar = () => {
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
<Link href="/inbox/update" legacyBehavior>
|
<Link href="/inbox/update" legacyBehavior>
|
||||||
<p
|
<p className="text-[15px] text-center py-2" role="button">
|
||||||
className="text-[15px] text-center py-2"
|
|
||||||
role="button"
|
|
||||||
>
|
|
||||||
Lihat semua
|
Lihat semua
|
||||||
</p>
|
</p>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
@ -590,20 +470,10 @@ const Navbar = () => {
|
||||||
<DropdownMenuTrigger asChild className="cursor-pointer">
|
<DropdownMenuTrigger asChild className="cursor-pointer">
|
||||||
{detail !== undefined ? (
|
{detail !== undefined ? (
|
||||||
<div className="flex items-center gap-3 text-default-800">
|
<div className="flex items-center gap-3 text-default-800">
|
||||||
<Image
|
<Image src={"/assets/avatar-profile.png"} alt={"Image"} width={36} height={36} className="rounded-full" />
|
||||||
src={"/assets/avatar-profile.png"}
|
|
||||||
alt={"Image"}
|
|
||||||
width={36}
|
|
||||||
height={36}
|
|
||||||
className="rounded-full"
|
|
||||||
/>
|
|
||||||
<div>
|
<div>
|
||||||
<div className="text-sm font-medium capitalize lg:block hidden whitespace-nowrap overflow-hidden truncate">
|
<div className="text-sm font-medium capitalize lg:block hidden whitespace-nowrap overflow-hidden truncate">{detail?.fullname}</div>
|
||||||
{detail?.fullname}
|
<p className="text-xs whitespace-nowrap overflow-hidden truncate">({detail?.fullname})</p>
|
||||||
</div>
|
|
||||||
<p className="text-xs whitespace-nowrap overflow-hidden truncate">
|
|
||||||
({detail?.fullname})
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<span className="text-base me-2.5 lg:inline-block hidden">
|
<span className="text-base me-2.5 lg:inline-block hidden">
|
||||||
<Icon icon="heroicons-outline:chevron-down"></Icon>
|
<Icon icon="heroicons-outline:chevron-down"></Icon>
|
||||||
|
|
@ -627,11 +497,7 @@ const Navbar = () => {
|
||||||
href: "/content-management/galery",
|
href: "/content-management/galery",
|
||||||
},
|
},
|
||||||
].map((item, index) => (
|
].map((item, index) => (
|
||||||
<Link
|
<Link href={item.href} key={`info-menu-${index}`} className="cursor-pointer">
|
||||||
href={item.href}
|
|
||||||
key={`info-menu-${index}`}
|
|
||||||
className="cursor-pointer"
|
|
||||||
>
|
|
||||||
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize px-3 py-1.5 cursor-pointer">
|
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize px-3 py-1.5 cursor-pointer">
|
||||||
<Icon icon={item.icon} className="w-4 h-4" />
|
<Icon icon={item.icon} className="w-4 h-4" />
|
||||||
{item.name}
|
{item.name}
|
||||||
|
|
@ -643,11 +509,7 @@ const Navbar = () => {
|
||||||
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize my-1 px-3 cursor-pointer">
|
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize my-1 px-3 cursor-pointer">
|
||||||
<div>
|
<div>
|
||||||
<Link href={"/"}>
|
<Link href={"/"}>
|
||||||
<button
|
<button type="submit" className="w-full flex items-center gap-2" onClick={onLogout}>
|
||||||
type="submit"
|
|
||||||
className="w-full flex items-center gap-2"
|
|
||||||
onClick={onLogout}
|
|
||||||
>
|
|
||||||
<Icon icon="heroicons:power" className="w-4 h-4" />
|
<Icon icon="heroicons:power" className="w-4 h-4" />
|
||||||
{t("logOut")}
|
{t("logOut")}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -657,42 +519,22 @@ const Navbar = () => {
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</>
|
</>
|
||||||
) : roleId === "2" ||
|
) : roleId === "2" || roleId === "3" || roleId === "4" || roleId === "9" || roleId === "10" || roleId === "11" || roleId === "12" || roleId === "13" ? (
|
||||||
roleId === "3" ||
|
|
||||||
roleId === "4" ||
|
|
||||||
roleId === "9" ||
|
|
||||||
roleId === "10" ||
|
|
||||||
roleId === "11" ||
|
|
||||||
roleId === "12" ||
|
|
||||||
roleId === "13" ? (
|
|
||||||
<>
|
<>
|
||||||
{/* Inbox */}
|
{/* Inbox */}
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<a className="cursor-pointer" onClick={() => test()}>
|
<a className="cursor-pointer" onClick={() => test()}>
|
||||||
{" "}
|
{" "}
|
||||||
<Icon
|
<Icon icon="basil:envelope-outline" color="black" width="30" />
|
||||||
icon="basil:envelope-outline"
|
|
||||||
color="black"
|
|
||||||
width="30"
|
|
||||||
/>
|
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent
|
<PopoverContent className=" p-0 h-32 flex flex-col mt-2" align="end">
|
||||||
className=" p-0 h-32 flex flex-col mt-2"
|
<Tabs value={selectedTab} onValueChange={setSelectedTab} className="flex flex-row">
|
||||||
align="end"
|
|
||||||
>
|
|
||||||
<Tabs
|
|
||||||
value={selectedTab}
|
|
||||||
onValueChange={setSelectedTab}
|
|
||||||
className="flex flex-row"
|
|
||||||
>
|
|
||||||
<TabsList className="grid grid-cols-2 lg:flex lg:flex-row ">
|
<TabsList className="grid grid-cols-2 lg:flex lg:flex-row ">
|
||||||
<TabsTrigger value="notif-tab">
|
<TabsTrigger value="notif-tab">
|
||||||
<a
|
<a
|
||||||
className={`flex items-center justify-center cursor-pointer bg-[#bb3523] text-white gap-4 rounded-lg p-3 text-sm mr-4 ${
|
className={`flex items-center justify-center cursor-pointer bg-[#bb3523] text-white gap-4 rounded-lg p-3 text-sm mr-4 ${isMessageActive ? "active" : ""}`}
|
||||||
isMessageActive ? "active" : ""
|
|
||||||
}`}
|
|
||||||
id="notif-tab"
|
id="notif-tab"
|
||||||
data-toggle="tab"
|
data-toggle="tab"
|
||||||
role="tab"
|
role="tab"
|
||||||
|
|
@ -705,9 +547,7 @@ const Navbar = () => {
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="notifupdate-tab">
|
<TabsTrigger value="notifupdate-tab">
|
||||||
<a
|
<a
|
||||||
className={`flex items-center cursor-pointer bg-[#bb3523] text-white text-sm gap-4 rounded-lg p-3 mr-4 ${
|
className={`flex items-center cursor-pointer bg-[#bb3523] text-white text-sm gap-4 rounded-lg p-3 mr-4 ${isMessageActive ? "" : "active"}`}
|
||||||
isMessageActive ? "" : "active"
|
|
||||||
}`}
|
|
||||||
id="notifupdate-tab"
|
id="notifupdate-tab"
|
||||||
data-toggle="tab"
|
data-toggle="tab"
|
||||||
role="tab"
|
role="tab"
|
||||||
|
|
@ -721,33 +561,17 @@ const Navbar = () => {
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div
|
<div className={`flex justify-center my-3 ${isMessageActive ? "active" : ""}`}>
|
||||||
className={`flex justify-center my-3 ${
|
|
||||||
isMessageActive ? "active" : ""
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{notifications?.map((list: any) => (
|
{notifications?.map((list: any) => (
|
||||||
<a className="" href={list.redirectUrl} key={list.id}>
|
<a className="" href={list.redirectUrl} key={list.id}>
|
||||||
<div className="">
|
<div className="">
|
||||||
<img
|
<img src="/assets/avatar-profile.png" alt="..." className="" />
|
||||||
src="/assets/avatar-profile.png"
|
|
||||||
alt="..."
|
|
||||||
className=""
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="text-wrap text-left">
|
<div className="text-wrap text-left">{list?.message}</div>
|
||||||
{list?.message}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<small>
|
<small>
|
||||||
{`${new Date(list?.createdAt).getDate()}/${
|
{`${new Date(list?.createdAt).getDate()}/${new Date(list?.createdAt).getMonth() + 1}/${new Date(list?.createdAt).getFullYear()} ${new Date(list?.createdAt).getHours()}:${new Date(
|
||||||
new Date(list?.createdAt).getMonth() + 1
|
|
||||||
}/${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getFullYear()} ${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getHours()}:${new Date(
|
|
||||||
list?.createdAt
|
list?.createdAt
|
||||||
).getMinutes()}`}{" "}
|
).getMinutes()}`}{" "}
|
||||||
</small>
|
</small>
|
||||||
|
|
@ -761,37 +585,17 @@ const Navbar = () => {
|
||||||
</p>
|
</p>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className={`flex flex-col justify-center my-3 ${isMessageActive ? "active" : ""}`}>
|
||||||
className={`flex flex-col justify-center my-3 ${
|
|
||||||
isMessageActive ? "active" : ""
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{notificationsUpdate?.map((list: any) => (
|
{notificationsUpdate?.map((list: any) => (
|
||||||
<a
|
<a className="flex flex-row" href={list.redirectUrl} key={list.id}>
|
||||||
className="flex flex-row"
|
|
||||||
href={list.redirectUrl}
|
|
||||||
key={list.id}
|
|
||||||
>
|
|
||||||
<div className="ml-4">
|
<div className="ml-4">
|
||||||
<img
|
<img src="/assets/avatar-profile.png" alt="..." className="w-8 items-center mr-3" />
|
||||||
src="/assets/avatar-profile.png"
|
|
||||||
alt="..."
|
|
||||||
className="w-8 items-center mr-3"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="text-wrap text-left">
|
<div className="text-wrap text-left">{list?.message}</div>
|
||||||
{list?.message}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<small>
|
<small>
|
||||||
{`${new Date(list?.createdAt).getDate()}/${
|
{`${new Date(list?.createdAt).getDate()}/${new Date(list?.createdAt).getMonth() + 1}/${new Date(list?.createdAt).getFullYear()} ${new Date(list?.createdAt).getHours()}:${new Date(
|
||||||
new Date(list?.createdAt).getMonth() + 1
|
|
||||||
}/${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getFullYear()} ${new Date(
|
|
||||||
list?.createdAt
|
|
||||||
).getHours()}:${new Date(
|
|
||||||
list?.createdAt
|
list?.createdAt
|
||||||
).getMinutes()}`}{" "}
|
).getMinutes()}`}{" "}
|
||||||
</small>
|
</small>
|
||||||
|
|
@ -813,20 +617,10 @@ const Navbar = () => {
|
||||||
<DropdownMenuTrigger asChild className="cursor-pointer">
|
<DropdownMenuTrigger asChild className="cursor-pointer">
|
||||||
{detail !== undefined ? (
|
{detail !== undefined ? (
|
||||||
<div className="flex items-center gap-3 text-default-800">
|
<div className="flex items-center gap-3 text-default-800">
|
||||||
<Image
|
<Image src={"/assets/avatar-profile.png"} alt={"Image"} width={36} height={36} className="rounded-full" />
|
||||||
src={"/assets/avatar-profile.png"}
|
|
||||||
alt={"Image"}
|
|
||||||
width={36}
|
|
||||||
height={36}
|
|
||||||
className="rounded-full"
|
|
||||||
/>
|
|
||||||
<div>
|
<div>
|
||||||
<div className="text-sm font-medium capitalize lg:block hidden whitespace-nowrap overflow-hidden truncate">
|
<div className="text-sm font-medium capitalize lg:block hidden whitespace-nowrap overflow-hidden truncate">{detail?.fullname}</div>
|
||||||
{detail?.fullname}
|
<p className="text-xs whitespace-nowrap overflow-hidden truncate">({detail?.fullname})</p>
|
||||||
</div>
|
|
||||||
<p className="text-xs whitespace-nowrap overflow-hidden truncate">
|
|
||||||
({detail?.fullname})
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<span className="text-base me-2.5 lg:inline-block hidden">
|
<span className="text-base me-2.5 lg:inline-block hidden">
|
||||||
<Icon icon="heroicons-outline:chevron-down"></Icon>
|
<Icon icon="heroicons-outline:chevron-down"></Icon>
|
||||||
|
|
@ -850,11 +644,7 @@ const Navbar = () => {
|
||||||
href: "/dashboard",
|
href: "/dashboard",
|
||||||
},
|
},
|
||||||
].map((item, index) => (
|
].map((item, index) => (
|
||||||
<Link
|
<Link href={item.href} key={`info-menu-${index}`} className="cursor-pointer">
|
||||||
href={item.href}
|
|
||||||
key={`info-menu-${index}`}
|
|
||||||
className="cursor-pointer"
|
|
||||||
>
|
|
||||||
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize px-3 py-1.5 cursor-pointer">
|
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize px-3 py-1.5 cursor-pointer">
|
||||||
<Icon icon={item.icon} className="w-4 h-4" />
|
<Icon icon={item.icon} className="w-4 h-4" />
|
||||||
{item.name}
|
{item.name}
|
||||||
|
|
@ -866,11 +656,7 @@ const Navbar = () => {
|
||||||
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize my-1 px-3 cursor-pointer">
|
<DropdownMenuItem className="flex items-center gap-2 text-sm font-medium text-default-600 capitalize my-1 px-3 cursor-pointer">
|
||||||
<div>
|
<div>
|
||||||
<Link href={"/"}>
|
<Link href={"/"}>
|
||||||
<button
|
<button type="submit" className="w-full flex items-center gap-2" onClick={onLogout}>
|
||||||
type="submit"
|
|
||||||
className="w-full flex items-center gap-2"
|
|
||||||
onClick={onLogout}
|
|
||||||
>
|
|
||||||
<Icon icon="heroicons:power" className="w-4 h-4" />
|
<Icon icon="heroicons:power" className="w-4 h-4" />
|
||||||
{t("logOut")}
|
{t("logOut")}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -883,39 +669,22 @@ const Navbar = () => {
|
||||||
) : (
|
) : (
|
||||||
// Masuk and Daftar buttons for roleId === null
|
// Masuk and Daftar buttons for roleId === null
|
||||||
<div className="flex justify-center items-center mx-3 gap-5">
|
<div className="flex justify-center items-center mx-3 gap-5">
|
||||||
<Link
|
<Link href="/auth" className="w-full lg:w-max px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 text-center">
|
||||||
href="/auth"
|
|
||||||
className="w-full lg:w-max px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 text-center"
|
|
||||||
>
|
|
||||||
{t("logIn")}
|
{t("logIn")}
|
||||||
</Link>
|
</Link>
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button className="w-full lg:w-fit px-4 h-8 border bg-white border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-[#bb3523] hover:text-white">
|
<Button className="w-full lg:w-fit px-4 h-8 border bg-white border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-[#bb3523] hover:text-white">{t("register")}</Button>
|
||||||
{t("register")}
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent size="sm" className="sm:max-w-[425px]">
|
<DialogContent size="sm" className="sm:max-w-[425px]">
|
||||||
<div className="flex flex-col w-full gap-1">
|
<div className="flex flex-col w-full gap-1">
|
||||||
<p className="text-lg font-semibold text-center">
|
<p className="text-lg font-semibold text-center">Kategori Registrasi</p>
|
||||||
Kategori Registrasi
|
<p className="text-base text-center">Silahkan pilih salah satu</p>
|
||||||
</p>
|
|
||||||
<p className="text-base text-center">
|
|
||||||
Silahkan pilih salah satu
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{role?.map((row: any) => (
|
{role?.map((row: any) => (
|
||||||
<div key={row.id}>
|
<div key={row.id}>
|
||||||
<input
|
<input type="radio" id={`category${row.id}`} name="category" className="" value={row.id} checked={category == `${row.id}`} onChange={(event) => setCategory(event.target.value)} />
|
||||||
type="radio"
|
|
||||||
id={`category${row.id}`}
|
|
||||||
name="category"
|
|
||||||
className=""
|
|
||||||
value={row.id}
|
|
||||||
checked={category == `${row.id}`}
|
|
||||||
onChange={(event) => setCategory(event.target.value)}
|
|
||||||
/>
|
|
||||||
<label className="ml-2" htmlFor={`category${row.id}`}>
|
<label className="ml-2" htmlFor={`category${row.id}`}>
|
||||||
{row.name}
|
{row.name}
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -924,11 +693,7 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b-2 border-black"></div>
|
<div className="border-b-2 border-black"></div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Link
|
<Link href={`/auth/registration?category=${category}`} className="bg-red-500 px-4 py-1 rounded-md border border-black text-white" type="submit">
|
||||||
href={`/auth/registration?category=${category}`}
|
|
||||||
className="bg-red-500 px-4 py-1 rounded-md border border-black text-white"
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Selanjutnya{" "}
|
Selanjutnya{" "}
|
||||||
</Link>
|
</Link>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|
@ -947,14 +712,7 @@ const Navbar = () => {
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
<NavigationMenuTrigger>
|
<NavigationMenuTrigger>
|
||||||
<a className="dark:text-white text-black flex flex-row justify-center items-center cursor-pointer">
|
<a className="dark:text-white text-black flex flex-row justify-center items-center cursor-pointer">
|
||||||
<svg
|
<svg className="mx-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
className="mx-2"
|
|
||||||
width="25"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 25 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M20 7.5H5C4.6023 7.5004 4.221 7.65856 3.93978 7.93978C3.65856 8.221 3.5004 8.6023 3.5 9V19.5C3.5004 19.8977 3.65856 20.279 3.93978 20.5602C4.221 20.8414 4.6023 20.9996 5 21H20C20.3977 20.9996 20.779 20.8414 21.0602 20.5602C21.3414 20.279 21.4996 19.8977 21.5 19.5V9C21.4996 8.6023 21.3414 8.221 21.0602 7.93978C20.779 7.65856 20.3977 7.5004 20 7.5ZM10.25 17.25V11.25L15.5 14.25L10.25 17.25ZM5 4.5H20V6H5V4.5ZM6.5 1.5H18.5V3H6.5V1.5Z"
|
d="M20 7.5H5C4.6023 7.5004 4.221 7.65856 3.93978 7.93978C3.65856 8.221 3.5004 8.6023 3.5 9V19.5C3.5004 19.8977 3.65856 20.279 3.93978 20.5602C4.221 20.8414 4.6023 20.9996 5 21H20C20.3977 20.9996 20.779 20.8414 21.0602 20.5602C21.3414 20.279 21.4996 19.8977 21.5 19.5V9C21.4996 8.6023 21.3414 8.221 21.0602 7.93978C20.779 7.65856 20.3977 7.5004 20 7.5ZM10.25 17.25V11.25L15.5 14.25L10.25 17.25ZM5 4.5H20V6H5V4.5ZM6.5 1.5H18.5V3H6.5V1.5Z"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
|
|
@ -964,56 +722,25 @@ const Navbar = () => {
|
||||||
</a>
|
</a>
|
||||||
</NavigationMenuTrigger>
|
</NavigationMenuTrigger>
|
||||||
<NavigationMenuContent className="p-0 rounded-md overflow-hidden w-full">
|
<NavigationMenuContent className="p-0 rounded-md overflow-hidden w-full">
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(generateLocalizedPath("/video/filter", String(locale)))} className="flex items-start gap-1.5 p-2 hover:bg-white">
|
||||||
onClick={() =>
|
|
||||||
router.push(
|
|
||||||
generateLocalizedPath("/video/filter", String(locale))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className="flex items-start gap-1.5 p-2 hover:bg-white"
|
|
||||||
>
|
|
||||||
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
||||||
<FiYoutube className="mr-2" />
|
<FiYoutube className="mr-2" />
|
||||||
{t("video")}
|
{t("video")}
|
||||||
</p>
|
</p>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(generateLocalizedPath("/audio/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||||
onClick={() =>
|
|
||||||
router.push(
|
|
||||||
generateLocalizedPath("/audio/filter", String(locale))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
|
||||||
>
|
|
||||||
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
||||||
<FiMusic className="mr-2" />
|
<FiMusic className="mr-2" />
|
||||||
{t("audio")}
|
{t("audio")}
|
||||||
</p>
|
</p>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(generateLocalizedPath("/image/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||||
onClick={() =>
|
|
||||||
router.push(
|
|
||||||
generateLocalizedPath("/image/filter", String(locale))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
|
||||||
>
|
|
||||||
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
||||||
<FiImage className="mr-2" />
|
<FiImage className="mr-2" />
|
||||||
{t("image")}
|
{t("image")}
|
||||||
</p>
|
</p>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
<NavigationMenuLink
|
<NavigationMenuLink onClick={() => router.push(generateLocalizedPath("/document/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||||
onClick={() =>
|
|
||||||
router.push(
|
|
||||||
generateLocalizedPath(
|
|
||||||
"/document/filter",
|
|
||||||
String(locale)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
|
||||||
>
|
|
||||||
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
<p className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2 cursor-pointer">
|
||||||
<FiFile className="mr-2" />
|
<FiFile className="mr-2" />
|
||||||
{t("text")}
|
{t("text")}
|
||||||
|
|
@ -1025,14 +752,7 @@ const Navbar = () => {
|
||||||
<Link href="/schedule" legacyBehavior passHref>
|
<Link href="/schedule" legacyBehavior passHref>
|
||||||
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
<span>
|
<span>
|
||||||
<svg
|
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
className="mr-2"
|
|
||||||
width="25"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 25 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M19.5 4H18.5V3C18.5 2.4 18.1 2 17.5 2C16.9 2 16.5 2.4 16.5 3V4H8.5V3C8.5 2.4 8.1 2 7.5 2C6.9 2 6.5 2.4 6.5 3V4H5.5C3.8 4 2.5 5.3 2.5 7V8H22.5V7C22.5 5.3 21.2 4 19.5 4ZM2.5 19C2.5 20.7 3.8 22 5.5 22H19.5C21.2 22 22.5 20.7 22.5 19V10H2.5V19ZM17.5 12C18.1 12 18.5 12.4 18.5 13C18.5 13.6 18.1 14 17.5 14C16.9 14 16.5 13.6 16.5 13C16.5 12.4 16.9 12 17.5 12ZM17.5 16C18.1 16 18.5 16.4 18.5 17C18.5 17.6 18.1 18 17.5 18C16.9 18 16.5 17.6 16.5 17C16.5 16.4 16.9 16 17.5 16ZM12.5 12C13.1 12 13.5 12.4 13.5 13C13.5 13.6 13.1 14 12.5 14C11.9 14 11.5 13.6 11.5 13C11.5 12.4 11.9 12 12.5 12ZM12.5 16C13.1 16 13.5 16.4 13.5 17C13.5 17.6 13.1 18 12.5 18C11.9 18 11.5 17.6 11.5 17C11.5 16.4 11.9 16 12.5 16ZM7.5 12C8.1 12 8.5 12.4 8.5 13C8.5 13.6 8.1 14 7.5 14C6.9 14 6.5 13.6 6.5 13C6.5 12.4 6.9 12 7.5 12ZM7.5 16C8.1 16 8.5 16.4 8.5 17C8.5 17.6 8.1 18 7.5 18C6.9 18 6.5 17.6 6.5 17C6.5 16.4 6.9 16 7.5 16Z"
|
d="M19.5 4H18.5V3C18.5 2.4 18.1 2 17.5 2C16.9 2 16.5 2.4 16.5 3V4H8.5V3C8.5 2.4 8.1 2 7.5 2C6.9 2 6.5 2.4 6.5 3V4H5.5C3.8 4 2.5 5.3 2.5 7V8H22.5V7C22.5 5.3 21.2 4 19.5 4ZM2.5 19C2.5 20.7 3.8 22 5.5 22H19.5C21.2 22 22.5 20.7 22.5 19V10H2.5V19ZM17.5 12C18.1 12 18.5 12.4 18.5 13C18.5 13.6 18.1 14 17.5 14C16.9 14 16.5 13.6 16.5 13C16.5 12.4 16.9 12 17.5 12ZM17.5 16C18.1 16 18.5 16.4 18.5 17C18.5 17.6 18.1 18 17.5 18C16.9 18 16.5 17.6 16.5 17C16.5 16.4 16.9 16 17.5 16ZM12.5 12C13.1 12 13.5 12.4 13.5 13C13.5 13.6 13.1 14 12.5 14C11.9 14 11.5 13.6 11.5 13C11.5 12.4 11.9 12 12.5 12ZM12.5 16C13.1 16 13.5 16.4 13.5 17C13.5 17.6 13.1 18 12.5 18C11.9 18 11.5 17.6 11.5 17C11.5 16.4 11.9 16 12.5 16ZM7.5 12C8.1 12 8.5 12.4 8.5 13C8.5 13.6 8.1 14 7.5 14C6.9 14 6.5 13.6 6.5 13C6.5 12.4 6.9 12 7.5 12ZM7.5 16C8.1 16 8.5 16.4 8.5 17C8.5 17.6 8.1 18 7.5 18C6.9 18 6.5 17.6 6.5 17C6.5 16.4 6.9 16 7.5 16Z"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
|
|
@ -1047,14 +767,7 @@ const Navbar = () => {
|
||||||
<Link href="/indeks" legacyBehavior passHref>
|
<Link href="/indeks" legacyBehavior passHref>
|
||||||
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
|
||||||
<span>
|
<span>
|
||||||
<svg
|
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
className="mr-2"
|
|
||||||
width="25"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 25 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
clip-rule="evenodd"
|
clip-rule="evenodd"
|
||||||
|
|
@ -1076,10 +789,7 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-1 mx-3 text-yellow-600 font-medium">
|
<div className="flex items-center space-x-1 mx-3 text-yellow-600 font-medium">
|
||||||
<a href="https://tvradio.polri.go.id/">
|
<a href="https://tvradio.polri.go.id/">
|
||||||
<img
|
<img src="/assets/polriTv.png" className="object-contain h-11 flex items-center" />
|
||||||
src="/assets/polriTv.png"
|
|
||||||
className="object-contain h-11 flex items-center"
|
|
||||||
/>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1118,22 +828,14 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className=" py-1 flex items-center mx-3">
|
<div className=" py-1 flex items-center mx-3">
|
||||||
<input
|
<input type="text" placeholder="Pencarian" className="border rounded-full w-full text-sm text-center text-gray-600" />
|
||||||
type="text"
|
|
||||||
placeholder="Pencarian"
|
|
||||||
className="border rounded-full w-full text-sm text-center text-gray-600"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center items-center mx-3 gap-5">
|
<div className="flex justify-center items-center mx-3 gap-5">
|
||||||
{fullName ? (
|
{fullName ? (
|
||||||
<>
|
<>
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger className="flex items-center gap-1">
|
<DropdownMenuTrigger className="flex items-center gap-1">
|
||||||
<img
|
<img className="h-12 w-12" src="/assets/avatar-profile.png" alt="avatar-profile" />
|
||||||
className="h-12 w-12"
|
|
||||||
src="/assets/avatar-profile.png"
|
|
||||||
alt="avatar-profile"
|
|
||||||
/>
|
|
||||||
<a className="gap-2">
|
<a className="gap-2">
|
||||||
<p className="text-xs font-semibold">{fullName}</p>
|
<p className="text-xs font-semibold">{fullName}</p>
|
||||||
<p className="text-xs">{`(${roleName})`}</p>
|
<p className="text-xs">{`(${roleName})`}</p>
|
||||||
|
|
@ -1141,33 +843,20 @@ const Navbar = () => {
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<Link
|
<Link href="/profile" className="flex items-center gap-1 hover:bg-slate-600 w-full rounded-lg">
|
||||||
href="/profile"
|
|
||||||
className="flex items-center gap-1 hover:bg-slate-600 w-full rounded-lg"
|
|
||||||
>
|
|
||||||
<Icon icon="iconamoon:profile-circle-fill" />
|
<Icon icon="iconamoon:profile-circle-fill" />
|
||||||
{t("profile")}
|
{t("profile")}
|
||||||
</Link>
|
</Link>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<Link
|
<Link href="/content-management/galery" className="flex items-center gap-1 hover:bg-slate-600 w-full rounded-lg">
|
||||||
href="/content-management/galery"
|
|
||||||
className="flex items-center gap-1 hover:bg-slate-600 w-full rounded-lg"
|
|
||||||
>
|
|
||||||
<Icon icon="stash:save-ribbon-light" />
|
<Icon icon="stash:save-ribbon-light" />
|
||||||
{t("contentManagement")}
|
{t("contentManagement")}
|
||||||
</Link>
|
</Link>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<Link
|
<Link href={"/"} className="flex items-center gap-1 hover:bg-slate-600 w-full rounded-lg">
|
||||||
href={"/"}
|
<button type="submit" className="w-full flex items-center gap-2" onClick={onLogout}>
|
||||||
className="flex items-center gap-1 hover:bg-slate-600 w-full rounded-lg"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
className="w-full flex items-center gap-2"
|
|
||||||
onClick={onLogout}
|
|
||||||
>
|
|
||||||
<Icon icon="iconamoon:exit-bold" />
|
<Icon icon="iconamoon:exit-bold" />
|
||||||
{t("logOut")}
|
{t("logOut")}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -1178,41 +867,22 @@ const Navbar = () => {
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Link
|
<Link href="/auth" className="px-4 py-[10px] bg-[#bb3523] text-white font-semibold rounded-md hover:bg-[#bb3523]">
|
||||||
href="/auth"
|
|
||||||
className="px-4 py-[10px] bg-[#bb3523] text-white font-semibold rounded-md hover:bg-[#bb3523]"
|
|
||||||
>
|
|
||||||
{t("logIn")}
|
{t("logIn")}
|
||||||
</Link>
|
</Link>
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button className="w-full lg:w-max px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 text-center">
|
<Button className="w-full lg:w-max px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 text-center">{t("register")}</Button>
|
||||||
{t("register")}
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent size="sm" className="sm:max-w-[425px]">
|
<DialogContent size="sm" className="sm:max-w-[425px]">
|
||||||
<div className="flex flex-col w-full gap-1">
|
<div className="flex flex-col w-full gap-1">
|
||||||
<p className="text-lg font-semibold text-center">
|
<p className="text-lg font-semibold text-center">Kategori Registrasi</p>
|
||||||
Kategori Registrasi
|
<p className="text-base text-center">Silahkan pilih salah satu</p>
|
||||||
</p>
|
|
||||||
<p className="text-base text-center">
|
|
||||||
Silahkan pilih salah satu
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{role?.map((row: any) => (
|
{role?.map((row: any) => (
|
||||||
<div key={row.id}>
|
<div key={row.id}>
|
||||||
<input
|
<input type="radio" id={`category${row.id}`} name="category" className="" value={row.id} checked={category == `${row.id}`} onChange={(event) => setCategory(event.target.value)} />
|
||||||
type="radio"
|
|
||||||
id={`category${row.id}`}
|
|
||||||
name="category"
|
|
||||||
className=""
|
|
||||||
value={row.id}
|
|
||||||
checked={category == `${row.id}`}
|
|
||||||
onChange={(event) =>
|
|
||||||
setCategory(event.target.value)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<label className="ml-2" htmlFor={`category${row.id}`}>
|
<label className="ml-2" htmlFor={`category${row.id}`}>
|
||||||
{row.name}
|
{row.name}
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -1221,11 +891,7 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b-2 border-black"></div>
|
<div className="border-b-2 border-black"></div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Link
|
<Link href={`/auth/registration?category=${category}`} className="bg-red-500 px-4 py-1 rounded-md border border-black text-white" type="submit">
|
||||||
href={`/auth/registration?category=${category}`}
|
|
||||||
className="bg-red-500 px-4 py-1 rounded-md border border-black text-white"
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Selanjutnya{" "}
|
Selanjutnya{" "}
|
||||||
</Link>
|
</Link>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,17 @@ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||||
import { useParams, usePathname, useRouter } from "next/navigation";
|
import { useParams, usePathname, useRouter } from "next/navigation";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import { formatDateToIndonesian } from "@/utils/globals";
|
import { formatDateToIndonesian, secondToTimes } from "@/utils/globals";
|
||||||
import { getListContent } from "@/service/landing/landing";
|
import { getListContent } from "@/service/landing/landing";
|
||||||
import { Link } from "@/i18n/routing";
|
import { Link } from "@/i18n/routing";
|
||||||
import { Reveal } from "./Reveal";
|
import { Reveal } from "./Reveal";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { Skeleton } from "../ui/skeleton";
|
||||||
|
|
||||||
const NewContent = (props: { group: string; type: string }) => {
|
const NewContent = (props: { group: string; type: string }) => {
|
||||||
const [newContent, setNewContent] = useState<any>();
|
const [newContent, setNewContent] = useState<any>();
|
||||||
const [selectedTab, setSelectedTab] = useState("image");
|
const [selectedTab, setSelectedTab] = useState("image");
|
||||||
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
|
@ -22,6 +24,14 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
const t = useTranslations("LandingPage");
|
const t = useTranslations("LandingPage");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
initFetch();
|
||||||
}, [selectedTab]);
|
}, [selectedTab]);
|
||||||
|
|
@ -91,55 +101,137 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
</TabsList>
|
</TabsList>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<div className="px-0 lg:px-10">
|
|
||||||
{selectedTab == "video" ? (
|
{isLoading ? (
|
||||||
newContent?.length > 0 ? (
|
<div className="flex flex-col space-y-3 max-w-sm mx-auto">
|
||||||
<Carousel className="w-full max-w-7xl mx-auto">
|
<Skeleton className="h-[125px] w-[250px] rounded-xl" />
|
||||||
<CarouselContent>
|
<div className="space-y-2">
|
||||||
{newContent?.map((video: any) => (
|
<Skeleton className="h-4 w-[250px]" />
|
||||||
<CarouselItem key={video?.id} className="md:basis-1/2 lg:basis-1/3">
|
<Skeleton className="h-4 w-[200px]" />
|
||||||
<Link href={`/video/detail/${video?.slug}`} className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
</div>
|
||||||
<img src={video?.thumbnailLink} className="w-full rounded-lg h-48 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300" />
|
</div>
|
||||||
<div className="absolute bottom-0 left-0 right-0 bg-gray-600 border-l-4 border-[#bb3523] rounded-lg backdrop-blur-sm text-white p-2">
|
) : (
|
||||||
<h1 className="text-sm lg:text-lg mb-2 font-semibold h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{video?.title}</h1>
|
<div className="px-0 lg:px-10">
|
||||||
<p className="flex flex-row items-center text-[10px] gap-2">
|
{selectedTab == "image" ? (
|
||||||
{formatDateToIndonesian(new Date(video?.createdAt))} {video?.timezone ? video?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {video.clickCount}{" "}
|
newContent?.length > 0 ? (
|
||||||
</p>
|
<Carousel className="w-full max-w-7xl mx-auto">
|
||||||
|
<CarouselContent>
|
||||||
|
{newContent?.map((image: any) => (
|
||||||
|
<CarouselItem key={image?.id} className="md:basis-1/2 lg:basis-1/3">
|
||||||
|
<Link href={`/image/detail/${image?.slug}`} className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
||||||
|
<img src={image?.thumbnailLink} className="w-full rounded-lg h-48 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300" />
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 bg-gray-600 border-l-4 border-[#bb3523] rounded-lg backdrop-blur-sm text-white p-2">
|
||||||
|
<h1 className="text-sm lg:text-lg mb-2 font-semibold h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{image?.title}</h1>
|
||||||
|
<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>
|
||||||
|
</Link>
|
||||||
|
</CarouselItem>
|
||||||
|
))}
|
||||||
|
</CarouselContent>
|
||||||
|
<CarouselPrevious />
|
||||||
|
<CarouselNext />
|
||||||
|
</Carousel>
|
||||||
|
) : (
|
||||||
|
<p className="flex items-center justify-center">
|
||||||
|
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : selectedTab == "audio" ? (
|
||||||
|
newContent?.length > 0 ? (
|
||||||
|
<Carousel className="w-full max-w-7xl mx-auto">
|
||||||
|
<CarouselContent>
|
||||||
|
{newContent?.map((audio: any) => (
|
||||||
|
<CarouselItem key={audio?.id} className="md:basis-1/2 lg:basis-1/3">
|
||||||
|
<div className="flex flex-row gap-6">
|
||||||
|
<Link href={`/audio/detail/${audio?.slug}`} className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer 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">
|
||||||
|
<svg width="32" height="34" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col flex-1">
|
||||||
|
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm text-center items-center">
|
||||||
|
{formatDateToIndonesian(new Date(audio?.createdAt))} {audio?.timezone ? audio?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" />
|
||||||
|
{audio?.clickCount}{" "}
|
||||||
|
</div>
|
||||||
|
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{audio?.title}</div>
|
||||||
|
<p className="text-sm"> {audio?.duration ? secondToTimes(Number(audio?.duration)) : "00:00:00"}</p>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</CarouselItem>
|
||||||
</CarouselItem>
|
))}
|
||||||
))}
|
</CarouselContent>
|
||||||
</CarouselContent>
|
<CarouselPrevious />
|
||||||
<CarouselPrevious />
|
<CarouselNext />
|
||||||
<CarouselNext />
|
</Carousel>
|
||||||
</Carousel>
|
) : (
|
||||||
) : (
|
<p className="flex items-center justify-center">
|
||||||
<p className="flex items-center justify-center">
|
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
||||||
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
</p>
|
||||||
</p>
|
)
|
||||||
)
|
) : selectedTab == "video" ? (
|
||||||
) : selectedTab == "audio" ? (
|
newContent?.length > 0 ? (
|
||||||
newContent?.length > 0 ? (
|
<Carousel className="w-full max-w-7xl mx-auto">
|
||||||
|
<CarouselContent>
|
||||||
|
{newContent?.map((video: any) => (
|
||||||
|
<CarouselItem key={video?.id} className="md:basis-1/2 lg:basis-1/3">
|
||||||
|
<Link href={`/video/detail/${video?.slug}`} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
|
||||||
|
<img src={video?.thumbnailLink} className="w-full h-40 lg:h-60 object-cover rounded-lg group-hover:scale-100 transition-transform duration-300" />
|
||||||
|
<div className="absolute bottom-0 rounded-lg left-0 right-0 border-l-4 border-[#bb3523] bg-gray-600 text-white p-2">
|
||||||
|
<h1 className="text-sm font-semibold h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{video?.title}</h1>
|
||||||
|
<p className="flex flex-row items-center text-sm gap-2">
|
||||||
|
{formatDateToIndonesian(new Date(video?.createdAt))} {video?.timezone ? video?.timezone : "WIB"}| <Icon icon="formkit:eye" width="15" height="15" /> {video?.clickCount}{" "}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</CarouselItem>
|
||||||
|
))}
|
||||||
|
</CarouselContent>
|
||||||
|
<CarouselPrevious />
|
||||||
|
<CarouselNext />
|
||||||
|
</Carousel>
|
||||||
|
) : (
|
||||||
|
<p className="flex items-center justify-center">
|
||||||
|
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
) : newContent.length > 0 ? (
|
||||||
<Carousel className="w-full max-w-7xl mx-auto">
|
<Carousel className="w-full max-w-7xl mx-auto">
|
||||||
<CarouselContent>
|
<CarouselContent>
|
||||||
{newContent?.map((audio: any) => (
|
{newContent?.map((text: any) => (
|
||||||
<CarouselItem key={audio?.id} className="md:basis-1/2 lg:basis-1/3">
|
<CarouselItem key={text?.id} className="md:basis-1/2 lg:basis-1/3">
|
||||||
<div className="flex flex-row gap-6">
|
<div className="md:basis-1/2 lg:basis-1/3">
|
||||||
<Link href={`/audio/detail/${audio?.slug}`} className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
|
<Link href={`/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 bg-red-500 text-white rounded-lg w-16 h-8 lg:h-16">
|
<div className="flex items-center justify-center rounded-lg w-16 h-2 lg:h-16">
|
||||||
<svg width="32" height="34" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
|
<svg width="28" height="34" viewBox="0 0 28 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
|
d="M5.6665 17.4167C5.6665 17.0851 5.7982 16.7672 6.03262 16.5328C6.26704 16.2984 6.58498 16.1667 6.9165 16.1667C7.24802 16.1667 7.56597 16.2984 7.80039 16.5328C8.03481 16.7672 8.1665 17.0851 8.1665 17.4167C8.1665 17.7482 8.03481 18.0661 7.80039 18.3005C7.56597 18.535 7.24802 18.6667 6.9165 18.6667C6.58498 18.6667 6.26704 18.535 6.03262 18.3005C5.7982 18.0661 5.6665 17.7482 5.6665 17.4167ZM6.9165 21.1667C6.58498 21.1667 6.26704 21.2984 6.03262 21.5328C5.7982 21.7672 5.6665 22.0851 5.6665 22.4167C5.6665 22.7482 5.7982 23.0661 6.03262 23.3005C6.26704 23.535 6.58498 23.6667 6.9165 23.6667C7.24802 23.6667 7.56597 23.535 7.80039 23.3005C8.03481 23.0661 8.1665 22.7482 8.1665 22.4167C8.1665 22.0851 8.03481 21.7672 7.80039 21.5328C7.56597 21.2984 7.24802 21.1667 6.9165 21.1667ZM5.6665 27.4167C5.6665 27.0851 5.7982 26.7672 6.03262 26.5328C6.26704 26.2984 6.58498 26.1667 6.9165 26.1667C7.24802 26.1667 7.56597 26.2984 7.80039 26.5328C8.03481 26.7672 8.1665 27.0851 8.1665 27.4167C8.1665 27.7482 8.03481 28.0661 7.80039 28.3005C7.56597 28.535 7.24802 28.6667 6.9165 28.6667C6.58498 28.6667 6.26704 28.535 6.03262 28.3005C5.7982 28.0661 5.6665 27.7482 5.6665 27.4167ZM11.9165 16.1667C11.585 16.1667 11.267 16.2984 11.0326 16.5328C10.7982 16.7672 10.6665 17.0851 10.6665 17.4167C10.6665 17.7482 10.7982 18.0661 11.0326 18.3005C11.267 18.535 11.585 18.6667 11.9165 18.6667H21.0832C21.4147 18.6667 21.7326 18.535 21.9671 18.3005C22.2015 18.0661 22.3332 17.7482 22.3332 17.4167C22.3332 17.0851 22.2015 16.7672 21.9671 16.5328C21.7326 16.2984 21.4147 16.1667 21.0832 16.1667H11.9165ZM10.6665 22.4167C10.6665 22.0851 10.7982 21.7672 11.0326 21.5328C11.267 21.2984 11.585 21.1667 11.9165 21.1667H21.0832C21.4147 21.1667 21.7326 21.2984 21.9671 21.5328C22.2015 21.7672 22.3332 22.0851 22.3332 22.4167C22.3332 22.7482 22.2015 23.0661 21.9671 23.3005C21.7326 23.535 21.4147 23.6667 21.0832 23.6667H11.9165C11.585 23.6667 11.267 23.535 11.0326 23.3005C10.7982 23.0661 10.6665 22.7482 10.6665 22.4167ZM11.9165 26.1667C11.585 26.1667 11.267 26.2984 11.0326 26.5328C10.7982 26.7672 10.6665 27.0851 10.6665 27.4167C10.6665 27.7482 10.7982 28.0661 11.0326 28.3005C11.267 28.535 11.585 28.6667 11.9165 28.6667H21.0832C21.4147 28.6667 21.7326 28.535 21.9671 28.3005C22.2015 28.0661 22.3332 27.7482 22.3332 27.4167C22.3332 27.0851 22.2015 26.7672 21.9671 26.5328C21.7326 26.2984 21.4147 26.1667 21.0832 26.1667H11.9165ZM26.3565 11.0233L16.6415 1.31C16.6157 1.28605 16.5885 1.26378 16.5598 1.24333C16.5392 1.22742 16.5192 1.21074 16.4998 1.19333C16.3852 1.08512 16.2632 0.984882 16.1348 0.893332C16.0922 0.865802 16.0476 0.841298 16.0015 0.819999L15.9215 0.779999L15.8382 0.731666C15.7482 0.679999 15.6565 0.626665 15.5615 0.586665C15.2296 0.454104 14.8783 0.376423 14.5215 0.356665C14.4885 0.354519 14.4557 0.350625 14.4232 0.344999C14.3779 0.338012 14.3323 0.334114 14.2865 0.333332H3.99984C3.11578 0.333332 2.26794 0.684521 1.64281 1.30964C1.01769 1.93476 0.666504 2.78261 0.666504 3.66667V30.3333C0.666504 31.2174 1.01769 32.0652 1.64281 32.6904C2.26794 33.3155 3.11578 33.6667 3.99984 33.6667H23.9998C24.8839 33.6667 25.7317 33.3155 26.3569 32.6904C26.982 32.0652 27.3332 31.2174 27.3332 30.3333V13.38C27.333 12.496 26.9817 11.6483 26.3565 11.0233ZM24.8332 30.3333C24.8332 30.5543 24.7454 30.7663 24.5891 30.9226C24.4328 31.0789 24.2208 31.1667 23.9998 31.1667H3.99984C3.77882 31.1667 3.56686 31.0789 3.41058 30.9226C3.2543 30.7663 3.1665 30.5543 3.1665 30.3333V3.66667C3.1665 3.44565 3.2543 3.23369 3.41058 3.07741C3.56686 2.92113 3.77882 2.83333 3.99984 2.83333H13.9998V10.3333C13.9998 11.2174 14.351 12.0652 14.9761 12.6904C15.6013 13.3155 16.4491 13.6667 17.3332 13.6667H24.8332V30.3333ZM16.4998 4.70166L22.9632 11.1667H17.3332C17.1122 11.1667 16.9002 11.0789 16.7439 10.9226C16.5876 10.7663 16.4998 10.5543 16.4998 10.3333V4.70166Z"
|
||||||
fill="white"
|
fill="black"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col flex-1">
|
<div className="flex w-full pr-10 flex-col flex-1">
|
||||||
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
|
<div className="text-gray-500 dark:text-gray-400 flex flex-row items-center text-xs gap-0 lg:gap-1 mt-1 lg:text-sm">
|
||||||
{formatDateToIndonesian(new Date(audio?.createdAt))} {audio?.timezone ? audio?.timezone : "WIB"} | <Icon icon="formkit:eye" width="15" height="15" /> {audio?.clickCount}{" "}
|
{formatDateToIndonesian(new Date(text?.createdAt))}
|
||||||
|
{text?.timezone ? text?.timezone : "WIB"}|
|
||||||
|
<Icon icon="formkit:eye" width="15" height="15" />
|
||||||
|
{text?.clickCount}
|
||||||
|
</div>
|
||||||
|
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible ">{text?.title}</div>
|
||||||
|
<div className="flex gap-2 items-center text-sm text-red-500 dark:text-red-500">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512">
|
||||||
|
<path fill="#f00" d="M224 30v256h-64l96 128l96-128h-64V30zM32 434v48h448v-48z" />
|
||||||
|
</svg>
|
||||||
|
Download {t("document")}
|
||||||
</div>
|
</div>
|
||||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{audio?.title}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -153,78 +245,9 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
<p className="flex items-center justify-center">
|
<p className="flex items-center justify-center">
|
||||||
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
||||||
</p>
|
</p>
|
||||||
)
|
)}
|
||||||
) : selectedTab == "image" ? (
|
</div>
|
||||||
newContent?.length > 0 ? (
|
)}
|
||||||
<Carousel className="w-full max-w-7xl mx-auto">
|
|
||||||
<CarouselContent>
|
|
||||||
{newContent?.map((image: any) => (
|
|
||||||
<CarouselItem key={image?.id} className="md:basis-1/2 lg:basis-1/3">
|
|
||||||
<Link href={`/image/detail/${image?.slug}`} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
|
|
||||||
<img src={image?.thumbnailLink} className="w-full h-40 lg:h-60 object-cover rounded-lg group-hover:scale-100 transition-transform duration-300" />
|
|
||||||
<div className="absolute bottom-0 rounded-lg left-0 right-0 border-l-4 border-[#bb3523] bg-gray-600 text-white p-2">
|
|
||||||
<h1 className="text-sm font-semibold h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{image?.title}</h1>
|
|
||||||
<p className="flex flex-row items-center text-sm gap-2">
|
|
||||||
{formatDateToIndonesian(new Date(image?.createdAt))} {image?.timezone ? image?.timezone : "WIB"}| <Icon icon="formkit:eye" width="15" height="15" /> {image?.clickCount}{" "}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
) : (
|
|
||||||
<p className="flex items-center justify-center">
|
|
||||||
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
) : newContent.length > 0 ? (
|
|
||||||
<Carousel className="w-full max-w-7xl mx-auto">
|
|
||||||
<CarouselContent>
|
|
||||||
{newContent?.map((text: any) => (
|
|
||||||
<CarouselItem key={text?.id} className="md:basis-1/2 lg:basis-1/3">
|
|
||||||
<div className="md:basis-1/2 lg:basis-1/3">
|
|
||||||
<Link href={`/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">
|
|
||||||
<svg width="28" height="34" viewBox="0 0 28 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path
|
|
||||||
d="M5.6665 17.4167C5.6665 17.0851 5.7982 16.7672 6.03262 16.5328C6.26704 16.2984 6.58498 16.1667 6.9165 16.1667C7.24802 16.1667 7.56597 16.2984 7.80039 16.5328C8.03481 16.7672 8.1665 17.0851 8.1665 17.4167C8.1665 17.7482 8.03481 18.0661 7.80039 18.3005C7.56597 18.535 7.24802 18.6667 6.9165 18.6667C6.58498 18.6667 6.26704 18.535 6.03262 18.3005C5.7982 18.0661 5.6665 17.7482 5.6665 17.4167ZM6.9165 21.1667C6.58498 21.1667 6.26704 21.2984 6.03262 21.5328C5.7982 21.7672 5.6665 22.0851 5.6665 22.4167C5.6665 22.7482 5.7982 23.0661 6.03262 23.3005C6.26704 23.535 6.58498 23.6667 6.9165 23.6667C7.24802 23.6667 7.56597 23.535 7.80039 23.3005C8.03481 23.0661 8.1665 22.7482 8.1665 22.4167C8.1665 22.0851 8.03481 21.7672 7.80039 21.5328C7.56597 21.2984 7.24802 21.1667 6.9165 21.1667ZM5.6665 27.4167C5.6665 27.0851 5.7982 26.7672 6.03262 26.5328C6.26704 26.2984 6.58498 26.1667 6.9165 26.1667C7.24802 26.1667 7.56597 26.2984 7.80039 26.5328C8.03481 26.7672 8.1665 27.0851 8.1665 27.4167C8.1665 27.7482 8.03481 28.0661 7.80039 28.3005C7.56597 28.535 7.24802 28.6667 6.9165 28.6667C6.58498 28.6667 6.26704 28.535 6.03262 28.3005C5.7982 28.0661 5.6665 27.7482 5.6665 27.4167ZM11.9165 16.1667C11.585 16.1667 11.267 16.2984 11.0326 16.5328C10.7982 16.7672 10.6665 17.0851 10.6665 17.4167C10.6665 17.7482 10.7982 18.0661 11.0326 18.3005C11.267 18.535 11.585 18.6667 11.9165 18.6667H21.0832C21.4147 18.6667 21.7326 18.535 21.9671 18.3005C22.2015 18.0661 22.3332 17.7482 22.3332 17.4167C22.3332 17.0851 22.2015 16.7672 21.9671 16.5328C21.7326 16.2984 21.4147 16.1667 21.0832 16.1667H11.9165ZM10.6665 22.4167C10.6665 22.0851 10.7982 21.7672 11.0326 21.5328C11.267 21.2984 11.585 21.1667 11.9165 21.1667H21.0832C21.4147 21.1667 21.7326 21.2984 21.9671 21.5328C22.2015 21.7672 22.3332 22.0851 22.3332 22.4167C22.3332 22.7482 22.2015 23.0661 21.9671 23.3005C21.7326 23.535 21.4147 23.6667 21.0832 23.6667H11.9165C11.585 23.6667 11.267 23.535 11.0326 23.3005C10.7982 23.0661 10.6665 22.7482 10.6665 22.4167ZM11.9165 26.1667C11.585 26.1667 11.267 26.2984 11.0326 26.5328C10.7982 26.7672 10.6665 27.0851 10.6665 27.4167C10.6665 27.7482 10.7982 28.0661 11.0326 28.3005C11.267 28.535 11.585 28.6667 11.9165 28.6667H21.0832C21.4147 28.6667 21.7326 28.535 21.9671 28.3005C22.2015 28.0661 22.3332 27.7482 22.3332 27.4167C22.3332 27.0851 22.2015 26.7672 21.9671 26.5328C21.7326 26.2984 21.4147 26.1667 21.0832 26.1667H11.9165ZM26.3565 11.0233L16.6415 1.31C16.6157 1.28605 16.5885 1.26378 16.5598 1.24333C16.5392 1.22742 16.5192 1.21074 16.4998 1.19333C16.3852 1.08512 16.2632 0.984882 16.1348 0.893332C16.0922 0.865802 16.0476 0.841298 16.0015 0.819999L15.9215 0.779999L15.8382 0.731666C15.7482 0.679999 15.6565 0.626665 15.5615 0.586665C15.2296 0.454104 14.8783 0.376423 14.5215 0.356665C14.4885 0.354519 14.4557 0.350625 14.4232 0.344999C14.3779 0.338012 14.3323 0.334114 14.2865 0.333332H3.99984C3.11578 0.333332 2.26794 0.684521 1.64281 1.30964C1.01769 1.93476 0.666504 2.78261 0.666504 3.66667V30.3333C0.666504 31.2174 1.01769 32.0652 1.64281 32.6904C2.26794 33.3155 3.11578 33.6667 3.99984 33.6667H23.9998C24.8839 33.6667 25.7317 33.3155 26.3569 32.6904C26.982 32.0652 27.3332 31.2174 27.3332 30.3333V13.38C27.333 12.496 26.9817 11.6483 26.3565 11.0233ZM24.8332 30.3333C24.8332 30.5543 24.7454 30.7663 24.5891 30.9226C24.4328 31.0789 24.2208 31.1667 23.9998 31.1667H3.99984C3.77882 31.1667 3.56686 31.0789 3.41058 30.9226C3.2543 30.7663 3.1665 30.5543 3.1665 30.3333V3.66667C3.1665 3.44565 3.2543 3.23369 3.41058 3.07741C3.56686 2.92113 3.77882 2.83333 3.99984 2.83333H13.9998V10.3333C13.9998 11.2174 14.351 12.0652 14.9761 12.6904C15.6013 13.3155 16.4491 13.6667 17.3332 13.6667H24.8332V30.3333ZM16.4998 4.70166L22.9632 11.1667H17.3332C17.1122 11.1667 16.9002 11.0789 16.7439 10.9226C16.5876 10.7663 16.4998 10.5543 16.4998 10.3333V4.70166Z"
|
|
||||||
fill="black"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex w-full pr-10 flex-col flex-1">
|
|
||||||
<div className="text-gray-500 dark:text-gray-400 flex flex-row items-center text-xs gap-0 lg:gap-1 mt-1 lg:text-sm">
|
|
||||||
{formatDateToIndonesian(new Date(text?.createdAt))}
|
|
||||||
{text?.timezone ? text?.timezone : "WIB"}|
|
|
||||||
<Icon icon="formkit:eye" width="15" height="15" />
|
|
||||||
{text?.clickCount}
|
|
||||||
</div>
|
|
||||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible ">{text?.title}</div>
|
|
||||||
<div className="flex gap-2 items-center text-sm text-red-500 dark:text-red-500">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512">
|
|
||||||
<path fill="#f00" d="M224 30v256h-64l96 128l96-128h-64V30zM32 434v48h448v-48z" />
|
|
||||||
</svg>
|
|
||||||
Download {t("document")}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
) : (
|
|
||||||
<p className="flex items-center justify-center">
|
|
||||||
<img src="/assets/empty-data.png" alt="empty" className="h-52 w-52 my-4" />
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center flex-row justify-center">
|
<div className="flex items-center flex-row justify-center">
|
||||||
<Link href={`/${selectedTab}/filter?sortBy=${props.type}`} className="border text-[#bb3523] rounded-lg text-sm lg:text-md px-4 py-1 border-[#bb3523]">
|
<Link href={`/${selectedTab}/filter?sortBy=${props.type}`} className="border text-[#bb3523] rounded-lg text-sm lg:text-md px-4 py-1 border-[#bb3523]">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
"use client";
|
||||||
|
import { Link } from "@/i18n/routing";
|
||||||
|
import { getHeroData, listCarousel } from "@/service/landing/landing";
|
||||||
|
import { formatDateToIndonesian, textEllipsis } from "@/utils/globals";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Icon } from "../ui/icon";
|
||||||
|
|
||||||
|
export default function NewsTicker() {
|
||||||
|
const [article, setArticle] = useState<any>([]);
|
||||||
|
const [currentNewsIndex, setCurrentNewsIndex] = useState(0);
|
||||||
|
const [animate, setAnimate] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getArticle() {
|
||||||
|
const response = await getHeroData();
|
||||||
|
setArticle(response?.data?.data?.content);
|
||||||
|
}
|
||||||
|
getArticle();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const triggerAnimation = (newIndex: number) => {
|
||||||
|
setAnimate(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCurrentNewsIndex(newIndex);
|
||||||
|
setAnimate(false);
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
const newIndex = (currentNewsIndex - 1 + article.length) % article.length;
|
||||||
|
triggerAnimation(newIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
const newIndex = (currentNewsIndex + 1) % article.length;
|
||||||
|
triggerAnimation(newIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
triggerAnimation((currentNewsIndex + 1) % article.length);
|
||||||
|
}, 7000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [article.length]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed bottom-0 z-50 flex flex-row h-[60px] gap-3 w-full justify-between dark:bg-stone-800 bg-gray-50">
|
||||||
|
<div className="relative px-4 py-2 font-semibold text-xs lg:text-sm flex items-center bg-[#bb3523] text-white w-[30%] lg:w-[10%]">
|
||||||
|
<span className="mr-2"></span> BREAKING NEWS
|
||||||
|
<div className="absolute right-0 top-0 h-full w-4 bg-[#bb3523] transform translate-x-full clip-path-triangle"></div>
|
||||||
|
</div>
|
||||||
|
<div className={`w-full px-5 py-1 flex flex-col gap-1 transition-transform duration-300 ${animate ? "opacity-0 translate-y-5" : "opacity-100 translate-y-0"}`}>
|
||||||
|
<Link href={`news/detail/${article[currentNewsIndex]?.id}`} className="hidden lg:block">
|
||||||
|
<p className="text-sm lg:text-base">{article[currentNewsIndex]?.title}</p>
|
||||||
|
</Link>
|
||||||
|
<Link href={`news/detail/${article[currentNewsIndex]?.id}`} className="lg:hidden">
|
||||||
|
<p className="text-sm lg:text-base">{textEllipsis(article[currentNewsIndex]?.title, 28)}</p>
|
||||||
|
</Link>
|
||||||
|
<p className="text-xs">{formatDateToIndonesian(article[currentNewsIndex]?.createdAt)}</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row text-white h-full gap-[1px]">
|
||||||
|
<a className="bg-[#bb3523] h-full flex items-center" onClick={() => handlePrev()}>
|
||||||
|
<Icon icon="ic:twotone-arrow-left" fontSize={30} />
|
||||||
|
</a>
|
||||||
|
<a className="bg-[#bb3523] h-full flex items-center" onClick={() => handleNext()}>
|
||||||
|
<Icon icon="ic:twotone-arrow-right" fontSize={30} />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -9,30 +9,63 @@ type Inputs = {
|
||||||
exampleRequired: string;
|
exampleRequired: string;
|
||||||
};
|
};
|
||||||
import { useForm, SubmitHandler } from "react-hook-form";
|
import { useForm, SubmitHandler } from "react-hook-form";
|
||||||
|
import { error, loading } from "@/config/swal";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import { useRouter } from "@/i18n/routing";
|
||||||
|
import { forgotPassword } from "@/service/landing/landing";
|
||||||
|
|
||||||
const ForgotPass = () => {
|
const ForgotPass = () => {
|
||||||
const {
|
const [username, setUsername] = useState<any>();
|
||||||
register,
|
const MySwal = withReactContent(Swal);
|
||||||
handleSubmit,
|
const router = useRouter();
|
||||||
watch,
|
|
||||||
formState: { errors },
|
const {
|
||||||
} = useForm<Inputs>();
|
register,
|
||||||
const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data);
|
handleSubmit,
|
||||||
console.log(watch("example"));
|
watch,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm<Inputs>();
|
||||||
|
const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data);
|
||||||
|
|
||||||
|
async function handleCheckUsername() {
|
||||||
|
loading();
|
||||||
|
const response = await forgotPassword(username);
|
||||||
|
|
||||||
|
if (response.error) {
|
||||||
|
error(response.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
successSubmit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function successSubmit() {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Email berhasil dikirim. Silahkan cek email Anda.",
|
||||||
|
icon: "success",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
}).then((result: any) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
router.push("/admin");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4 ">
|
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4 ">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="email">Email</Label>
|
<Label htmlFor="user-name">Username</Label>
|
||||||
<Input
|
<Input id="user-name" defaultValue="akun1234" className="h-[48px] text-sm text-default-900 " onChange={(e) => setUsername(e.target.value)} />
|
||||||
id="email"
|
|
||||||
defaultValue="dashcode@gmail.com"
|
|
||||||
{...register("example")}
|
|
||||||
className="h-[48px] text-sm text-default-900 "
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button type="submit" fullWidth>
|
<Button type="submit" fullWidth onClick={handleCheckUsername}>
|
||||||
Send recovery email
|
Check Username
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" fullWidth onClick={handleCheckUsername}>
|
||||||
|
Kirim Ulang?{" "}
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ import { cn, setCookiesEncrypt } from "@/lib/utils";
|
||||||
import { Loader2 } from "lucide-react";
|
import { Loader2 } from "lucide-react";
|
||||||
import { getProfile, login } from "@/service/auth";
|
import { getProfile, login } from "@/service/auth";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Link, useRouter } from "@/components/navigation";
|
import { useRouter } from "@/components/navigation";
|
||||||
import { warning } from "@/lib/swal";
|
import { warning } from "@/lib/swal";
|
||||||
|
import { Link } from "@/i18n/routing";
|
||||||
|
|
||||||
// Schema validasi menggunakan zod
|
// Schema validasi menggunakan zod
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
|
|
@ -200,7 +201,7 @@ const LoginForm = () => {
|
||||||
<Checkbox id="checkbox" defaultChecked />
|
<Checkbox id="checkbox" defaultChecked />
|
||||||
<Label htmlFor="checkbox">Keep Me Signed In</Label>
|
<Label htmlFor="checkbox">Keep Me Signed In</Label>
|
||||||
</div>
|
</div>
|
||||||
<Link href="/forgot-password" className="text-sm text-default-800 dark:text-default-400 leading-6 font-medium">
|
<Link href="/auth/forgot-password" className="text-sm text-default-800 dark:text-default-400 leading-6 font-medium">
|
||||||
Forgot Password?
|
Forgot Password?
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Swal from 'sweetalert2';
|
import Swal from "sweetalert2";
|
||||||
import withReactContent from 'sweetalert2-react-content';
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
|
||||||
type SweetAlertIcon = 'success' | 'error' | 'warning' | 'info' | 'question';
|
type SweetAlertIcon = "success" | "error" | "warning" | "info" | "question";
|
||||||
|
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
|
|
||||||
|
|
@ -25,15 +25,15 @@ export function error(msg: string): void {
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
title: '<p class="text-red-600 font-semibold">Gagal</p>',
|
title: '<p class="text-red-600 font-semibold">Gagal</p>',
|
||||||
html: `<p class="text-gray-700">${msg}</p>`,
|
html: `<p class="text-gray-700">${msg}</p>`,
|
||||||
icon: 'error',
|
icon: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function success(redirect: string): void {
|
export function success(redirect: string): void {
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
title: '<p class="text-green-600 font-bold">Sukses</p>',
|
title: '<p class="text-green-600 font-bold">Sukses</p>',
|
||||||
icon: 'success',
|
icon: "success",
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: '<span class="text-white">OK</span>',
|
confirmButtonText: '<span class="text-white">OK</span>',
|
||||||
allowOutsideClick: false,
|
allowOutsideClick: false,
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
|
|
@ -45,18 +45,18 @@ export function success(redirect: string): void {
|
||||||
|
|
||||||
export function successCallback(title?: string): Promise<boolean> {
|
export function successCallback(title?: string): Promise<boolean> {
|
||||||
return MySwal.fire({
|
return MySwal.fire({
|
||||||
title: `<p class="text-green-600 font-bold">${title || 'Sukses'}</p>`,
|
title: `<p class="text-green-600 font-bold">${title || "Sukses"}</p>`,
|
||||||
icon: 'success',
|
icon: "success",
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: '<span class="text-white">OK</span>',
|
confirmButtonText: '<span class="text-white">OK</span>',
|
||||||
}).then((result) => result.isConfirmed);
|
}).then((result) => result.isConfirmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function successCallbackContent(title?: string): Promise<boolean> {
|
export function successCallbackContent(title?: string): Promise<boolean> {
|
||||||
return MySwal.fire({
|
return MySwal.fire({
|
||||||
title: `<p class="text-green-600 font-bold">${title || 'Konten Telah Berhasil Disimpan'}</p>`,
|
title: `<p class="text-green-600 font-bold">${title || "Konten Telah Berhasil Disimpan"}</p>`,
|
||||||
icon: 'success',
|
icon: "success",
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: '<span class="text-white">OK</span>',
|
confirmButtonText: '<span class="text-white">OK</span>',
|
||||||
}).then((result) => result.isConfirmed);
|
}).then((result) => result.isConfirmed);
|
||||||
}
|
}
|
||||||
|
|
@ -70,8 +70,8 @@ export function welcome(name: string): Promise<boolean> {
|
||||||
timerInterval = setInterval(() => {}, 100);
|
timerInterval = setInterval(() => {}, 100);
|
||||||
return MySwal.fire({
|
return MySwal.fire({
|
||||||
title: `<p class="text-green-600 font-bold">Selamat Datang ${name} \nDi Mediahub</p>`,
|
title: `<p class="text-green-600 font-bold">Selamat Datang ${name} \nDi Mediahub</p>`,
|
||||||
icon: 'success',
|
icon: "success",
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: '<span class="text-white">OK</span>',
|
confirmButtonText: '<span class="text-white">OK</span>',
|
||||||
timer: 2000,
|
timer: 2000,
|
||||||
timerProgressBar: false,
|
timerProgressBar: false,
|
||||||
|
|
@ -86,8 +86,8 @@ export function welcomeGuest(name: string): Promise<boolean> {
|
||||||
timerInterval = setInterval(() => {}, 100);
|
timerInterval = setInterval(() => {}, 100);
|
||||||
return MySwal.fire({
|
return MySwal.fire({
|
||||||
title: `<p class="text-green-600 font-bold">Selamat Datang ${name} \nDi Mediahub</p>`,
|
title: `<p class="text-green-600 font-bold">Selamat Datang ${name} \nDi Mediahub</p>`,
|
||||||
icon: 'success',
|
icon: "success",
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: '<span class="text-white">OK</span>',
|
confirmButtonText: '<span class="text-white">OK</span>',
|
||||||
timer: 2000,
|
timer: 2000,
|
||||||
timerProgressBar: false,
|
timerProgressBar: false,
|
||||||
|
|
@ -101,12 +101,12 @@ export function registerConfirm(): void {
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
title: '<p class="text-green-600 font-bold">Selamat Anda Telah Terdaftar</p>',
|
title: '<p class="text-green-600 font-bold">Selamat Anda Telah Terdaftar</p>',
|
||||||
html: '<p class="text-gray-700">Mohon Menunggu Email Konfirmasi Untuk Bisa Melakukan Login</p>',
|
html: '<p class="text-gray-700">Mohon Menunggu Email Konfirmasi Untuk Bisa Melakukan Login</p>',
|
||||||
icon: 'success',
|
icon: "success",
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: '<span class="text-white">OK</span>',
|
confirmButtonText: '<span class="text-white">OK</span>',
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
window.location.href = '/auth/login';
|
window.location.href = "/auth";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -114,8 +114,8 @@ export function registerConfirm(): void {
|
||||||
export function warning(text: string, redirect?: string): Promise<boolean> {
|
export function warning(text: string, redirect?: string): Promise<boolean> {
|
||||||
return MySwal.fire({
|
return MySwal.fire({
|
||||||
title: `<p class="text-yellow-600 font-bold">${text}</p>`,
|
title: `<p class="text-yellow-600 font-bold">${text}</p>`,
|
||||||
icon: 'warning',
|
icon: "warning",
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: '<span class="text-white">OK</span>',
|
confirmButtonText: '<span class="text-white">OK</span>',
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (redirect && result.isConfirmed) {
|
if (redirect && result.isConfirmed) {
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@
|
||||||
"@types/react-google-recaptcha": "^2.1.9",
|
"@types/react-google-recaptcha": "^2.1.9",
|
||||||
"@types/react-html-parser": "^2.0.6",
|
"@types/react-html-parser": "^2.0.6",
|
||||||
"@types/react-syntax-highlighter": "^15.5.13",
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
|
"@types/sanitize-html": "^2.13.0",
|
||||||
"@vercel/analytics": "^1.3.1",
|
"@vercel/analytics": "^1.3.1",
|
||||||
"@wavesurfer/react": "^1.0.8",
|
"@wavesurfer/react": "^1.0.8",
|
||||||
"apexcharts": "^3.49.2",
|
"apexcharts": "^3.49.2",
|
||||||
|
|
@ -88,6 +89,7 @@
|
||||||
"input-otp": "^1.2.4",
|
"input-otp": "^1.2.4",
|
||||||
"jodit-react": "^4.1.2",
|
"jodit-react": "^4.1.2",
|
||||||
"jotai": "^2.9.3",
|
"jotai": "^2.9.3",
|
||||||
|
"jquery": "^3.7.1",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"layout-grid": "^2.2.0",
|
"layout-grid": "^2.2.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
|
|
@ -129,6 +131,7 @@
|
||||||
"react-voice-recorder": "^2.1.2",
|
"react-voice-recorder": "^2.1.2",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
"rtl-detect": "^1.1.2",
|
"rtl-detect": "^1.1.2",
|
||||||
|
"sanitize-html": "^2.14.0",
|
||||||
"sharp": "^0.33.4",
|
"sharp": "^0.33.4",
|
||||||
"sonner": "^1.5.0",
|
"sonner": "^1.5.0",
|
||||||
"sweetalert2": "^11.10.5",
|
"sweetalert2": "^11.10.5",
|
||||||
|
|
@ -139,7 +142,7 @@
|
||||||
"tus-js-client": "^4.2.3",
|
"tus-js-client": "^4.2.3",
|
||||||
"use-places-autocomplete": "^4.0.1",
|
"use-places-autocomplete": "^4.0.1",
|
||||||
"vaul": "^0.9.1",
|
"vaul": "^0.9.1",
|
||||||
"wavesurfer.js": "^7.8.15",
|
"wavesurfer.js": "^7.8.16",
|
||||||
"yup": "^1.6.1",
|
"yup": "^1.6.1",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
|
|
@ -3847,6 +3850,32 @@
|
||||||
"integrity": "sha512-qpstuHivwg/HoXxRrBo5/r/OVx5M2SkqJpVu2haasdLctt+jMGHWjqdbI0LL7Rk2wRmN/UHdHK4JZg9RUMcvKA==",
|
"integrity": "sha512-qpstuHivwg/HoXxRrBo5/r/OVx5M2SkqJpVu2haasdLctt+jMGHWjqdbI0LL7Rk2wRmN/UHdHK4JZg9RUMcvKA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/sanitize-html": {
|
||||||
|
"version": "2.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.13.0.tgz",
|
||||||
|
"integrity": "sha512-X31WxbvW9TjIhZZNyNBZ/p5ax4ti7qsNDBDEnH4zAgmEh35YnFD1UiS6z9Cd34kKm0LslFW0KPmTQzu/oGtsqQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"htmlparser2": "^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/sanitize-html/node_modules/htmlparser2": {
|
||||||
|
"version": "8.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||||
|
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fb55"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.3",
|
||||||
|
"domutils": "^3.0.1",
|
||||||
|
"entities": "^4.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/scheduler": {
|
"node_modules/@types/scheduler": {
|
||||||
"version": "0.16.8",
|
"version": "0.16.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||||
|
|
@ -9356,7 +9385,6 @@
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
|
|
@ -9669,9 +9697,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jquery": {
|
"node_modules/jquery": {
|
||||||
"version": "2.2.4",
|
"version": "3.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
|
||||||
"integrity": "sha512-lBHj60ezci2u1v2FqnZIraShGgEXq35qCzMv4lITyHGppTnA13rwR0MgwyNJh9TnDs3aXUvd1xjAotfraMHX/Q=="
|
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
|
||||||
},
|
},
|
||||||
"node_modules/js-base64": {
|
"node_modules/js-base64": {
|
||||||
"version": "3.7.7",
|
"version": "3.7.7",
|
||||||
|
|
@ -9880,6 +9908,11 @@
|
||||||
"jquery": "^1.7, ^2.0"
|
"jquery": "^1.7, ^2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/layout-grid/node_modules/jquery": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-lBHj60ezci2u1v2FqnZIraShGgEXq35qCzMv4lITyHGppTnA13rwR0MgwyNJh9TnDs3aXUvd1xjAotfraMHX/Q=="
|
||||||
|
},
|
||||||
"node_modules/leaflet": {
|
"node_modules/leaflet": {
|
||||||
"version": "1.9.4",
|
"version": "1.9.4",
|
||||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||||
|
|
@ -12576,6 +12609,11 @@
|
||||||
"protocols": "^2.0.0"
|
"protocols": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/parse-srcset": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
|
||||||
|
},
|
||||||
"node_modules/parse-url": {
|
"node_modules/parse-url": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz",
|
||||||
|
|
@ -12779,7 +12817,6 @@
|
||||||
"version": "8.4.49",
|
"version": "8.4.49",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
|
||||||
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
|
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|
@ -14974,6 +15011,37 @@
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/sanitize-html": {
|
||||||
|
"version": "2.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.14.0.tgz",
|
||||||
|
"integrity": "sha512-CafX+IUPxZshXqqRaG9ZClSlfPVjSxI0td7n07hk8QO2oO+9JDnlcL8iM8TWeOXOIBFgIOx6zioTzM53AOMn3g==",
|
||||||
|
"dependencies": {
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"htmlparser2": "^8.0.0",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"parse-srcset": "^1.0.2",
|
||||||
|
"postcss": "^8.3.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/sanitize-html/node_modules/htmlparser2": {
|
||||||
|
"version": "8.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||||
|
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fb55"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.3",
|
||||||
|
"domutils": "^3.0.1",
|
||||||
|
"entities": "^4.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/scheduler": {
|
"node_modules/scheduler": {
|
||||||
"version": "0.23.2",
|
"version": "0.23.2",
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||||
|
|
@ -17159,9 +17227,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/wavesurfer.js": {
|
"node_modules/wavesurfer.js": {
|
||||||
"version": "7.8.15",
|
"version": "7.8.16",
|
||||||
"resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-7.8.15.tgz",
|
"resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-7.8.16.tgz",
|
||||||
"integrity": "sha512-fWNnQt5BEGzuoJ7HRxfvpT1rOEI1AmCGPZ/+7QDkDVN/m2vIBeLVQ+5vENRMz1YwvZ/u1No0UV492/o8G++KXQ=="
|
"integrity": "sha512-lhQF42A4Wn7ug5bixaqGK53qWF2minWdXlzxPtLV+QoVH3WgvVSdsP2HBaHRbkfT2Lh67kJG6CquFdukmf95gg=="
|
||||||
},
|
},
|
||||||
"node_modules/web-namespaces": {
|
"node_modules/web-namespaces": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
"@types/react-google-recaptcha": "^2.1.9",
|
"@types/react-google-recaptcha": "^2.1.9",
|
||||||
"@types/react-html-parser": "^2.0.6",
|
"@types/react-html-parser": "^2.0.6",
|
||||||
"@types/react-syntax-highlighter": "^15.5.13",
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
|
"@types/sanitize-html": "^2.13.0",
|
||||||
"@vercel/analytics": "^1.3.1",
|
"@vercel/analytics": "^1.3.1",
|
||||||
"@wavesurfer/react": "^1.0.8",
|
"@wavesurfer/react": "^1.0.8",
|
||||||
"apexcharts": "^3.49.2",
|
"apexcharts": "^3.49.2",
|
||||||
|
|
@ -89,6 +90,7 @@
|
||||||
"input-otp": "^1.2.4",
|
"input-otp": "^1.2.4",
|
||||||
"jodit-react": "^4.1.2",
|
"jodit-react": "^4.1.2",
|
||||||
"jotai": "^2.9.3",
|
"jotai": "^2.9.3",
|
||||||
|
"jquery": "^3.7.1",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"layout-grid": "^2.2.0",
|
"layout-grid": "^2.2.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
|
|
@ -130,6 +132,7 @@
|
||||||
"react-voice-recorder": "^2.1.2",
|
"react-voice-recorder": "^2.1.2",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
"rtl-detect": "^1.1.2",
|
"rtl-detect": "^1.1.2",
|
||||||
|
"sanitize-html": "^2.14.0",
|
||||||
"sharp": "^0.33.4",
|
"sharp": "^0.33.4",
|
||||||
"sonner": "^1.5.0",
|
"sonner": "^1.5.0",
|
||||||
"sweetalert2": "^11.10.5",
|
"sweetalert2": "^11.10.5",
|
||||||
|
|
@ -140,7 +143,7 @@
|
||||||
"tus-js-client": "^4.2.3",
|
"tus-js-client": "^4.2.3",
|
||||||
"use-places-autocomplete": "^4.0.1",
|
"use-places-autocomplete": "^4.0.1",
|
||||||
"vaul": "^0.9.1",
|
"vaul": "^0.9.1",
|
||||||
"wavesurfer.js": "^7.8.15",
|
"wavesurfer.js": "^7.8.16",
|
||||||
"yup": "^1.6.1",
|
"yup": "^1.6.1",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -176,12 +176,15 @@ importers:
|
||||||
'@types/react-syntax-highlighter':
|
'@types/react-syntax-highlighter':
|
||||||
specifier: ^15.5.13
|
specifier: ^15.5.13
|
||||||
version: 15.5.13
|
version: 15.5.13
|
||||||
|
'@types/sanitize-html':
|
||||||
|
specifier: ^2.13.0
|
||||||
|
version: 2.13.0
|
||||||
'@vercel/analytics':
|
'@vercel/analytics':
|
||||||
specifier: ^1.3.1
|
specifier: ^1.3.1
|
||||||
version: 1.4.1(next@14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 1.4.1(next@14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
'@wavesurfer/react':
|
'@wavesurfer/react':
|
||||||
specifier: ^1.0.8
|
specifier: ^1.0.8
|
||||||
version: 1.0.8(react@18.3.1)(wavesurfer.js@7.8.15)
|
version: 1.0.8(react@18.3.1)(wavesurfer.js@7.8.16)
|
||||||
apexcharts:
|
apexcharts:
|
||||||
specifier: ^3.49.2
|
specifier: ^3.49.2
|
||||||
version: 3.54.1
|
version: 3.54.1
|
||||||
|
|
@ -248,6 +251,9 @@ importers:
|
||||||
jotai:
|
jotai:
|
||||||
specifier: ^2.9.3
|
specifier: ^2.9.3
|
||||||
version: 2.11.0(@types/react@18.3.18)(react@18.3.1)
|
version: 2.11.0(@types/react@18.3.18)(react@18.3.1)
|
||||||
|
jquery:
|
||||||
|
specifier: ^3.7.1
|
||||||
|
version: 3.7.1
|
||||||
js-cookie:
|
js-cookie:
|
||||||
specifier: ^3.0.5
|
specifier: ^3.0.5
|
||||||
version: 3.0.5
|
version: 3.0.5
|
||||||
|
|
@ -371,6 +377,9 @@ importers:
|
||||||
rtl-detect:
|
rtl-detect:
|
||||||
specifier: ^1.1.2
|
specifier: ^1.1.2
|
||||||
version: 1.1.2
|
version: 1.1.2
|
||||||
|
sanitize-html:
|
||||||
|
specifier: ^2.14.0
|
||||||
|
version: 2.14.0
|
||||||
sharp:
|
sharp:
|
||||||
specifier: ^0.33.4
|
specifier: ^0.33.4
|
||||||
version: 0.33.5
|
version: 0.33.5
|
||||||
|
|
@ -402,8 +411,8 @@ importers:
|
||||||
specifier: ^0.9.1
|
specifier: ^0.9.1
|
||||||
version: 0.9.9(@types/react-dom@16.9.25(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 0.9.9(@types/react-dom@16.9.25(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
wavesurfer.js:
|
wavesurfer.js:
|
||||||
specifier: ^7.8.15
|
specifier: ^7.8.16
|
||||||
version: 7.8.15
|
version: 7.8.16
|
||||||
yup:
|
yup:
|
||||||
specifier: ^1.6.1
|
specifier: ^1.6.1
|
||||||
version: 1.6.1
|
version: 1.6.1
|
||||||
|
|
@ -2246,6 +2255,9 @@ packages:
|
||||||
'@types/rtl-detect@1.0.3':
|
'@types/rtl-detect@1.0.3':
|
||||||
resolution: {integrity: sha512-qpstuHivwg/HoXxRrBo5/r/OVx5M2SkqJpVu2haasdLctt+jMGHWjqdbI0LL7Rk2wRmN/UHdHK4JZg9RUMcvKA==}
|
resolution: {integrity: sha512-qpstuHivwg/HoXxRrBo5/r/OVx5M2SkqJpVu2haasdLctt+jMGHWjqdbI0LL7Rk2wRmN/UHdHK4JZg9RUMcvKA==}
|
||||||
|
|
||||||
|
'@types/sanitize-html@2.13.0':
|
||||||
|
resolution: {integrity: sha512-X31WxbvW9TjIhZZNyNBZ/p5ax4ti7qsNDBDEnH4zAgmEh35YnFD1UiS6z9Cd34kKm0LslFW0KPmTQzu/oGtsqQ==}
|
||||||
|
|
||||||
'@types/scheduler@0.16.8':
|
'@types/scheduler@0.16.8':
|
||||||
resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==}
|
resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==}
|
||||||
|
|
||||||
|
|
@ -3568,6 +3580,9 @@ packages:
|
||||||
html-void-elements@3.0.0:
|
html-void-elements@3.0.0:
|
||||||
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
||||||
|
|
||||||
|
htmlparser2@8.0.2:
|
||||||
|
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||||
|
|
||||||
htmlparser2@9.1.0:
|
htmlparser2@9.1.0:
|
||||||
resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
|
resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
|
||||||
|
|
||||||
|
|
@ -3864,6 +3879,9 @@ packages:
|
||||||
jquery@2.2.4:
|
jquery@2.2.4:
|
||||||
resolution: {integrity: sha512-lBHj60ezci2u1v2FqnZIraShGgEXq35qCzMv4lITyHGppTnA13rwR0MgwyNJh9TnDs3aXUvd1xjAotfraMHX/Q==}
|
resolution: {integrity: sha512-lBHj60ezci2u1v2FqnZIraShGgEXq35qCzMv4lITyHGppTnA13rwR0MgwyNJh9TnDs3aXUvd1xjAotfraMHX/Q==}
|
||||||
|
|
||||||
|
jquery@3.7.1:
|
||||||
|
resolution: {integrity: sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==}
|
||||||
|
|
||||||
js-base64@3.7.7:
|
js-base64@3.7.7:
|
||||||
resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==}
|
resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==}
|
||||||
|
|
||||||
|
|
@ -4520,6 +4538,9 @@ packages:
|
||||||
parse-path@7.0.0:
|
parse-path@7.0.0:
|
||||||
resolution: {integrity: sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==}
|
resolution: {integrity: sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==}
|
||||||
|
|
||||||
|
parse-srcset@1.0.2:
|
||||||
|
resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==}
|
||||||
|
|
||||||
parse-url@8.1.0:
|
parse-url@8.1.0:
|
||||||
resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==}
|
resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==}
|
||||||
|
|
||||||
|
|
@ -5073,6 +5094,9 @@ packages:
|
||||||
safer-buffer@2.1.2:
|
safer-buffer@2.1.2:
|
||||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||||
|
|
||||||
|
sanitize-html@2.14.0:
|
||||||
|
resolution: {integrity: sha512-CafX+IUPxZshXqqRaG9ZClSlfPVjSxI0td7n07hk8QO2oO+9JDnlcL8iM8TWeOXOIBFgIOx6zioTzM53AOMn3g==}
|
||||||
|
|
||||||
scheduler@0.23.2:
|
scheduler@0.23.2:
|
||||||
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
|
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
|
||||||
|
|
||||||
|
|
@ -5666,8 +5690,8 @@ packages:
|
||||||
wavesurfer.js@4.6.0:
|
wavesurfer.js@4.6.0:
|
||||||
resolution: {integrity: sha512-+nn6VD86pTtRu9leVNXoIGOCMJyaTNsKNy9v+SfUsYo+SxLCQvEzrZZ/eKMImqspsk+BX1V1xlY4FRkHswu3fA==}
|
resolution: {integrity: sha512-+nn6VD86pTtRu9leVNXoIGOCMJyaTNsKNy9v+SfUsYo+SxLCQvEzrZZ/eKMImqspsk+BX1V1xlY4FRkHswu3fA==}
|
||||||
|
|
||||||
wavesurfer.js@7.8.15:
|
wavesurfer.js@7.8.16:
|
||||||
resolution: {integrity: sha512-fWNnQt5BEGzuoJ7HRxfvpT1rOEI1AmCGPZ/+7QDkDVN/m2vIBeLVQ+5vENRMz1YwvZ/u1No0UV492/o8G++KXQ==}
|
resolution: {integrity: sha512-lhQF42A4Wn7ug5bixaqGK53qWF2minWdXlzxPtLV+QoVH3WgvVSdsP2HBaHRbkfT2Lh67kJG6CquFdukmf95gg==}
|
||||||
|
|
||||||
web-namespaces@2.0.1:
|
web-namespaces@2.0.1:
|
||||||
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
||||||
|
|
@ -8003,6 +8027,10 @@ snapshots:
|
||||||
|
|
||||||
'@types/rtl-detect@1.0.3': {}
|
'@types/rtl-detect@1.0.3': {}
|
||||||
|
|
||||||
|
'@types/sanitize-html@2.13.0':
|
||||||
|
dependencies:
|
||||||
|
htmlparser2: 8.0.2
|
||||||
|
|
||||||
'@types/scheduler@0.16.8': {}
|
'@types/scheduler@0.16.8': {}
|
||||||
|
|
||||||
'@types/sizzle@2.3.9': {}
|
'@types/sizzle@2.3.9': {}
|
||||||
|
|
@ -8064,10 +8092,10 @@ snapshots:
|
||||||
next: 14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
next: 14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
'@wavesurfer/react@1.0.8(react@18.3.1)(wavesurfer.js@7.8.15)':
|
'@wavesurfer/react@1.0.8(react@18.3.1)(wavesurfer.js@7.8.16)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
wavesurfer.js: 7.8.15
|
wavesurfer.js: 7.8.16
|
||||||
|
|
||||||
'@wojtekmaj/date-utils@1.5.1': {}
|
'@wojtekmaj/date-utils@1.5.1': {}
|
||||||
|
|
||||||
|
|
@ -9657,6 +9685,13 @@ snapshots:
|
||||||
|
|
||||||
html-void-elements@3.0.0: {}
|
html-void-elements@3.0.0: {}
|
||||||
|
|
||||||
|
htmlparser2@8.0.2:
|
||||||
|
dependencies:
|
||||||
|
domelementtype: 2.3.0
|
||||||
|
domhandler: 5.0.3
|
||||||
|
domutils: 3.2.1
|
||||||
|
entities: 4.5.0
|
||||||
|
|
||||||
htmlparser2@9.1.0:
|
htmlparser2@9.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype: 2.3.0
|
domelementtype: 2.3.0
|
||||||
|
|
@ -9933,6 +9968,8 @@ snapshots:
|
||||||
|
|
||||||
jquery@2.2.4: {}
|
jquery@2.2.4: {}
|
||||||
|
|
||||||
|
jquery@3.7.1: {}
|
||||||
|
|
||||||
js-base64@3.7.7: {}
|
js-base64@3.7.7: {}
|
||||||
|
|
||||||
js-cookie@3.0.5: {}
|
js-cookie@3.0.5: {}
|
||||||
|
|
@ -10900,6 +10937,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
protocols: 2.0.1
|
protocols: 2.0.1
|
||||||
|
|
||||||
|
parse-srcset@1.0.2: {}
|
||||||
|
|
||||||
parse-url@8.1.0:
|
parse-url@8.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
parse-path: 7.0.0
|
parse-path: 7.0.0
|
||||||
|
|
@ -11516,6 +11555,15 @@ snapshots:
|
||||||
|
|
||||||
safer-buffer@2.1.2: {}
|
safer-buffer@2.1.2: {}
|
||||||
|
|
||||||
|
sanitize-html@2.14.0:
|
||||||
|
dependencies:
|
||||||
|
deepmerge: 4.3.1
|
||||||
|
escape-string-regexp: 4.0.0
|
||||||
|
htmlparser2: 8.0.2
|
||||||
|
is-plain-object: 5.0.0
|
||||||
|
parse-srcset: 1.0.2
|
||||||
|
postcss: 8.4.49
|
||||||
|
|
||||||
scheduler@0.23.2:
|
scheduler@0.23.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
|
|
@ -12227,7 +12275,7 @@ snapshots:
|
||||||
|
|
||||||
wavesurfer.js@4.6.0: {}
|
wavesurfer.js@4.6.0: {}
|
||||||
|
|
||||||
wavesurfer.js@7.8.15: {}
|
wavesurfer.js@7.8.16: {}
|
||||||
|
|
||||||
web-namespaces@2.0.1: {}
|
web-namespaces@2.0.1: {}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
|
|
@ -75,15 +75,42 @@ export async function setupPassword(data: any) {
|
||||||
|
|
||||||
export async function saveUser(data: any) {
|
export async function saveUser(data: any) {
|
||||||
const url = "users/save";
|
const url = "users/save";
|
||||||
return httpPostInterceptor(url, data);
|
const headers = {
|
||||||
|
"content-type": "application/json",
|
||||||
|
};
|
||||||
|
return httpPost(url, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveInstitutes(data: any) {
|
export async function saveInstitutes(data: any) {
|
||||||
const url = "public/users/save-institutes";
|
const url = "public/users/save-institutes";
|
||||||
return httpPostInterceptor(url, data);
|
const headers = {
|
||||||
|
"content-type": "application/json",
|
||||||
|
};
|
||||||
|
return httpPost(url, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postRegistration(data: any) {
|
export async function postRegistration(data: any) {
|
||||||
const url = "public/users/save";
|
const url = "public/users/save";
|
||||||
return httpPostInterceptor(url, data);
|
const headers = {
|
||||||
|
"content-type": "application/json",
|
||||||
|
};
|
||||||
|
return httpPost(url, headers, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function requestOTP(data: any) {
|
||||||
|
const url = "public/users/otp-request";
|
||||||
|
const headers = {
|
||||||
|
"content-Type": "application/json",
|
||||||
|
};
|
||||||
|
return httpPost(url, headers, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function verifyOTP(email: any, otp: any) {
|
||||||
|
const url = `public/users/verify-otp?email=${email}&otp=${otp}`;
|
||||||
|
const headers = {
|
||||||
|
"content-Type": "application/json",
|
||||||
|
};
|
||||||
|
return httpPost(url, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDataByNIK(reqid: any, nik: any) {
|
export async function getDataByNIK(reqid: any, nik: any) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import * as $ from "jquery";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface JQuery {
|
||||||
|
modal(action?: string): JQuery;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,31 @@
|
||||||
import { httpPost } from "../http-config/http-base-service";
|
import { httpGet, httpPost } from "../http-config/http-base-service";
|
||||||
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor } from "../http-config/http-interceptor-service";
|
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor } from "../http-config/http-interceptor-service";
|
||||||
|
|
||||||
|
export async function getCsrfToken() {
|
||||||
|
const pathUrl = "csrf";
|
||||||
|
const headers = {
|
||||||
|
"content-type": "application/json",
|
||||||
|
};
|
||||||
|
return httpGet(pathUrl, headers);
|
||||||
|
// const url = 'https://netidhub.com/api/csrf';
|
||||||
|
// try {
|
||||||
|
// const response = await fetch(url, {
|
||||||
|
// method: 'GET',
|
||||||
|
// credentials: 'include'
|
||||||
|
// });
|
||||||
|
|
||||||
|
// if (!response.ok) {
|
||||||
|
// throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const data = await response.json();
|
||||||
|
// console.log("csrf : ", data);
|
||||||
|
// return data;
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Fetch error: ', error);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
export async function getHeroData() {
|
export async function getHeroData() {
|
||||||
return await httpGetInterceptor(`media/public/list?enablePage=1&sort=desc&sortBy=createdAt&size=5&page=0&typeId=1&title=&categoryId=&fileFormats=&tags=&group=&startDate=&endDate=&month=&year=`);
|
return await httpGetInterceptor(`media/public/list?enablePage=1&sort=desc&sortBy=createdAt&size=5&page=0&typeId=1&title=&categoryId=&fileFormats=&tags=&group=&startDate=&endDate=&month=&year=`);
|
||||||
}
|
}
|
||||||
|
|
@ -114,21 +139,46 @@ export async function saveWishlist(data: { mediaUploadId: string }) {
|
||||||
return httpPostInterceptor(url, data);
|
return httpPostInterceptor(url, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPublicSuggestionList(id: any) {
|
export async function getPublicSuggestionList(slug: any) {
|
||||||
const url = `media/public/suggestion?mediaId=${id}`;
|
const url = `media/public/suggestion?mediaId=${slug}`;
|
||||||
return httpGetInterceptor(url);
|
const headers = {
|
||||||
}
|
"content-Type": "application/json",
|
||||||
export async function verifyOTP(email: any, otp: any) {
|
};
|
||||||
const url = `public/users/verify-otp?email=${email}&otp=${otp}`;
|
return httpGet(url, headers);
|
||||||
return httpPostInterceptor(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function requestOTP(data: any) {
|
|
||||||
const url = "public/users/otp-request";
|
|
||||||
return httpPost(url, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUserNotifications(page = 0, typeId: any) {
|
export async function getUserNotifications(page = 0, typeId: any) {
|
||||||
const url = `notification/public/list?enablePage=1&page=${page}&typeId=${typeId}`;
|
const url = `notification/public/list?enablePage=1&page=${page}&typeId=${typeId}`;
|
||||||
return httpGetInterceptor(url);
|
return httpGetInterceptor(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function forgotPassword(username: any) {
|
||||||
|
const url = `forgot-password?username=${username}`;
|
||||||
|
const header = {
|
||||||
|
"content-Type": "application/json",
|
||||||
|
};
|
||||||
|
return httpPost(url, header);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveUserReports(data: any) {
|
||||||
|
const url = "public/users/reports";
|
||||||
|
const header = {
|
||||||
|
"content-Type": "application/json",
|
||||||
|
};
|
||||||
|
return httpPost(url, header);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listCarousel() {
|
||||||
|
const url = "/media/public/banner";
|
||||||
|
return httpGetInterceptor(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createPublicSuggestion(data: any) {
|
||||||
|
const url = "media/public/suggestion";
|
||||||
|
return httpPostInterceptor(url, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deletePublicSuggestion(slug: any) {
|
||||||
|
const url = `media/public/suggestion?id=${slug}`;
|
||||||
|
return httpDeleteInterceptor( url );
|
||||||
}
|
}
|
||||||
|
|
@ -3,16 +3,10 @@ import {
|
||||||
httpPostInterceptor,
|
httpPostInterceptor,
|
||||||
} from "../http-config/http-interceptor-service";
|
} from "../http-config/http-interceptor-service";
|
||||||
import { httpGet } from "../http-config/http-base-service";
|
import { httpGet } from "../http-config/http-base-service";
|
||||||
|
import { any } from "zod";
|
||||||
|
|
||||||
export async function paginationSchedule(
|
export async function paginationSchedule(size: number, page: number, type: any, title: string = "") {
|
||||||
size: number,
|
return await httpGetInterceptor(`schedule/pagination?enablePage=1&scheduleTypeId=${type}&page=${page}&size=${size}&title=${title}`);
|
||||||
page: number,
|
|
||||||
type: any,
|
|
||||||
title: string = ""
|
|
||||||
) {
|
|
||||||
return await httpGetInterceptor(
|
|
||||||
`schedule/pagination?enablePage=1&scheduleTypeId=${type}&page=${page}&size=${size}&title=${title}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postSchedule(data: any) {
|
export async function postSchedule(data: any) {
|
||||||
|
|
@ -45,6 +39,11 @@ export async function listSchedule(group = null) {
|
||||||
return httpGet(url, null);
|
return httpGet(url, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function searchSchedules(search = null) {
|
||||||
|
const url = `public/schedule/list?search=${search}`;
|
||||||
|
return httpGet(url, null);
|
||||||
|
}
|
||||||
|
|
||||||
export async function listScheduleToday() {
|
export async function listScheduleToday() {
|
||||||
const url = "schedule/today";
|
const url = "schedule/today";
|
||||||
return httpGetInterceptor(url);
|
return httpGetInterceptor(url);
|
||||||
|
|
|
||||||
|
|
@ -106,3 +106,42 @@ export function getTimestamp(d: Date) {
|
||||||
d.getDate()
|
d.getDate()
|
||||||
)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function secondToTimes(sec: number) {
|
||||||
|
if (sec) {
|
||||||
|
const date = new Date(0);
|
||||||
|
date.setSeconds(sec); // specify value for SECONDS here
|
||||||
|
return date?.toISOString().slice(11, 19);
|
||||||
|
}
|
||||||
|
return "00:00:00";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkMaliciousText(str: any) {
|
||||||
|
try {
|
||||||
|
const urlPattern = new RegExp(
|
||||||
|
"(https?:\\/\\/(?:www\\.|(?!www))[^\\s\\.]+\\.[^\\s]{2,}|www\\.[^\\s]+\\.[^\\s]{2,}|https?:\\/\\/[^\\s]+|\\b(?:https?|ftp):\\/\\/[^\\s/$.?#].[^\\s]*)",
|
||||||
|
"gi"
|
||||||
|
);
|
||||||
|
const isContainUrl = urlPattern.test(str);
|
||||||
|
if (isContainUrl) {
|
||||||
|
return "Message mengandung URL yang tidak diizinkan";
|
||||||
|
}
|
||||||
|
|
||||||
|
const emailPattern = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i;
|
||||||
|
const isContainEmail = emailPattern.test(str);
|
||||||
|
if (isContainEmail) {
|
||||||
|
return "Message mengandung Email yang tidak diizinkan";
|
||||||
|
}
|
||||||
|
|
||||||
|
const phonePattern = /\b(?!\+?62|62|082[0-9])[2-9][0-9]{7,11}\b/g;
|
||||||
|
const isContainPhone = phonePattern.test(str);
|
||||||
|
if (isContainPhone) {
|
||||||
|
return "Message mengandung Nomor HP yang tidak diizinkan";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue