merge
This commit is contained in:
commit
c4ba5e44f0
|
|
@ -23,7 +23,7 @@ RUN pnpm install --frozen-lockfile
|
|||
COPY . .
|
||||
|
||||
# Build aplikasi
|
||||
RUN pnpm run build
|
||||
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm next build
|
||||
|
||||
# Expose port untuk server
|
||||
EXPOSE 3000
|
||||
|
|
|
|||
|
|
@ -8,13 +8,20 @@ import { Link, useRouter } from "@/i18n/routing";
|
|||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { BarWave } from "react-cssfx-loading";
|
||||
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 { close, error, loading } from "@/config/swal";
|
||||
import { close, error, loading, warning } from "@/config/swal";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import parse from "html-react-parser";
|
||||
|
||||
|
||||
const DetailAudio = () => {
|
||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||
const [selectedTab, setSelectedTab] = useState("video");
|
||||
const t = useTranslations("LandingPage");
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const params = useParams();
|
||||
|
|
@ -29,6 +36,11 @@ const DetailAudio = () => {
|
|||
const [main, setMain] = useState<any>();
|
||||
const [resolutionSelected, setResolutionSelected] = useState("720");
|
||||
const [imageSizeSelected, setImageSizeSelected] = useState("l");
|
||||
const [message, setMessage] = useState("");
|
||||
const userRoleId = getCookiesDecrypt("urie");
|
||||
const [listSuggestion, setListSuggestion] = useState<any>();
|
||||
const [visibleInput, setVisibleInput] = useState<string | null>(null);
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
|
||||
|
|
@ -215,7 +227,120 @@ const DetailAudio = () => {
|
|||
{ label: "S", value: "1066 x 599 px" },
|
||||
{ label: "XS", value: "800 x 450 px" },
|
||||
];
|
||||
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);
|
||||
}
|
||||
};
|
||||
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("none");
|
||||
setVisibleInput(visibleInput === e ? null : e);
|
||||
};
|
||||
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 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 (
|
||||
<>
|
||||
<div className="min-h-screen px-4 md:px-24 py-4">
|
||||
|
|
@ -316,10 +441,188 @@ const DetailAudio = () => {
|
|||
|
||||
<div className="w-full mb-8">
|
||||
{/* Comment */}
|
||||
<div className="flex flex-col my-16 gap-5 p-10 bg-gray-300">
|
||||
{/* <div className="flex flex-col my-16 gap-5 p-10 bg-gray-300">
|
||||
<p className="flex items-start text-lg">Berikan Komentar</p>
|
||||
<Textarea placeholder="Type your comments here." className="flex items-start justify-center" />
|
||||
<button className="flex items-start bg-[#bb3523] rounded-lg w-fit px-4 py-1">Kirim</button>
|
||||
</div> */}
|
||||
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7]">
|
||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||
<p className="flex items-start text-lg">{t("comment")}</p>
|
||||
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
||||
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
|
||||
{t("send")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="border-b-2 border-slate-300 mt-4 w-auto"></div>
|
||||
|
||||
<div>
|
||||
{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-12 lg:h-16 w-12 lg:w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||
<div className="border border-slate-300 w-full p-2 lg:p-4 bg-white gap-1">
|
||||
<p className="text-slate-500 text-sm lg: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-[13px] lg: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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("reply")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("delete")}</small>
|
||||
</a>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{visibleInput === `comment-id-${data.id}` && (
|
||||
<div id={`comment-id-${data.id}`} className="px-4 pl-[72px] lg:px-14 lg:pl-32 mt-2 ">
|
||||
<Textarea id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder={t("enterReply")} />
|
||||
<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-2 text-xs lg:text-base lg:px-4 py-1 mt-2 cursor-pointer">{t("send")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("cancel")}</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:pr-14 pl-16 lg:pl-32">
|
||||
<img src={child1.suggestionFrom?.profilePictureUrl} onError={addDefaultProfile} alt="" className="h-10 lg:h-16 w-10 lg:w-16 mr-2" />
|
||||
<div className="border border-slate-300 w-full p-2 lg:p-4 bg-white gap-1">
|
||||
<p className="text-slate-500 text-sm lg: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-[13px] lg: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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("reply")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("delete")}</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{visibleInput === `comment-id-${child1.id}` && (
|
||||
<div id={`comment-id-${child1.id}`} className="px-4 lg:px-14 pl-28 lg:pl-[200px]">
|
||||
<Textarea name="" className="mt-2 " id={`input-comment-${child1.id}`} placeholder={t("enterReply")} />
|
||||
<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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("send")}</small>
|
||||
</a>
|
||||
<a onClick={() => showInput(`comment-id-${child1.id}`)}>
|
||||
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("cancel")}</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:pr-14 pl-28 lg:pl-48">
|
||||
<img src={child2.suggestionFrom?.profilePictureUrl} className="h-9 lg:h-16 w-9 lg:w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||
<div className="border border-slate-300 w-full p-2 lg:p-4 bg-white gap-1">
|
||||
<p className="text-slate-500 text-sm lg: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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("reply")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("delete")}</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{visibleInput === `comment-id-${child2.id}` && (
|
||||
<div id={`comment-id-${child2.id}`} className="px-4 lg:px-14 pl-40 lg:pl-[265px]">
|
||||
<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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("send")}</small>
|
||||
</a>
|
||||
<a onClick={() => showInput(`comment-id-${child2.id}`)}>
|
||||
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("cancel")}</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
: ""}
|
||||
</div>
|
||||
))
|
||||
: ""}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Konten Serupa */}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,20 @@ import { Icon } from "@iconify/react/dist/iconify.js";
|
|||
import NewContent from "@/components/landing-page/new-content";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
import { checkWishlistStatus, deleteWishlist, getDetail, saveWishlist } from "@/service/landing/landing";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import { checkWishlistStatus, createPublicSuggestion, deletePublicSuggestion, deleteWishlist, getDetail, getPublicSuggestionList, saveWishlist } from "@/service/landing/landing";
|
||||
import { close, error, loading, successCallback, warning } from "@/config/swal";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { Link, useRouter } from "@/i18n/routing";
|
||||
import { checkMaliciousText, formatDateToIndonesian, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import { useTranslations } from "next-intl";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||
import parse from "html-react-parser";
|
||||
|
||||
const DetailDocument = () => {
|
||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||
|
|
@ -29,6 +39,20 @@ const DetailDocument = () => {
|
|||
const [main, setMain] = useState<any>();
|
||||
const [resolutionSelected, setResolutionSelected] = useState("720");
|
||||
const [imageSizeSelected, setImageSizeSelected] = useState("l");
|
||||
const t = useTranslations("LandingPage");
|
||||
const [message, setMessage] = useState("");
|
||||
const userRoleId = getCookiesDecrypt("urie");
|
||||
const [listSuggestion, setListSuggestion] = useState<any>();
|
||||
const [visibleInput, setVisibleInput] = useState<string | null>(null);
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [width, setWidth] = useState<any>();
|
||||
let typeString = "document";
|
||||
const [content, setContent] = useState<any>([]);
|
||||
const [emailShareInput, setEmailShareInput] = useState<any>();
|
||||
const [emailShareList, setEmailShareList] = useState<any>();
|
||||
const [emailMessageInput, setEmailMessageInput] = useState();
|
||||
const searchParams = useSearchParams();
|
||||
const id = searchParams?.get("id");
|
||||
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
|
||||
|
|
@ -215,8 +239,282 @@ const DetailDocument = () => {
|
|||
|
||||
xhr.send();
|
||||
};
|
||||
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);
|
||||
}
|
||||
};
|
||||
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("none");
|
||||
setVisibleInput(visibleInput === e ? null : e);
|
||||
};
|
||||
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 postDataChild = (id: any) => {
|
||||
const checkMessage = checkMaliciousText(message);
|
||||
if (checkMessage == "") {
|
||||
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||
router.push("/auth");
|
||||
} else {
|
||||
sendSuggestionChild(id);
|
||||
}
|
||||
} else {
|
||||
warning(checkMessage);
|
||||
}
|
||||
};
|
||||
const handleShare = (type: any, url: any) => {
|
||||
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||
router.push("/auth/login");
|
||||
} else {
|
||||
sendActivityLog(2);
|
||||
sendActivityLog(4);
|
||||
if (type == "wa" && width <= 768) {
|
||||
window.open(`whatsapp://send?${url}`, "_blank");
|
||||
} else if (type == "wa" && width > 768) {
|
||||
window.open(`https://web.whatsapp.com/send?${url}`, "_blank", "noreferrer");
|
||||
} else {
|
||||
window.open(url);
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleEmailList = (e: any) => {
|
||||
const arrayEmail: any = [];
|
||||
for (let i = 0; i < emailShareList?.length; i += 1) {
|
||||
arrayEmail.push(emailShareList[i]);
|
||||
}
|
||||
if (e.which == 13) {
|
||||
if (e.target.value) {
|
||||
arrayEmail.push(e.target.value);
|
||||
setEmailShareList(arrayEmail);
|
||||
setEmailShareInput("");
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
async function shareToEmail() {
|
||||
if (Number(userRoleId) < 1 || userRoleId == undefined) {
|
||||
router.push("/auth/login");
|
||||
} else {
|
||||
const data = {
|
||||
mediaUploadId: id?.split("-")?.[0],
|
||||
email: emailShareList || [emailShareInput],
|
||||
message: emailMessageInput,
|
||||
url: window.location.href,
|
||||
};
|
||||
loading();
|
||||
const res = await sendMediaUploadToEmail(data);
|
||||
if (res?.error) {
|
||||
error(res.message);
|
||||
return false;
|
||||
}
|
||||
close();
|
||||
successCallback("Konten Telah Dikirim");
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
// <>
|
||||
// <div className="px-4 md:px-24 py-4">
|
||||
// <div className="rounded-md overflow-hidden md:flex">
|
||||
// {/* Bagian Kiri */}
|
||||
// <div className="md:w-3/4">
|
||||
// <div className="relative">
|
||||
// <img src={detailDataDocument?.files[selectedDocument]?.url} alt="Main" className="rounded-lg w-auto h-fit" />
|
||||
// <div className="absolute top-4 left-4"></div>
|
||||
// </div>
|
||||
// {/* Footer Informasi */}
|
||||
// <div className="text-sm text-gray-500 flex justify-between items-center border-t mt-4">
|
||||
// <p className="flex flex-row items-center mt-3">
|
||||
// oleh <span className="font-semibold text-black">{detailDataDocument?.uploadedBy?.userLevel?.name}</span> | Diupdate pada {detailDataDocument?.updatedAt} WIB |
|
||||
// <Icon icon="formkit:eye" width="15" height="15" />
|
||||
//
|
||||
// {detailDataDocument?.clickCount}
|
||||
// </p>
|
||||
// <p className="mt-3">Kreator: {detailDataDocument?.creatorName}</p>
|
||||
// </div>
|
||||
|
||||
// {/* Keterangan */}
|
||||
// <div className="md:w-3/4">
|
||||
// <h1 className="flex flex-row font-bold text-2xl my-8">{detailDataDocument?.title}</h1>
|
||||
// <div dangerouslySetInnerHTML={{ __html: detailDataDocument?.htmlDescription }} />
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// {/* Bagian Kanan */}
|
||||
// <div className="md:w-1/4 p-4 bg-[#f7f7f7] h-fit rounded-lg mx-4">
|
||||
// {isSaved ? (
|
||||
// <a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||
// <Icon icon="material-symbols:bookmark" width={40} />
|
||||
// <p className="text-base lg:text-lg">Hapus</p>
|
||||
// </a>
|
||||
// ) : (
|
||||
// <a onClick={() => doBookmark()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||
// <Icon icon="material-symbols:bookmark-outline" width={40} />
|
||||
// <p className="text-base lg:text-lg">Simpan</p>
|
||||
// </a>
|
||||
// )}
|
||||
|
||||
// {/* garis */}
|
||||
// <div className="border-t border-black my-4"></div>
|
||||
|
||||
// <Link href={`/all/filter?title=polda&category=${detailDataDocument?.category.id}`} className="bg-red-600 text-white text-xs font-bold px-3 py-3 my-3 flex justify-center items-center rounded">
|
||||
// {detailDataDocument?.category?.name}
|
||||
// </Link>
|
||||
|
||||
// <div className="flex justify-center flex-wrap gap-2 mb-4">
|
||||
// {detailDataDocument?.tags?.split(",").map((tag: string) => (
|
||||
// <a onClick={() => router.push(`/all/filter?tag=${tag}`)} key={tag} className="bg-gray-200 text-gray-700 text-xs px-3 py-1 rounded-full cursor-pointer hover:bg-gray-500">
|
||||
// {tag}
|
||||
// </a>
|
||||
// ))}
|
||||
// </div>
|
||||
|
||||
// <div className="border-t border-black my-4"></div>
|
||||
|
||||
// {/* Opsi Ukuran Foto */}
|
||||
// <h4 className="flex text-lg justify-center items-center font-semibold my-3">Opsi Ukuran Foto</h4>
|
||||
// <div className="border-t border-black my-4"></div>
|
||||
// <div className="space-y-2">
|
||||
// {sizes.map((size: any) => (
|
||||
// <div className="flex flex-row justify-between">
|
||||
// <div key={size.label} className="items-center flex flex-row gap-2 cursor-pointer">
|
||||
// <input type="radio" name="size" value={size.label} checked={selectedSize === size.label} onChange={() => setSelectedSize(size.label)} className="text-red-600 focus:ring-red-600" />
|
||||
// <div className="text-sm">{size.label}</div>
|
||||
// </div>
|
||||
// <div className="">
|
||||
// <div className="text-sm">{size.value}</div>
|
||||
// </div>
|
||||
// </div>
|
||||
// ))}
|
||||
// </div>
|
||||
|
||||
// {/* Download Semua */}
|
||||
// <div className="mt-4">
|
||||
// <label className="flex items-center space-x-2 text-sm">
|
||||
// <input type="checkbox" className="text-red-600 focus:ring-red-600" onChange={() => setIsDownloadAll(!isDownloadAll)} />
|
||||
// <span>Download Semua File?</span>
|
||||
// </label>
|
||||
// </div>
|
||||
|
||||
// {/* Tombol Download */}
|
||||
// <button onClick={handleDownload} className="mt-4 bg-red-600 text-white w-full py-2 flex justify-center items-center gap-1 rounded-md text-sm hover:bg-red-700">
|
||||
// <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
// <path fill="white" d="m12 16l-5-5l1.4-1.45l2.6 2.6V4h2v8.15l2.6-2.6L17 11zm-6 4q-.825 0-1.412-.587T4 18v-3h2v3h12v-3h2v3q0 .825-.587 1.413T18 20z" />
|
||||
// </svg>
|
||||
// Download
|
||||
// </button>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <div className="w-full mb-8">
|
||||
// {/* Comment */}
|
||||
// <div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
||||
// <div className="gap-5 flex flex-col px-4 lg:px-16">
|
||||
// <p className="flex items-start text-lg">Berikan Komentar</p>
|
||||
// <Textarea placeholder="Type your comments here." className="flex w-full" />
|
||||
// <button className="flex items-start bg-[#bb3523] rounded-lg text-white w-fit px-4 py-1">Kirim</button>
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// {/* Konten Serupa */}
|
||||
// <div className="">
|
||||
// <NewContent group="polda" type={"similar"} />
|
||||
// </div>
|
||||
// </div>
|
||||
// </>
|
||||
<>
|
||||
<div className="px-4 md:px-24 py-4">
|
||||
<div className="rounded-md overflow-hidden md:flex">
|
||||
|
|
@ -227,19 +525,42 @@ const DetailDocument = () => {
|
|||
<div className="absolute top-4 left-4"></div>
|
||||
</div>
|
||||
{/* Footer Informasi */}
|
||||
<div className="text-sm text-gray-500 flex justify-between items-center border-t mt-4">
|
||||
<p className="flex flex-row items-center mt-3">
|
||||
<div className="text-gray-500 flex flex-col lg:flex-row justify-between items-center border-t mt-4">
|
||||
{/* <p className="flex flex-row items-center mt-3">
|
||||
oleh <span className="font-semibold text-black">{detailDataDocument?.uploadedBy?.userLevel?.name}</span> | Diupdate pada {detailDataDocument?.updatedAt} WIB |
|
||||
<Icon icon="formkit:eye" width="15" height="15" />
|
||||
|
||||
{detailDataDocument?.clickCount}
|
||||
</p>
|
||||
<p className="mt-3">Kreator: {detailDataDocument?.creatorName}</p>
|
||||
<p className="mt-3">Kreator: {detailDataDocument?.creatorName}</p> */}
|
||||
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
||||
<p className="text-xs lg:text-sm">
|
||||
{t("by")} <span className="font-semibold text-black">{detailDataDocument?.uploadedBy?.userLevel?.name}</span>
|
||||
</p>
|
||||
{/* <p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")} {detailDataDocument?.updatedAt} WIB |
|
||||
</p> */}
|
||||
<p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")}
|
||||
{formatDateToIndonesian(new Date(detailDataDocument?.updatedAt))} {"WIB"}
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm flex justify-center items-center">
|
||||
|
|
||||
<Icon icon="formkit:eye" width="15" height="15" />
|
||||
{detailDataDocument?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<p className="flex text-end text-xs lg:text-sm font-semibold">
|
||||
{t("creator")}
|
||||
{detailDataDocument?.creatorName}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Keterangan */}
|
||||
<div className="md:w-3/4">
|
||||
<h1 className="flex flex-row font-bold text-2xl my-8">{detailDataDocument?.title}</h1>
|
||||
<div className="">
|
||||
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8 text-justify space-y-4">{detailDataDocument?.title}</h1>
|
||||
<div dangerouslySetInnerHTML={{ __html: detailDataDocument?.htmlDescription }} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -249,12 +570,12 @@ const DetailDocument = () => {
|
|||
{isSaved ? (
|
||||
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||
<Icon icon="material-symbols:bookmark" width={40} />
|
||||
<p className="text-base lg:text-lg">Hapus</p>
|
||||
<p className="text-base lg:text-lg">{t("delete")}</p>
|
||||
</a>
|
||||
) : (
|
||||
<a onClick={() => doBookmark()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||
<Icon icon="material-symbols:bookmark-outline" width={40} />
|
||||
<p className="text-base lg:text-lg">Simpan</p>
|
||||
<p className="text-base lg:text-lg">{t("save")}</p>
|
||||
</a>
|
||||
)}
|
||||
|
||||
|
|
@ -276,7 +597,7 @@ const DetailDocument = () => {
|
|||
<div className="border-t border-black my-4"></div>
|
||||
|
||||
{/* Opsi Ukuran Foto */}
|
||||
<h4 className="flex text-lg justify-center items-center font-semibold my-3">Opsi Ukuran Foto</h4>
|
||||
<h4 className="flex text-lg justify-center items-center font-semibold my-3">{t("docSize")}</h4>
|
||||
<div className="border-t border-black my-4"></div>
|
||||
<div className="space-y-2">
|
||||
{sizes.map((size: any) => (
|
||||
|
|
@ -296,7 +617,7 @@ const DetailDocument = () => {
|
|||
<div className="mt-4">
|
||||
<label className="flex items-center space-x-2 text-sm">
|
||||
<input type="checkbox" className="text-red-600 focus:ring-red-600" onChange={() => setIsDownloadAll(!isDownloadAll)} />
|
||||
<span>Download Semua File?</span>
|
||||
<span>{t("downloadAll")}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
|
@ -305,19 +626,223 @@ const DetailDocument = () => {
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path fill="white" d="m12 16l-5-5l1.4-1.45l2.6 2.6V4h2v8.15l2.6-2.6L17 11zm-6 4q-.825 0-1.412-.587T4 18v-3h2v3h12v-3h2v3q0 .825-.587 1.413T18 20z" />
|
||||
</svg>
|
||||
Download
|
||||
{t("download")}
|
||||
</button>
|
||||
|
||||
{/* Tombol Bagikan */}
|
||||
<div className="flex flex-row py-3">
|
||||
<p className="text-base font-semibold">{t("share")}</p>
|
||||
<a className="ml-8 cursor-pointer" onClick={() => handleShare("fb", `https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmediahub.polri.go.id%2F${typeString}%2Fdetail%2F${content?.id}"e=${content?.title}`)}>
|
||||
<Icon icon="brandico:facebook" height="20" className="px-auto text-red-600 text-center" />
|
||||
</a>
|
||||
<a className="ml-5 cursor-pointer" onClick={() => handleShare("tw", `https://twitter.com/share?url=https%3A%2F%2Fmediahub.polri.go.id%2F${typeString}%2Fdetail%2F${content?.id}&text=${content?.title}`)}>
|
||||
<Icon icon="mdi:twitter" width="23" className="text-red-600 text-center" />
|
||||
</a>
|
||||
<a className="ml-5 cursor-pointer" onClick={() => handleShare("wa", `text=${content?.title}%0D%0A%0D%0Ahttps%3A%2F%2Fmediahub.polri.go.id%2F${typeString}%2Fdetail%2F${content?.id}`)}>
|
||||
<Icon icon="ri:whatsapp-fill" width="23" className="text-red-600 text-center" />
|
||||
</a>
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex justify-end gap-1 cursor-pointer" asChild>
|
||||
<a className="ml-5 cursor-pointer" data-toggle="dropdown" href="#" aria-expanded="false">
|
||||
<Icon icon="material-symbols-light:mail" width="23" className="text-red-600 text-center" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full mb-8">
|
||||
{/* Comment */}
|
||||
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
|
||||
<div className="gap-5 flex flex-col px-4 lg:px-16">
|
||||
<p className="flex items-start text-lg">Berikan Komentar</p>
|
||||
<Textarea placeholder="Type your comments here." className="flex w-full" />
|
||||
<button className="flex items-start bg-[#bb3523] rounded-lg text-white w-fit px-4 py-1">Kirim</button>
|
||||
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7]">
|
||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||
<p className="flex items-start text-lg">{t("comment")}</p>
|
||||
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
||||
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
|
||||
{t("send")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="border-b-2 border-slate-300 mt-4 w-auto"></div>
|
||||
|
||||
<div>
|
||||
{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-12 lg:h-16 w-12 lg:w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||
<div className="border border-slate-300 w-full p-2 lg:p-4 bg-white gap-1">
|
||||
<p className="text-slate-500 text-sm lg: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-[13px] lg: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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("reply")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("delete")}</small>
|
||||
</a>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{visibleInput === `comment-id-${data.id}` && (
|
||||
<div id={`comment-id-${data.id}`} className="px-4 pl-[72px] lg:px-14 lg:pl-32 mt-2 ">
|
||||
<Textarea id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder={t("enterReply")} />
|
||||
<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-2 text-xs lg:text-base lg:px-4 py-1 mt-2 cursor-pointer">{t("send")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("cancel")}</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:pr-14 pl-16 lg:pl-32">
|
||||
<img src={child1.suggestionFrom?.profilePictureUrl} onError={addDefaultProfile} alt="" className="h-10 lg:h-16 w-10 lg:w-16 mr-2" />
|
||||
<div className="border border-slate-300 w-full p-2 lg:p-4 bg-white gap-1">
|
||||
<p className="text-slate-500 text-sm lg: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-[13px] lg: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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("reply")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("delete")}</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{visibleInput === `comment-id-${child1.id}` && (
|
||||
<div id={`comment-id-${child1.id}`} className="px-4 lg:px-14 pl-28 lg:pl-[200px]">
|
||||
<Textarea name="" className="mt-2 " id={`input-comment-${child1.id}`} placeholder={t("enterReply")} />
|
||||
<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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("send")}</small>
|
||||
</a>
|
||||
<a onClick={() => showInput(`comment-id-${child1.id}`)}>
|
||||
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("cancel")}</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:pr-14 pl-28 lg:pl-48">
|
||||
<img src={child2.suggestionFrom?.profilePictureUrl} className="h-9 lg:h-16 w-9 lg:w-16 mr-2" onError={addDefaultProfile} alt="" />
|
||||
<div className="border border-slate-300 w-full p-2 lg:p-4 bg-white gap-1">
|
||||
<p className="text-slate-500 text-sm lg: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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("reply")}</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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("delete")}</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{visibleInput === `comment-id-${child2.id}` && (
|
||||
<div id={`comment-id-${child2.id}`} className="px-4 lg:px-14 pl-40 lg:pl-[265px]">
|
||||
<Textarea name="" id={`input-comment-${child2.id}`} className="my-2" placeholder={t("enterReply")} />
|
||||
<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-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("send")}</small>
|
||||
</a>
|
||||
<a onClick={() => showInput(`comment-id-${child2.id}`)}>
|
||||
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-2 text-xs lg:text-base lg:px-4 py-1 cursor-pointer">{t("cancel")}</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
: ""}
|
||||
</div>
|
||||
))
|
||||
: ""}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { Input } from "@/components/ui/input";
|
|||
import { Button } from "@/components/ui/button";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import { checkMaliciousText, formatDateToIndonesian, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import parse from "html-react-parser";
|
||||
import $ from "jquery";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
|
@ -594,12 +594,17 @@ const DetailAudio = () => {
|
|||
<p className="text-xs lg:text-sm">
|
||||
{t("by")} <span className="font-semibold text-black">{detailDataAudio?.uploadedBy?.userLevel?.name}</span>
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm">
|
||||
{/* <p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")} {detailDataAudio?.updatedAt} WIB |
|
||||
</p> */}
|
||||
<p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")}
|
||||
{formatDateToIndonesian(new Date(detailDataAudio?.updatedAt))} {"WIB"}
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm flex justify-center items-center">
|
||||
|
|
||||
<Icon icon="formkit:eye" width="15" height="15" />
|
||||
{detailDataAudio?.clickCount}
|
||||
{detailDataAudio?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
|
|
@ -611,7 +616,7 @@ const DetailAudio = () => {
|
|||
{/* Keterangan */}
|
||||
<div className="w-full">
|
||||
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8">{detailDataAudio?.title}</h1>
|
||||
<div className="font-light text-justify mb-5 lg:mb-0" dangerouslySetInnerHTML={{ __html: detailDataAudio?.htmlDescription }} />
|
||||
<div className="font-light text-justify mb-5 lg:mb-0 space-y-4" dangerouslySetInnerHTML={{ __html: detailDataAudio?.htmlDescription }} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -724,7 +729,7 @@ const DetailAudio = () => {
|
|||
<p className="flex items-start text-lg">{t("comment")}</p>
|
||||
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
||||
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
|
||||
{t("send")}
|
||||
{t("send")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,59 +1,159 @@
|
|||
"use client";
|
||||
import { Reveal } from "@/components/landing-page/Reveal";
|
||||
import React from "react";
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import * as Yup from "yup";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { getInfoProfile, getProfile, getSubjects } from "@/service/auth";
|
||||
import { close, error, loading, successCallback } from "@/config/swal";
|
||||
import { sendMessage } from "@/service/landing/landing";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const ContactForm = () => {
|
||||
const router = useRouter();
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
const [subjects, setSubjects] = useState<any>();
|
||||
const [isOtherActive, setIsOtherActive] = useState(false);
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
const form = document.getElementById("form") as HTMLFormElement;
|
||||
|
||||
// Form Handling
|
||||
const validationSchema = Yup.object().shape({
|
||||
name: Yup.string().required("Nama tidak boleh kosong"),
|
||||
email: Yup.string().required("Email tidak boleh kosong"),
|
||||
subjects: Yup.string().required("Subjek tidak boleh kosong"),
|
||||
message: Yup.string().required("Pesan tidak boleh kosong"),
|
||||
});
|
||||
|
||||
const formOptions = {
|
||||
resolver: yupResolver(validationSchema),
|
||||
};
|
||||
|
||||
const { register, handleSubmit, formState, setValue } = useForm(formOptions);
|
||||
|
||||
const { errors } = formState;
|
||||
|
||||
useEffect(() => {
|
||||
async function initState() {
|
||||
const response = await getInfoProfile();
|
||||
const responseSubject = await getSubjects();
|
||||
const profile = response?.data?.data;
|
||||
|
||||
setSubjects(responseSubject?.data?.data);
|
||||
console.log(response);
|
||||
setValue("name", profile?.fullname);
|
||||
setValue("email", profile?.email); // setValue('name', profile?.fullname);
|
||||
// setValue('name', profile?.fullname);
|
||||
}
|
||||
|
||||
initState();
|
||||
}, []);
|
||||
|
||||
async function save(data: any) {
|
||||
loading();
|
||||
const finalData = {
|
||||
name: data.name,
|
||||
email: data.email,
|
||||
phone: data.phone,
|
||||
title: isOtherActive ? data.othersubject : data.subjects,
|
||||
message: data.message,
|
||||
};
|
||||
|
||||
const response = await sendMessage(finalData);
|
||||
if (response?.error) {
|
||||
error(response?.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
close();
|
||||
successCallback("Terima kasih, pesan Anda telah terkirim");
|
||||
// $("#form")[0].onreset();
|
||||
if (form) {
|
||||
form.reset();
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmit(data: any) {
|
||||
if (userId == undefined) {
|
||||
router.push("/auth/login");
|
||||
} else {
|
||||
save(data);
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubjects = (e: any) => {
|
||||
const id = e.target.value;
|
||||
|
||||
if (id == "Lainnya") {
|
||||
setIsOtherActive(true);
|
||||
} else {
|
||||
setIsOtherActive(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto bg-white p-6">
|
||||
<form method="POST" id="form" onSubmit={handleSubmit(onSubmit)} className="max-w-2xl mx-auto bg-white p-6">
|
||||
<Reveal>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-center mb-6">
|
||||
<img src="/assets/icons-contact.png" alt="contact" />
|
||||
<h2 className="ml-4 text-2xl font-bold">Hubungi Kami</h2>
|
||||
<h2 className="ml-4 text-2xl font-bold">{t("contactUs")}</h2>
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-1">Tulis Pesan</h3>
|
||||
<p className="text-sm text-gray-600 mb-6">Silahkan tinggalkan pesan Anda pada kolom yang tersedia</p>
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-1">{t("writeMessage")}</h3>
|
||||
<p className="text-sm text-gray-600 mb-6">{t("leaveMessage")}</p>
|
||||
|
||||
{/* Form */}
|
||||
<form>
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Nama</label>
|
||||
<input type="text" placeholder="Masukkan nama lengkap Anda" className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required />
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("name")}</label>
|
||||
<input type="text" placeholder={t("enterName")} className={`w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${errors.name ? "block" : ""}`} {...register("name")} required />
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Email</label>
|
||||
<input type="email" placeholder="name@mail.com" className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required />
|
||||
<input type="email" placeholder="name@mail.com" className={`w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${errors.email ? "block" : ""}`} {...register("email")} required />
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">No. Handphone (Optional)</label>
|
||||
<input type="text" placeholder="Masukkan no.handphone" className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("number")} (Optional)</label>
|
||||
<input type="text" placeholder={t("enterNumber")} className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Subjek</label>
|
||||
<select className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" defaultValue="">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("subject")}</label>
|
||||
<select
|
||||
className={`w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${errors.subjects ? "block" : ""}`}
|
||||
{...register("subjects", { onChange: (e) => handleSubjects(e) })}
|
||||
defaultValue=""
|
||||
>
|
||||
<option value="" disabled>
|
||||
Pilih Subjek
|
||||
{t("selectSubject")}
|
||||
</option>
|
||||
<option value="1">Pertanyaan</option>
|
||||
<option value="2">Kritik</option>
|
||||
<option value="3">Saran</option>
|
||||
{/* <option value="1">{t("question")}</option>
|
||||
<option value="2">{t("criticism")}</option>
|
||||
<option value="3">{t("suggestion")}</option> */}
|
||||
{subjects?.map((list: any) => (
|
||||
<option key={list.id} value={list.title}>
|
||||
{list.title}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Pesan</label>
|
||||
<textarea placeholder="Tulis pesan Anda" rows={4} className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("messages")}</label>
|
||||
<textarea placeholder={t("writeYourMessage")} rows={4} className="w-full p-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" className="w-fit bg-blue-500 flex justify-self-end text-white p-2 px-8 rounded-md hover:bg-blue-600 transition">
|
||||
Kirim
|
||||
{t("send")}
|
||||
</button>
|
||||
</form>
|
||||
</Reveal>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { checkWishlistStatus, deleteWishlist, getInfoProfile, mediaWishlist, sav
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Link, useRouter } from "@/i18n/routing";
|
||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import HeaderManagement from "@/components/landing-page/header-management";
|
||||
import SidebarManagement from "@/components/landing-page/sidebar-management";
|
||||
|
|
@ -19,6 +19,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||
import ImageBlurry from "@/components/ui/image-blurry";
|
||||
import Image from "next/image";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const Galery = (props: any) => {
|
||||
const [profile, setProfile] = useState<any>();
|
||||
|
|
@ -26,6 +27,7 @@ const Galery = (props: any) => {
|
|||
const router = useRouter();
|
||||
const MySwal = withReactContent(Swal);
|
||||
const searchParams = useSearchParams();
|
||||
const pathname = usePathname();
|
||||
const page: any = searchParams?.get("page");
|
||||
const title = searchParams?.get("title");
|
||||
const category = searchParams?.get("category");
|
||||
|
|
@ -50,6 +52,7 @@ const Galery = (props: any) => {
|
|||
const [emailShareInput, setEmailShareInput] = useState<any>();
|
||||
const [emailMessageInput, setEmailMessageInput] = useState();
|
||||
const id = searchParams?.get("id");
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
useEffect(() => {
|
||||
getDataVideo();
|
||||
|
|
@ -278,98 +281,117 @@ const Galery = (props: any) => {
|
|||
<HeaderManagement />
|
||||
<div className="flex flex-col lg:flex-row">
|
||||
<SidebarManagement />
|
||||
<div className="w-full lg:w-2/3 p-8 lg:p-12">
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold mb-3">Galeri Saya</h1>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="w-full lg:w-2/3 p-8 lg:p-0 mt-12">
|
||||
<div className="flex flex-col mt-4">
|
||||
<div className="mx-auto w-full max-w-7xl justify-start flex flex-col lg:flex-row gap-5 mb-4">
|
||||
<h1 className="text-2xl w-fit font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-center text-white">
|
||||
{/* <span className="text-black">Galeri </span>
|
||||
Saya */}
|
||||
{pathname?.split("/")[1] == "in" ? (
|
||||
<>
|
||||
<span className="text-black ">{t("gallery")}</span>
|
||||
{t("my")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-black">{t("my")}</span>
|
||||
{t("gallery")}
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
|
||||
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
|
||||
<TabsList className="grid grid-cols-2 lg:flex lg:flex-row ">
|
||||
<TabsTrigger
|
||||
value="image"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Foto
|
||||
{t("image")}
|
||||
</TabsTrigger>
|
||||
<div className="text-[#bb3523] text-lg hidden md:inline-block">|</div>
|
||||
<TabsTrigger
|
||||
value="video"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Audio Visual
|
||||
{t("video")}
|
||||
</TabsTrigger>
|
||||
<div className="text-[#bb3523] text-lg hidden md:inline-block">|</div>
|
||||
<TabsTrigger
|
||||
value="text"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Teks
|
||||
{t("text")}
|
||||
</TabsTrigger>
|
||||
<div className="text-[#bb3523] text-lg hidden md:inline-block">|</div>
|
||||
<TabsTrigger
|
||||
value="audio"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Audio
|
||||
{t("audio")}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
{selectedTab == "video" ? (
|
||||
contentVideo?.length > 0 ? (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{contentVideo?.map((video: any) => (
|
||||
<Card key={video?.id}>
|
||||
<CardContent className="flex flex-col bg-black dark:bg-white w-full rounded-lg p-0">
|
||||
<Card key={video?.id} className="hover:scale-105 transition-transform duration-300">
|
||||
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
||||
<div>
|
||||
<Link href={`/video/detail/${video?.mediaUpload?.slug}`}>
|
||||
{/* <img src={video?.mediaUpload?.thumbnailLink} className="h-40 object-cover items-center justify-center cursor-pointer rounded-lg " /> */}
|
||||
<div className="img-container h-60 bg-[#e9e9e9] cursor-pointer rounded-lg">
|
||||
<ImageBlurry src={video?.mediaUpload?.thumbnailLink} alt={video?.mediaUpload?.title} style={{ objectFit: "contain", width: "100%", height: "100%" }} />
|
||||
</div>
|
||||
</Link>
|
||||
<div className="font-semibold p-4 text-white text-xs lg:text-sm dark:text-black truncate w-full">{video?.mediaUpload?.title}</div>
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex justify-end gap-1 cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
<div className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
||||
<div className="relative h-60 rounded-lg overflow-hidden">
|
||||
<ImageBlurry src={video?.mediaUpload?.thumbnailLink} alt={video?.mediaUpload?.title} style={{ objectFit: "cover", width: "100%", height: "100%" }} />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-transparent via-gray-900/80 to-transparent text-white">
|
||||
<Link href={`/video/detail/${video?.mediaUpload?.slug}`}>
|
||||
<p className="text-sm p-2 lg:text-base font-semibold truncate">{video?.mediaUpload?.title}</p>
|
||||
</Link>
|
||||
<p className="flex text-[10px] ml-1 mb-2 items-end">
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">{t("save")}</p>
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex flex-row items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-1">{t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</p>
|
||||
</div>
|
||||
<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} />
|
||||
<p className="text-base font-semibold">Hapus</p>
|
||||
</a>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
@ -414,12 +436,16 @@ const Galery = (props: any) => {
|
|||
</div>
|
||||
</div>
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex justify-end gap-1 cursor-pointer" asChild>
|
||||
<PopoverTrigger className="flex cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">{t("save")}</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>
|
||||
|
|
@ -427,29 +453,25 @@ const Galery = (props: any) => {
|
|||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-3">
|
||||
<button className="w-full flex flex-row items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||
<p className="text-base font-semibold mb-1">{t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<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} />
|
||||
<p className="text-base font-semibold">Hapus</p>
|
||||
</a>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
|
|
@ -464,54 +486,61 @@ const Galery = (props: any) => {
|
|||
contentImage?.length > 0 ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{contentImage?.map((image: any) => (
|
||||
<Card key={image?.id}>
|
||||
<CardContent className="flex flex-col bg-black dark:bg-white w-full h-full rounded-lg p-0">
|
||||
<Link href={`/image/detail/${image?.mediaUpload?.slug}`}>
|
||||
{/* <img src={image?.mediaUpload?.thumbnailLink} className="h-40 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center" /> */}
|
||||
<div className="img-container h-60 bg-[#e9e9e9] cursor-pointer rounded-lg">
|
||||
<ImageBlurry src={image?.mediaUpload?.thumbnailLink} alt={image?.mediaUpload?.title} style={{ objectFit: "contain", width: "100%", height: "100%" }} />
|
||||
</div>
|
||||
</Link>
|
||||
<div className="font-semibold p-4 text-white text-xs lg:text-sm dark:text-black truncate w-full">{image?.mediaUpload?.title}</div>
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex justify-end gap-1 cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<Card key={image?.id} className="hover:scale-105 transition-transform duration-300">
|
||||
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
||||
<div>
|
||||
<div className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
||||
<div className="relative h-60 rounded-lg overflow-hidden">
|
||||
<ImageBlurry src={image?.mediaUpload?.thumbnailLink} alt={image?.mediaUpload?.title} style={{ objectFit: "cover", width: "100%", height: "100%" }} />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-transparent via-gray-900/80 to-transparent text-white">
|
||||
<Link href={`/video/detail/${image?.mediaUpload?.slug}`}>
|
||||
<p className="text-sm p-2 lg:text-base font-semibold truncate">{image?.mediaUpload?.title}</p>
|
||||
</Link>
|
||||
<p className="flex text-[10px] ml-1 mb-2 items-end">
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">{t("save")}</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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex flex-row items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-1"> {t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<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} />
|
||||
<p className="text-base font-semibold">Hapus</p>
|
||||
</a>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
|
|
@ -542,7 +571,7 @@ const Galery = (props: any) => {
|
|||
<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 Dokumen
|
||||
Download {t("document")}
|
||||
</div>
|
||||
</div>
|
||||
<Popover>
|
||||
|
|
@ -552,6 +581,10 @@ const Galery = (props: any) => {
|
|||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">{t("save")}</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>
|
||||
|
|
@ -559,29 +592,25 @@ const Galery = (props: any) => {
|
|||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-3">
|
||||
<button className="w-full flex items-center gap-2">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||
<p className="text-base font-semibold mb-2">{t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<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} />
|
||||
<p className="text-base font-semibold">Hapus</p>
|
||||
</a>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||
import ImageBlurry from "@/components/ui/image-blurry";
|
||||
import Image from "next/image";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const Galery = (props: any) => {
|
||||
const [profile, setProfile] = useState<any>();
|
||||
|
|
@ -53,6 +54,7 @@ const Galery = (props: any) => {
|
|||
const [emailShareInput, setEmailShareInput] = useState<any>();
|
||||
const [emailMessageInput, setEmailMessageInput] = useState();
|
||||
const id = searchParams?.get("id");
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
useEffect(() => {
|
||||
getDataVideo();
|
||||
|
|
@ -284,98 +286,105 @@ const Galery = (props: any) => {
|
|||
<HeaderManagement />
|
||||
<div className="flex flex-col lg:flex-row">
|
||||
<SidebarManagement />
|
||||
<div className="w-full lg:w-2/3 p-8 lg:p-12">
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold">Galeri {profile?.institute?.name}</h1>
|
||||
</div>
|
||||
<div className="w-full lg:w-2/3 p-8 lg:p-0 mt-12">
|
||||
<div className="flex flex-col mt-4">
|
||||
<div className="mx-auto w-full max-w-7xl justify-start flex flex-col lg:flex-row gap-5 mb-4">
|
||||
<h1 className="text-2xl w-fit font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-center text-white">
|
||||
<span className="text-black">{t("gallery")} </span>
|
||||
{profile?.institute?.name}
|
||||
</h1>
|
||||
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
|
||||
<TabsList className="grid grid-cols-2 lg:flex lg:flex-row ">
|
||||
<TabsTrigger
|
||||
value="image"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Foto
|
||||
{t("image")}
|
||||
</TabsTrigger>
|
||||
<div className="text-[#bb3523] text-lg hidden md:inline-block">|</div>
|
||||
<TabsTrigger
|
||||
value="video"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Audio Visual
|
||||
{t("video")}
|
||||
</TabsTrigger>
|
||||
<div className="text-[#bb3523] text-lg hidden md:inline-block">|</div>
|
||||
<TabsTrigger
|
||||
value="text"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Teks
|
||||
{t("text")}
|
||||
</TabsTrigger>
|
||||
<div className="text-[#bb3523] text-lg hidden md:inline-block">|</div>
|
||||
<TabsTrigger
|
||||
value="audio"
|
||||
className="relative text-xs md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
|
||||
>
|
||||
Audio
|
||||
{t("audio")}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<div className="px-2">
|
||||
{selectedTab == "video" ? (
|
||||
contentVideo?.length > 0 ? (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{contentVideo?.map((video: any) => (
|
||||
<Card key={video?.id}>
|
||||
<CardContent className="flex flex-col bg-black dark:bg-white w-full rounded-lg p-0">
|
||||
<Card key={video?.id} className="hover:scale-105 transition-transform duration-300">
|
||||
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
||||
<div>
|
||||
<Link href={`/video/detail/${video?.mediaUpload?.slug}`}>
|
||||
{/* <img src={video?.mediaUpload?.thumbnailLink} className="h-40 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center" /> */}
|
||||
<div className="img-container h-60 bg-[#e9e9e9] cursor-pointer rounded-lg">
|
||||
<ImageBlurry src={video?.mediaUpload?.thumbnailLink} alt={video?.mediaUpload?.title} style={{ objectFit: "contain", width: "100%", height: "100%" }} />
|
||||
</div>
|
||||
</Link>
|
||||
<div className="font-semibold p-4 text-white text-xs lg:text-sm dark:text-black truncate w-full">{video?.mediaUpload?.title}</div>
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex justify-end gap-1 cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex flex-row items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-1">Bagikan</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
<div className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
||||
<div className="relative h-60 rounded-lg overflow-hidden">
|
||||
<ImageBlurry src={video?.mediaUpload?.thumbnailLink} alt={video?.mediaUpload?.title} style={{ objectFit: "cover", width: "100%", height: "100%" }} />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-transparent via-gray-900/80 to-transparent text-white">
|
||||
<Link href={`/video/detail/${video?.mediaUpload?.slug}`}>
|
||||
<p className="text-sm p-2 lg:text-base font-semibold truncate">{video?.mediaUpload?.title}</p>
|
||||
</Link>
|
||||
<p className="flex text-[10px] ml-1 mb-2 items-end">
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">{t("save")} </p>
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex flex-row items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-1">{t("share")} </p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">{t("shareTo")} </h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("shareTo")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</p>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
@ -426,7 +435,7 @@ const Galery = (props: any) => {
|
|||
<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>
|
||||
<p className="text-base font-semibold mb-2">{t("save")}</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} />
|
||||
|
|
@ -437,18 +446,18 @@ const Galery = (props: any) => {
|
|||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-2">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-2">Bagikan</p>
|
||||
<p className="text-base font-semibold mb-2">{t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
|
|
@ -468,54 +477,61 @@ const Galery = (props: any) => {
|
|||
contentImage?.length > 0 ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{contentImage?.map((image: any) => (
|
||||
<Card key={image?.id}>
|
||||
<CardContent className="flex flex-col bg-black dark:bg-white w-full rounded-lg p-0">
|
||||
<Link href={`/image/detail/${image?.mediaUpload?.slug}`}>
|
||||
{/* <img src={image?.mediaUpload?.thumbnailLink} className="h-40 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center" /> */}
|
||||
<div className="img-container h-60 bg-[#e9e9e9] cursor-pointer rounded-lg">
|
||||
<ImageBlurry src={image?.mediaUpload?.thumbnailLink} alt={image?.mediaUpload?.title} style={{ objectFit: "contain", width: "100%", height: "100%" }} />
|
||||
<Card key={image?.id} className="hover:scale-105 transition-transform duration-300">
|
||||
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
||||
<div>
|
||||
<div className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
||||
<div className="relative h-60 rounded-lg overflow-hidden">
|
||||
<ImageBlurry src={image?.mediaUpload?.thumbnailLink} alt={image?.mediaUpload?.title} style={{ objectFit: "cover", width: "100%", height: "100%" }} />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-transparent via-gray-900/80 to-transparent text-white">
|
||||
<Link href={`/video/detail/${image?.mediaUpload?.slug}`}>
|
||||
<p className="text-sm p-2 lg:text-base font-semibold truncate">{image?.mediaUpload?.title}</p>
|
||||
</Link>
|
||||
<p className="flex text-[10px] ml-1 mb-2 items-end">
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">{t("save")}</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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex flex-row items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-1"> {t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
<div className="font-semibold p-4 text-white text-xs lg:text-sm dark:text-black truncate w-full">{image?.mediaUpload?.title}</div>
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex justify-end gap-1 cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-2">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-2">Bagikan</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
|
|
@ -546,7 +562,7 @@ const Galery = (props: any) => {
|
|||
<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 Dokumen
|
||||
Download {t("document")}
|
||||
</div>
|
||||
</div>
|
||||
<Popover>
|
||||
|
|
@ -558,7 +574,7 @@ const Galery = (props: any) => {
|
|||
<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>
|
||||
<p className="text-base font-semibold mb-2">{t("save")}</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} />
|
||||
|
|
@ -569,18 +585,18 @@ const Galery = (props: any) => {
|
|||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-2">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-2">Bagikan</p>
|
||||
<p className="text-base font-semibold mb-2">{t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ import { getPublicSuggestionList } from "@/service/landing/landing";
|
|||
import { getDetail } from "@/service/detail/detail";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import * as Yup from "yup";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
import Cookies from "js-cookie";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const imageSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -63,6 +63,7 @@ const page = (props: any) => {
|
|||
const [isLoadingData, setIsLoadingData] = useState<boolean>(false);
|
||||
const [detailData, setDetailData] = useState<any>(null);
|
||||
const [articleImages, setArticleImages] = useState<string[]>([]);
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
const userLevelId = getCookiesDecrypt("ulie");
|
||||
const roleId = getCookiesDecrypt("urie");
|
||||
|
|
@ -293,21 +294,21 @@ const page = (props: any) => {
|
|||
<SidebarManagement />
|
||||
<div className="w-full lg:w-2/3 p-8 lg:p-12">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-xl font-bold mb-5">Content Rewrite</div>
|
||||
<div className="text-xl font-bold mb-5">{t("content")} Rewrite</div>
|
||||
<div className="p-8 border border-black rounded-lg">
|
||||
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
||||
{content && (
|
||||
<div className="flex flex-col gap-2 ">
|
||||
<div className="flex flex-col lg:flex-row gap-2">
|
||||
<div className="gap-1 flex flex-col mb-3">
|
||||
<p className="font-semibold">Bahasa</p>
|
||||
<p className="font-semibold">{t("language")}</p>
|
||||
<Select value={selectedLanguage} onValueChange={setSelectedLanguage}>
|
||||
<SelectTrigger className="w-full lg:w-[180px]">
|
||||
<SelectValue placeholder="Pilih Bahasa" />
|
||||
<SelectValue placeholder={t("selectLanguage")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Pilih Bahasa</SelectLabel>
|
||||
<SelectLabel>{t("selectLanguage")}</SelectLabel>
|
||||
<SelectItem value="id">Indonesia</SelectItem>
|
||||
<SelectItem value="en">English</SelectItem>
|
||||
</SelectGroup>
|
||||
|
|
@ -315,31 +316,31 @@ const page = (props: any) => {
|
|||
</Select>
|
||||
</div>
|
||||
<div className="gap-1 flex flex-col mb-3">
|
||||
<p className="font-semibold">Context Type</p>
|
||||
<p className="font-semibold">{t("contextType")}</p>
|
||||
<Select value={selectedContextType} onValueChange={setSelectedContextType}>
|
||||
<SelectTrigger className="w-full lg:w-[180px]">
|
||||
<SelectValue placeholder="Select Context" />
|
||||
<SelectValue placeholder={t("selectContext")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Select Context Type</SelectLabel>
|
||||
<SelectItem value="text">Text</SelectItem>
|
||||
<SelectItem value="article">Article</SelectItem>
|
||||
<SelectItem value="transcript">Transcript</SelectItem>
|
||||
<SelectLabel>{t("selectContext")}</SelectLabel>
|
||||
<SelectItem value="text">{t("text")}</SelectItem>
|
||||
<SelectItem value="article">{t("article")}</SelectItem>
|
||||
<SelectItem value="transcript">{t("transcript")}</SelectItem>
|
||||
<SelectItem value="url">URL</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="gap-1 flex flex-col mb-3">
|
||||
<p className="font-semibold">Writing Style</p>
|
||||
<p className="font-semibold">{t("writingStyle")}</p>
|
||||
<Select value={selectedWritingStyle} onValueChange={setSelectedWritingStyle}>
|
||||
<SelectTrigger className="w-full lg:w-[180px]">
|
||||
<SelectValue placeholder="Select Writing" />
|
||||
<SelectValue placeholder={t("selectWriting")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Select Writing Style</SelectLabel>
|
||||
<SelectLabel>{t("selectWriting")}</SelectLabel>
|
||||
<SelectItem value="firendly">Friendly</SelectItem>
|
||||
<SelectItem value="profesional">Profesional</SelectItem>
|
||||
<SelectItem value="informational">Informational</SelectItem>
|
||||
|
|
@ -350,14 +351,14 @@ const page = (props: any) => {
|
|||
</Select>
|
||||
</div>
|
||||
<div className="gap-1 flex flex-col mb-3">
|
||||
<p className="font-semibold">Article Size</p>
|
||||
<p className="font-semibold">{t("articleSize")}</p>
|
||||
<Select value={selectedSize} onValueChange={setSelectedSize}>
|
||||
<SelectTrigger className="w-full lg:w-[180px]">
|
||||
<SelectValue placeholder="Select Size" />
|
||||
<SelectValue placeholder={t("selectSize")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Select Article Size</SelectLabel>
|
||||
<SelectLabel>{t("selectSize")}</SelectLabel>
|
||||
<SelectItem value="news">News (300 - 900 words)</SelectItem>
|
||||
<SelectItem value="info">Info (900 - 2000 words)</SelectItem>
|
||||
<SelectItem value="detail">Detail (2000 - 5000 words)</SelectItem>
|
||||
|
|
@ -367,7 +368,7 @@ const page = (props: any) => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<p className="font-semibold">Judul</p>
|
||||
<p className="font-semibold">{t("title")}</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
|
|
@ -375,7 +376,7 @@ const page = (props: any) => {
|
|||
/>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<p className="font-semibold">Main Keyword</p>
|
||||
<p className="font-semibold">{t("mainKeyword")}</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="mainKeyword"
|
||||
|
|
@ -418,7 +419,7 @@ const page = (props: any) => {
|
|||
</div>
|
||||
|
||||
<div className=" mb-3">
|
||||
<p className="font-semibold">Deskripsi Baru</p>
|
||||
<p className="font-semibold">{t("newDescription")}</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="description"
|
||||
|
|
@ -442,10 +443,10 @@ const page = (props: any) => {
|
|||
}}
|
||||
className="border border-blue-400 hover:bg-blue-400 hover:text-white text-blue-400 text-sm lg:text-base"
|
||||
>
|
||||
Kembali
|
||||
{t("back")}
|
||||
</Button>
|
||||
<Button type="submit" className="border border-blue-500 bg-blue-500 text-sm lg:text-base text-white">
|
||||
Simpan
|
||||
{t("save")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,15 +34,12 @@ const page = () => {
|
|||
const userRoleId = getCookiesDecrypt("urie");
|
||||
const [articleIds, setArticleIds] = useState<any>([]);
|
||||
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
||||
const [selectedArticleId, setSelectedArticleId] = useState(null);
|
||||
const [articleBody, setArticleBody] = useState<any>("");
|
||||
const [selectedAdvConfig, setSelectedAdvConfig] = useState("");
|
||||
const [selectedWritingStyle, setSelectedWritingStyle] = useState("");
|
||||
const [selectedContextType, setSelectedContextType] = useState("");
|
||||
const [selectedLanguage, setSelectedLanguage] = useState("");
|
||||
const [selectedTitle, setSelectedTitle] = useState("");
|
||||
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
||||
const [selectedSEO, setSelectedSEO] = useState("");
|
||||
const [selectedSize, setSelectedSize] = useState("");
|
||||
const [detailArticle, setDetailArticle] = useState<any>(null);
|
||||
const userLevelId = getCookiesDecrypt("ulie");
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||
import ImageBlurry from "@/components/ui/image-blurry";
|
||||
import Image from "next/image";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const page = () => {
|
||||
const [, setProfile] = useState();
|
||||
|
|
@ -43,6 +44,7 @@ const page = () => {
|
|||
const [emailShareInput, setEmailShareInput] = useState<any>();
|
||||
const [emailMessageInput, setEmailMessageInput] = useState();
|
||||
const id = searchParams?.get("id");
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
useEffect(() => {
|
||||
async function initState() {
|
||||
|
|
@ -200,59 +202,69 @@ const page = () => {
|
|||
<HeaderManagement />
|
||||
<div className="flex flex-col lg:flex-row">
|
||||
<SidebarManagement />
|
||||
<div className="w-full lg:w-2/3 p-8 lg:p-12">
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold mb-4">Galeri Content Rewrite</h1>
|
||||
</div>
|
||||
<div className="w-full lg:w-2/3 p-8 lg:p-14">
|
||||
<h1 className="text-2xl w-fit font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-center text-white mb-4">
|
||||
<span className="text-black">{t("gallery")} </span>
|
||||
{t("content")} Rewrite
|
||||
</h1>
|
||||
<div className="">
|
||||
{contentImage?.length > 0 ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{contentImage?.map((image: any) => (
|
||||
<Card key={image?.id}>
|
||||
<CardContent className="flex flex-col bg-black dark:bg-white w-full rounded-lg p-0">
|
||||
<div className="">
|
||||
<Link href={`/content-management/rewrite/detail/${image.id}`}>
|
||||
{/* <img src={image?.thumbnailUrl} className="h-40 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center" /> */}
|
||||
<div className="img-container h-60 bg-[#e9e9e9] cursor-pointer rounded-lg">
|
||||
<Card key={image?.id} className="hover:scale-105 transition-transform duration-300">
|
||||
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
||||
<div>
|
||||
<div className="relative group overflow-hidden shadow-md hover:shadow-lg">
|
||||
<div className="relative h-60 rounded-lg overflow-hidden">
|
||||
<ImageBlurry src={image?.thumbnailUrl} alt={image?.title} style={{ objectFit: "contain", width: "100%", height: "100%" }} />
|
||||
</div>
|
||||
</Link>
|
||||
<div className="font-semibold p-4 text-white text-xs lg:text-sm dark:text-black truncate w-full">{image?.title}</div>
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex justify-end gap-1 cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-40">
|
||||
<div className="flex items-center gap-1 hover:text-red-800 w-full rounded-lg">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex items-center gap-2">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-3">Bagikan</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">Share Ke Email</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">Email Tujuan :</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder="Tekan Enter untuk input Email" />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-transparent via-gray-900/80 to-transparent text-white">
|
||||
<Link href={`/content-management/rewrite/detail/${image.id}`}>
|
||||
<p className="text-sm p-2 lg:text-base font-semibold truncate">{image?.title}</p>
|
||||
</Link>
|
||||
<p className="flex text-[10px] ml-1 mb-2 items-end">
|
||||
<Popover>
|
||||
<PopoverTrigger className="flex cursor-pointer" asChild>
|
||||
<a className="flex justify-end items-end place-items-end">
|
||||
<Icon className="text-white ml-1" fontSize={25} icon="tabler:dots" />
|
||||
</a>
|
||||
</PopoverTrigger>
|
||||
<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">{t("save")}</p>
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<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">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button className="w-full flex flex-row items-center gap-3">
|
||||
<Icon icon="oi:share" fontSize={20} />
|
||||
<p className="text-base font-semibold mb-1"> {t("share")}</p>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2">{t("shareTo")}</h1>
|
||||
<div className="flex flex-col mb-2">
|
||||
<p className="text-base font-semibold mb-1">{t("destinationEmail")}</p>
|
||||
<Input value={emailShareInput} onChange={(event) => setEmailShareInput(event.target.value)} onKeyPress={handleEmailList} type="email" placeholder={t("pressEnter")} />
|
||||
</div>
|
||||
<Button className="bg-blue-500 text-white p-2 w-fit rounded-lg" onClick={() => shareToEmail()}>
|
||||
{t("send")}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</p>
|
||||
</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>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import HeaderManagement from "@/components/landing-page/header-management";
|
||||
import SidebarManagement from "@/components/landing-page/sidebar-management";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import { close, loading } from "@/config/swal";
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
import { getInfoProfile, getUsersTeams, saveUserReports } from "@/service/landing/landing";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
|
@ -10,9 +10,9 @@ import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, Di
|
|||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
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";
|
||||
import Image from "next/image";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const page = () => {
|
||||
const [user, setUser] = useState<any>();
|
||||
|
|
@ -23,6 +23,7 @@ const page = () => {
|
|||
const MySwal = withReactContent(Swal);
|
||||
const { toast } = useToast();
|
||||
const [reportMessageOpen, setReportMessageOpen] = useState(false);
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
// const launchModal = (user: any) => {
|
||||
// setUserSelected(user);
|
||||
|
|
@ -118,25 +119,22 @@ const page = () => {
|
|||
<SidebarManagement />
|
||||
<div className="w-2/3 p-12">
|
||||
<div className="flex flex-col">
|
||||
<p className="text-lg font-semibold">Tim {profile?.institute?.name}</p>
|
||||
<p className="text-base mb-3">{user?.length} Anggota</p>
|
||||
<p className="text-2xl w-fit font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-center text-white my-4 ">
|
||||
<span className="text-black">{t("team")} </span>
|
||||
{profile?.institute?.name}
|
||||
</p>
|
||||
<p className="text-base mb-3">
|
||||
{user?.length} {t("teamMembers")} {profile?.institute?.name}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-row gap-5">
|
||||
{user?.map((row: any) => (
|
||||
<div key={row?.id}>
|
||||
<Dialog>
|
||||
<DialogTrigger>
|
||||
<div className="flex flex-col items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="5em" height="5em" viewBox="0 0 16 16">
|
||||
<path fill="currentColor" d="M11 7c0 1.66-1.34 3-3 3S5 8.66 5 7s1.34-3 3-3s3 1.34 3 3" />
|
||||
<path
|
||||
fill="black"
|
||||
fill-rule="evenodd"
|
||||
d="M16 8c0 4.42-3.58 8-8 8s-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8M4 13.75C4.16 13.484 5.71 11 7.99 11c2.27 0 3.83 2.49 3.99 2.75A6.98 6.98 0 0 0 14.99 8c0-3.87-3.13-7-7-7s-7 3.13-7 7c0 2.38 1.19 4.49 3.01 5.75"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<p className="font-semibold text-md">{row?.fullname}</p>
|
||||
<div className="flex flex-col items-center border border-gray-500 p-2 bg-[#f8f8f8] rounded-md">
|
||||
<Image src="/assets/gg-profile.png" alt="" width={1280} height={720} className="h-10 w-10 mb-4" />
|
||||
<p className="font-bold text-base ">{row?.fullname}</p>
|
||||
<p className="text-sm font-light">{row?.username || "username"}</p>
|
||||
</div>
|
||||
</DialogTrigger>
|
||||
|
|
@ -166,7 +164,7 @@ const page = () => {
|
|||
</div>
|
||||
<div className="border-b border-black w-full"></div>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="text-red-600 mb-2">Alasan Report Akun</h1>
|
||||
<h1 className="text-red-600 mb-2">{t("reasonReport")}</h1>
|
||||
<textarea id="formControlTextarea1" rows={4} className="border border-black font-light" onChange={(e: any) => setReportMessage(e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -174,17 +172,17 @@ const page = () => {
|
|||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="bg-red-500 text-white" type="submit">
|
||||
Kirim
|
||||
{t("send")}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<h1>Simpan Data?</h1>
|
||||
<h1>{t("saveData")}</h1>
|
||||
<DialogFooter>
|
||||
<DialogClose>
|
||||
<Button onClick={save}>Simpan</Button>
|
||||
<Button onClick={save}>{t("save")}</Button>
|
||||
</DialogClose>
|
||||
<DialogClose>
|
||||
<Button>Cancel</Button>
|
||||
<Button>{t("cancel")}</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking"
|
|||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import { checkMaliciousText, formatDateToIndonesian, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import parse from "html-react-parser";
|
||||
|
|
@ -435,12 +435,16 @@ const DetailDocument = () => {
|
|||
<p className="text-xs lg:text-sm">
|
||||
{t("by")} <span className="font-semibold text-black">{detailDataDocument?.uploadedBy?.userLevel?.name}</span>
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm">
|
||||
{/* <p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")} {detailDataDocument?.updatedAt} WIB |
|
||||
</p> */}
|
||||
<p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")}
|
||||
{formatDateToIndonesian(new Date(detailDataDocument?.updatedAt))} {"WIB"}
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm flex justify-center items-center">
|
||||
<Icon icon="formkit:eye" width="15" height="15" />
|
||||
{detailDataDocument?.clickCount}
|
||||
| <Icon icon="formkit:eye" width="15" height="15" />
|
||||
{detailDataDocument?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
|
|
@ -453,7 +457,7 @@ const DetailDocument = () => {
|
|||
|
||||
{/* Keterangan */}
|
||||
<div className="">
|
||||
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8 text-justify">{detailDataDocument?.title}</h1>
|
||||
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8 text-justify space-y-4">{detailDataDocument?.title}</h1>
|
||||
<div dangerouslySetInnerHTML={{ __html: detailDataDocument?.htmlDescription }} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"use client";
|
||||
import { Reveal } from "@/components/landing-page/Reveal";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
interface FAQItem {
|
||||
question: string;
|
||||
|
|
@ -8,22 +9,24 @@ interface FAQItem {
|
|||
}
|
||||
|
||||
const FAQS: React.FC = () => {
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
const faqs: FAQItem[] = [
|
||||
{
|
||||
question: "APA SAJA KONTEN-KONTEN YANG ADA DI MEDIAHUB DAN KATEGORI DI DALAMNYA?",
|
||||
answer: "MediaHub memiliki beragam konten seperti berita, video, dan dokumen yang dikategorikan dalam topik seperti edukasi, hiburan, dan informasi terkini.",
|
||||
question: t("question1"),
|
||||
answer: t("answer1"),
|
||||
},
|
||||
{
|
||||
question: "BAGAIMANA KONTEN DARI MEDIAHUB DAPAT DIUNDUH?",
|
||||
answer: "Anda dapat mengunduh konten dengan klik tombol unduh yang tersedia pada setiap konten di halaman MediaHub.",
|
||||
question: t("question2"),
|
||||
answer: t("answer2"),
|
||||
},
|
||||
{
|
||||
question: "SIAPA SAJA YANG DAPAT MENDAFTARKAN DIRI SEBAGAI PENGGUNA MEDIAHUB?",
|
||||
answer: "Semua orang yang memiliki minat terhadap konten di MediaHub dapat mendaftar sebagai pengguna, baik untuk personal maupun profesional.",
|
||||
question: t("question3"),
|
||||
answer: t("answer3"),
|
||||
},
|
||||
{
|
||||
question: "APA ITU MEDIAHUB? DAN APA SAJA FITUR YANG ADA DI DALAMNYA?",
|
||||
answer: "MediaHub adalah platform yang menyediakan berbagai konten informatif dan edukatif. Fitur utama meliputi pencarian, pengunduhan, dan personalisasi konten.",
|
||||
question: t("question4"),
|
||||
answer: t("answer4"),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -44,7 +47,7 @@ const FAQS: React.FC = () => {
|
|||
|
||||
{/* FAQS Items */}
|
||||
<div className="space-y-4">
|
||||
{faqs.map((faq, index) => (
|
||||
{faqs?.map((faq, index) => (
|
||||
<div key={index} className="border-b border-gray-300 pb-2 cursor-pointer">
|
||||
<div className="flex justify-between items-center" onClick={() => toggleFAQ(index)}>
|
||||
<h3 className="text-sm font-semibold text-gray-800">{faq.question}</h3>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Reveal } from "@/components/landing-page/Reveal";
|
|||
import { error, loading, successCallback } from "@/config/swal";
|
||||
import { getFeedback, postUserFeedback } from "@/service/landing/landing";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { any } from "zod";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
interface RatingProps {
|
||||
label: string;
|
||||
|
|
@ -57,6 +57,7 @@ const FeedbackForm: React.FC = () => {
|
|||
|
||||
const [userFeedbacks, setUserFeedbacks] = useState<Feedback[]>([]);
|
||||
const [hasMounted, setHasMounted] = useState(false);
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
const handleRatingChange = (id: any, score: any) => {
|
||||
const listData = [...userFeedbacks];
|
||||
|
|
@ -119,14 +120,14 @@ const FeedbackForm: React.FC = () => {
|
|||
<div className="max-w-6xl flex flex-col mx-auto p-4 lg:p-40 gap-5">
|
||||
<div className="flex items-center justify-center mb-6">
|
||||
<img src="/assets/icons-feedback.png" alt="Feedback" />
|
||||
<h2 className="ml-4 text-[15px] lg:text-[32px] font-bold text-gray-800">Feedback Pengguna</h2>
|
||||
<h2 className="ml-4 text-[15px] lg:text-[32px] font-bold text-gray-800">{t("userFeedback")}</h2>
|
||||
</div>
|
||||
<Rating label="Silakan berikan rating Anda terkait dengan kemudahan akses website MediaHUB Polri" onRate={(rating) => handleRatingChange("accessibility", rating)} />
|
||||
<Rating label="Silakan berikan rating Anda terkait dengan tampilan website MediaHUB Polri" onRate={(rating) => handleRatingChange("appearance", rating)} />
|
||||
<Rating label="Silakan berikan rating Anda terkait dengan konten MediaHUB Polri" onRate={(rating) => handleRatingChange("content", rating)} />
|
||||
<Rating label={t("ratings")} onRate={(rating) => handleRatingChange("accessibility", rating)} />
|
||||
<Rating label={t("ratings2")} onRate={(rating) => handleRatingChange("appearance", rating)} />
|
||||
<Rating label={t("ratings3")} onRate={(rating) => handleRatingChange("content", rating)} />
|
||||
<div className="flex justify-center">
|
||||
<button onClick={handleSubmit} className="w-fit lg:w-32 bg-[#2F80ED] text-white py-2 px-4 gap-4 rounded-md hover:bg-blue-600 transition text-sm lg:text-base">
|
||||
Kirim
|
||||
{t("send")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
|
||||
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import { checkMaliciousText, formatDateToIndonesian, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import parse from "html-react-parser";
|
||||
|
|
@ -473,11 +473,16 @@ const DetailInfo = () => {
|
|||
<p className="text-xs lg:text-sm">
|
||||
{t("by")} <span className="font-semibold text-black">{detailDataImage?.uploadedBy?.userLevel?.name}</span>
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm">
|
||||
{/* <p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")}
|
||||
{detailDataImage?.updatedAt} WIB |
|
||||
</p> */}
|
||||
<p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")}
|
||||
{formatDateToIndonesian(new Date(detailDataImage?.updatedAt))} {"WIB"}
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm flex justify-center items-center">
|
||||
|
|
||||
<Icon icon="formkit:eye" width="15" height="15" />
|
||||
{detailDataImage?.clickCount}
|
||||
</p>
|
||||
|
|
@ -493,7 +498,7 @@ const DetailInfo = () => {
|
|||
{/* Keterangan */}
|
||||
<div className="w-full">
|
||||
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8">{detailDataImage?.title}</h1>
|
||||
<div className="font-light text-justify mb-5 lg:mb-0" dangerouslySetInnerHTML={{ __html: detailDataImage?.htmlDescription }} />
|
||||
<div className="font-light text-justify mb-5 space-y-4 lg:mb-0" dangerouslySetInnerHTML={{ __html: detailDataImage?.htmlDescription }} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ import { Icon } from "@iconify/react/dist/iconify.js";
|
|||
import { useSearchParams } from "next/navigation";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const InboxSection = () => {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const isUpdate = pathname.includes("update");
|
||||
const searchParams = useSearchParams();
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
const page: any = searchParams?.get("page");
|
||||
|
||||
|
|
@ -53,20 +55,20 @@ const InboxSection = () => {
|
|||
<path d="M12 1C5.925 1 1 5.925 1 12s4.925 11 11 11s11-4.925 11-11S18.075 1 12 1M3 12c0 2.09.713 4.014 1.908 5.542A8.99 8.99 0 0 1 12.065 14a8.98 8.98 0 0 1 7.092 3.458A9 9 0 1 0 3 12m9 9a8.96 8.96 0 0 1-5.672-2.012A6.99 6.99 0 0 1 12.065 16a6.99 6.99 0 0 1 5.689 2.92A8.96 8.96 0 0 1 12 21" />
|
||||
</g>
|
||||
</svg>{" "}
|
||||
<h2 className="ml-4 text-[15px] lg:text-[32px] font-semibold text-gray-800">Pesan Masuk</h2>
|
||||
<h2 className="ml-4 text-[15px] lg:text-[32px] font-semibold text-gray-800">{t("inbox")}</h2>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col justify-center items-center gap-3">
|
||||
<div className="flex justify-center">
|
||||
<div className="flex flex-row gap-10 items-center justify-center">
|
||||
<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">{t("inbox")}</p>
|
||||
</div>
|
||||
<Link href={`/inbox/update`}>Update</Link>
|
||||
<Link href={`/inbox/update`}>{t("update")}</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-10 px-8 w-[400px] mt-3 border border-black rounded-lg flex flex-col">
|
||||
<h1 className="mb-3 text-lg font-semibold">List Notifikasi</h1>
|
||||
<h1 className="mb-3 text-lg font-semibold">{t("notifList")}</h1>
|
||||
<div className="hover:bg-slate-200 rounded-md">
|
||||
{notifications?.map((list: any) => (
|
||||
<a className="flex flex-row items-center ml-1" href={"/" + list.redirectUrl}>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import { getUserNotifications } from "@/service/landing/landing";
|
|||
import { getTimestamp } from "@/utils/globals";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const UpdateSection = () => {
|
||||
const pathname = usePathname();
|
||||
|
|
@ -14,7 +14,7 @@ const UpdateSection = () => {
|
|||
const searchParams = useSearchParams();
|
||||
const page: any = searchParams?.get("page");
|
||||
const pages = page ? page - 1 : 0;
|
||||
|
||||
const t = useTranslations("LandingPage");
|
||||
const [notifications, setNotifications] = useState([]);
|
||||
const [getTotalData, setGetTotalData] = useState();
|
||||
const [, setGetTotalPage] = useState();
|
||||
|
|
@ -50,20 +50,20 @@ const UpdateSection = () => {
|
|||
<path d="M12 1C5.925 1 1 5.925 1 12s4.925 11 11 11s11-4.925 11-11S18.075 1 12 1M3 12c0 2.09.713 4.014 1.908 5.542A8.99 8.99 0 0 1 12.065 14a8.98 8.98 0 0 1 7.092 3.458A9 9 0 1 0 3 12m9 9a8.96 8.96 0 0 1-5.672-2.012A6.99 6.99 0 0 1 12.065 16a6.99 6.99 0 0 1 5.689 2.92A8.96 8.96 0 0 1 12 21" />
|
||||
</g>
|
||||
</svg>{" "}
|
||||
<h2 className="ml-4 text-[15px] lg:text-[32px] font-semibold text-gray-800">Update</h2>
|
||||
<h2 className="ml-4 text-[15px] lg:text-[32px] font-semibold text-gray-800">{t("update")}</h2>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="flex justify-center">
|
||||
<div className="flex flex-row gap-10 items-center justify-center">
|
||||
<div>
|
||||
<Link href={`/inbox`}>Pesan Masuk</Link>
|
||||
<Link href={`/inbox`}>{t("inbox")}</Link>
|
||||
</div>
|
||||
<div className="bg-[#bb3523] py-1 px-3 rounded-full">Update</div>
|
||||
<div className="bg-[#bb3523] py-1 px-3 rounded-full">{t("update")}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-10 px-8 w-[400px] mt-3 border border-black rounded-lg flex flex-col">
|
||||
<h1 className="mb-3 text-lg font-semibold">List Notifikasi</h1>
|
||||
<h1 className="mb-3 text-lg font-semibold">{t("notifList")}</h1>
|
||||
<div className="hover:bg-slate-200 rounded-md">
|
||||
{notifications?.map((list: any) => (
|
||||
<a className="flex flex-row items-center ml-1" href={"/" + list.redirectUrl}>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import withReactContent from "sweetalert2-react-content";
|
|||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Link } from "@/components/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const profileSchema = z.object({
|
||||
password: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -33,6 +34,7 @@ const ChangePassword: React.FC = () => {
|
|||
const MySwal = withReactContent(Swal);
|
||||
const [detail, setDetail] = useState<Detail>();
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
type ProfileSchema = z.infer<typeof profileSchema>;
|
||||
const {
|
||||
|
|
@ -100,86 +102,45 @@ const ChangePassword: React.FC = () => {
|
|||
<div className="w-20 h-20 mx-auto rounded-full bg-red-700 flex items-center justify-center">
|
||||
<span className="text-white text-3xl font-bold">👤</span>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold mt-4">Ubah Profile</h1>
|
||||
<h1 className="text-2xl font-bold mt-4">{t("changePass")}</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-4 mb-8">
|
||||
<Link href={"/profile"}>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">
|
||||
User Profile
|
||||
</button>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("userProfile")}</button>
|
||||
</Link>
|
||||
<Link href={"/profile/change-profile"}>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">
|
||||
Ubah Foto
|
||||
</button>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("changePhoto")}</button>
|
||||
</Link>
|
||||
<Link href={"/profile/change-password"}>
|
||||
<button className="bg-red-700 text-white px-4 py-2 rounded">
|
||||
Ubah Password
|
||||
</button>
|
||||
<button className="bg-red-700 text-white px-4 py-2 rounded">{t("changePass")}</button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="max-w-3xl mx-auto bg-white shadow-sm p-4 rounded">
|
||||
<p className="mb-6 text-gray-600">
|
||||
Silahkan ubah data pribadi Anda pada form berikut.
|
||||
</p>
|
||||
<p className="mb-6 text-gray-600">{t("pleaseChange")}</p>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div>
|
||||
<div className="mb-4">
|
||||
<Label>
|
||||
Password<span className="text-red-500">*</span>
|
||||
{t("password")}
|
||||
<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="password"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="password"
|
||||
defaultValue={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.password?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.password.message}
|
||||
</p>
|
||||
)}
|
||||
<Controller control={control} name="password" render={({ field }) => <Input size="md" type="password" defaultValue={field.value} onChange={field.onChange} placeholder={t("inputPass")} />} />
|
||||
{errors.password?.message && <p className="text-red-400 text-sm">{errors.password.message}</p>}
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<Label>
|
||||
Konfirmasi Password<span className="text-red-500">*</span>
|
||||
{t("confirmPass")}
|
||||
<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="retypePassword"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="password"
|
||||
defaultValue={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.retypePassword?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.retypePassword.message}
|
||||
</p>
|
||||
)}
|
||||
<Controller control={control} name="retypePassword" render={({ field }) => <Input size="md" type="password" defaultValue={field.value} onChange={field.onChange} placeholder={t("samePass")} />} />
|
||||
{errors.retypePassword?.message && <p className="text-red-400 text-sm">{errors.retypePassword.message}</p>}
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="mt-4">
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300"
|
||||
>
|
||||
Simpan
|
||||
<button type="submit" className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300">
|
||||
{t("save")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
import { Link } from "@/components/navigation";
|
||||
import Image from "next/image";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const ChangeProfile: React.FC = () => {
|
||||
const [selectedImage, setSelectedImage] = useState<File | null>(null);
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
|
|
@ -32,35 +34,35 @@ const ChangeProfile: React.FC = () => {
|
|||
<div className="w-20 h-20 mx-auto rounded-full bg-red-700 flex items-center justify-center">
|
||||
<span className="text-white text-3xl font-bold">👤</span>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold mt-4">Ubah Photo</h1>
|
||||
<h1 className="text-2xl font-bold mt-4">{t("changePhoto")}</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-4 mb-8">
|
||||
<Link href={"/profile"}>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">User Profile</button>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("userProfile")}</button>
|
||||
</Link>
|
||||
<Link href={"/profile/change-profile"}>
|
||||
<button className="bg-red-700 text-white px-4 py-2 rounded">Ubah Foto</button>
|
||||
<button className="bg-red-700 text-white px-4 py-2 rounded">{t("changePhoto")}</button>
|
||||
</Link>
|
||||
<Link href={"/profile/change-password"}>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">Ubah Password</button>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("changePass")}</button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="w-80 mx-auto bg-gray-900 text-white shadow-md p-8 rounded">
|
||||
<div className="flex justify-center mb-6">
|
||||
<div className="w-40 h-40 rounded-full border border-gray-300 flex items-center justify-center">
|
||||
{selectedImage ? <Image width={1920} height={1080} src={URL.createObjectURL(selectedImage)} alt="Preview" className="w-full h-full rounded-full object-cover" /> : <span className="text-gray-500">No Image</span>}
|
||||
{selectedImage ? <Image width={1920} height={1080} src={URL.createObjectURL(selectedImage)} alt="Preview" className="w-full h-full rounded-full object-cover" /> : <span className="text-gray-500">{t("noImage")}</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-4">
|
||||
<input type="file" id="upload" accept="image/*" className="hidden" onChange={handleImageChange} />
|
||||
<label htmlFor="upload" className="bg-blue-600 text-white px-4 py-2 rounded cursor-pointer">
|
||||
Ganti Foto
|
||||
{t("changePhoto")}
|
||||
</label>
|
||||
<button onClick={handleDelete} className="border border-red-700 text-red-700 px-4 py-2 rounded">
|
||||
Hapus Foto
|
||||
{t("deletePhoto")}{" "}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -16,15 +16,14 @@ import withReactContent from "sweetalert2-react-content";
|
|||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Link } from "@/components/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const profileSchema = z.object({
|
||||
username: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
fullname: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
memberIdentity: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
email: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
address: z
|
||||
.string()
|
||||
.min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }),
|
||||
address: z.string().min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }),
|
||||
phoneNumber: z.string().min(1, { message: "Kategori diperlukan" }),
|
||||
});
|
||||
|
||||
|
|
@ -45,6 +44,7 @@ const UbahProfile: React.FC = () => {
|
|||
const MySwal = withReactContent(Swal);
|
||||
const [detail, setDetail] = useState<Detail>();
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
type ProfileSchema = z.infer<typeof profileSchema>;
|
||||
const {
|
||||
|
|
@ -117,30 +117,22 @@ const UbahProfile: React.FC = () => {
|
|||
<div className="w-20 h-20 mx-auto rounded-full bg-red-700 flex items-center justify-center">
|
||||
<span className="text-white text-3xl font-bold">👤</span>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold mt-4">Ubah Profile</h1>
|
||||
<h1 className="text-2xl font-bold mt-4">{t("changeProfile")}</h1>
|
||||
</div>
|
||||
<div className="flex justify-center gap-4 mb-8">
|
||||
<Link href={"/profile"}>
|
||||
<button className="bg-red-700 text-white px-4 py-2 rounded">
|
||||
User Profile
|
||||
</button>
|
||||
<button className="bg-red-700 text-white px-4 py-2 rounded">{t("userProfile")}</button>
|
||||
</Link>
|
||||
<Link href={"/profile/change-profile"}>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">
|
||||
Ubah Foto
|
||||
</button>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("changePhoto")}</button>
|
||||
</Link>
|
||||
<Link href={"/profile/change-password"}>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">
|
||||
Ubah Password
|
||||
</button>
|
||||
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("changePass")}</button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="max-w-3xl mx-auto bg-white shadow-sm p-4 rounded">
|
||||
<p className="mb-6 text-gray-600">
|
||||
Silahkan ubah data pribadi Anda pada form berikut.
|
||||
</p>
|
||||
<p className="mb-6 text-gray-600">{t("pleaseChange")}</p>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
{detail !== undefined ? (
|
||||
<div>
|
||||
|
|
@ -148,143 +140,52 @@ const UbahProfile: React.FC = () => {
|
|||
<Label>
|
||||
Username<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
defaultValue={detail?.username}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.username?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.username.message}
|
||||
</p>
|
||||
)}
|
||||
<Controller control={control} name="username" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.username} onChange={field.onChange} placeholder="Enter Title" />} />
|
||||
{errors.username?.message && <p className="text-red-400 text-sm">{errors.username.message}</p>}
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<Label>
|
||||
Nama Lengkap<span className="text-red-500">*</span>
|
||||
{t("fullName")}
|
||||
<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="fullname"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
defaultValue={detail?.fullname}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.fullname?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.fullname.message}
|
||||
</p>
|
||||
)}
|
||||
<Controller control={control} name="fullname" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.fullname} onChange={field.onChange} placeholder="Enter Title" />} />
|
||||
{errors.fullname?.message && <p className="text-red-400 text-sm">{errors.fullname.message}</p>}
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<Label>
|
||||
Nomor Identitas<span className="text-red-500">*</span>
|
||||
{t("identityNumber")}
|
||||
<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="memberIdentity"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
defaultValue={detail?.memberIdentity}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.memberIdentity?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.memberIdentity.message}
|
||||
</p>
|
||||
)}
|
||||
<Controller control={control} name="memberIdentity" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.memberIdentity} onChange={field.onChange} placeholder="Enter Title" />} />
|
||||
{errors.memberIdentity?.message && <p className="text-red-400 text-sm">{errors.memberIdentity.message}</p>}
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<Label>
|
||||
Email<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
defaultValue={detail?.email}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.email?.message && (
|
||||
<p className="text-red-400 text-sm">{errors.email.message}</p>
|
||||
)}
|
||||
<Controller control={control} name="email" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.email} onChange={field.onChange} placeholder="Enter Title" />} />
|
||||
{errors.email?.message && <p className="text-red-400 text-sm">{errors.email.message}</p>}
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<Label>
|
||||
Nomor HP<span className="text-red-500">*</span>
|
||||
{t("number")}
|
||||
<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="phoneNumber"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="number"
|
||||
defaultValue={detail?.phoneNumber}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.phoneNumber?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.phoneNumber.message}
|
||||
</p>
|
||||
)}
|
||||
<Controller control={control} name="phoneNumber" render={({ field }) => <Input size="md" type="number" defaultValue={detail?.phoneNumber} onChange={field.onChange} placeholder="Enter Title" />} />
|
||||
{errors.phoneNumber?.message && <p className="text-red-400 text-sm">{errors.phoneNumber.message}</p>}
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<Label>
|
||||
Alamat<span className="text-red-500">*</span>
|
||||
{t("address")}
|
||||
<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="address"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
defaultValue={detail?.address}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.address?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.address.message}
|
||||
</p>
|
||||
)}
|
||||
<Controller control={control} name="address" render={({ field }) => <Textarea defaultValue={detail?.address} onChange={field.onChange} placeholder="Enter Title" />} />
|
||||
{errors.address?.message && <p className="text-red-400 text-sm">{errors.address.message}</p>}
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="mt-4">
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300"
|
||||
>
|
||||
Simpan
|
||||
<button type="submit" className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300">
|
||||
{t("save")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking"
|
|||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import { checkMaliciousText, formatDateToIndonesian, getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import parse from "html-react-parser";
|
||||
|
|
@ -440,13 +440,18 @@ const DetailVideo = () => {
|
|||
<p className="text-xs lg:text-sm">
|
||||
{t("by")} <span className="font-semibold text-black">{detailDataVideo?.uploadedBy?.userLevel?.name}</span>
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm">
|
||||
{/* <p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")}
|
||||
{detailDataVideo?.updatedAt} WIB |
|
||||
</p> */}
|
||||
<p className="text-xs lg:text-sm">
|
||||
| {t("updatedOn")}
|
||||
{formatDateToIndonesian(new Date(detailDataVideo?.updatedAt))} {"WIB"}
|
||||
</p>
|
||||
<p className="text-xs lg:text-sm flex justify-center items-center">
|
||||
|
|
||||
<Icon icon="formkit:eye" width="15" height="15" />
|
||||
{detailDataVideo?.clickCount}
|
||||
{detailDataVideo?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
|
|
@ -461,7 +466,7 @@ const DetailVideo = () => {
|
|||
<div className="w-full">
|
||||
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8">{detailDataVideo?.title}</h1>
|
||||
<div
|
||||
className="font-light text-justify mb-5 lg:mb-0"
|
||||
className="font-light text-justify mb-5 space-y-4 lg:mb-0"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: detailDataVideo?.htmlDescription,
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ const ContentCategory = (props: { group?: string }) => {
|
|||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<div className="mx-auto px-4 lg:px-20 py-10 max-w-screen-2xl ">
|
||||
<div className="mx-auto px-4 lg:px-24 py-10 max-w-screen-2xl ">
|
||||
<Reveal>
|
||||
<h2 className="text-center text-xl lg:text-2xl font-bold text-[#bb3523] mb-4">
|
||||
{pathname?.split("/")[1] == "in" ? (
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ const Footer = () => {
|
|||
<img src="/assets/icon-privacy.png" alt="Privacy" />
|
||||
<p className="font-semibold text-lg">{t("privacy")}</p>
|
||||
</div>
|
||||
<div className="container text-dark">{parse(String(privacy))}</div>
|
||||
<div className="container text-black space-y-2">{parse(String(privacy))}</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import { useParams, usePathname, useRouter } from "next/navigation";
|
|||
import React, { useEffect, useState } from "react";
|
||||
import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import { getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import { formatDateToIndonesian, getPublicLocaleTimestamp, textEllipsis } from "@/utils/globals";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||
import Image from "next/image";
|
||||
|
||||
const HeaderBannerSatker = () => {
|
||||
const router = useRouter();
|
||||
|
|
@ -26,7 +27,7 @@ const HeaderBannerSatker = () => {
|
|||
// }
|
||||
|
||||
async function fetchData() {
|
||||
const res = await listData("1", "", "", 5, 0, "createdAt", "", "", "satker-"+satkerName);
|
||||
const res = await listData("1", "", "", 5, 0, "createdAt", "", "", "satker-" + satkerName);
|
||||
let data = res?.data?.data?.content;
|
||||
setContent(data);
|
||||
setCenterPadding(`${Math.trunc(Number(window.innerWidth) / 10 + 40)}px`);
|
||||
|
|
@ -70,49 +71,130 @@ const HeaderBannerSatker = () => {
|
|||
};
|
||||
return (
|
||||
<div>
|
||||
{/* Header */}
|
||||
<div className="p-6 lg:px-16 flex flex-col lg:flex-row">
|
||||
{/* Header Left */}
|
||||
<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">
|
||||
{isBannerLoading ? (
|
||||
<SkeletonTheme highlightColor="#f2f2f2">
|
||||
<Skeleton className="w-[100%] h-[480px]" />
|
||||
</SkeletonTheme>
|
||||
) : (
|
||||
<div className="mt-3">
|
||||
<Carousel className="w-full h-full">
|
||||
<CarouselContent>
|
||||
{content?.map((row: any) => (
|
||||
<CarouselItem key={row?.id} className="basis-1/2">
|
||||
<div className="relative h-[310px] lg:h-[420px]">
|
||||
<img src={row?.thumbnailLink} alt="" className="w-full h-[310px] lg:h-[420px] rounded-lg" />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm 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">{row?.categoryName}</span>
|
||||
<Link
|
||||
href={
|
||||
Number(row.fileType?.id) == 1
|
||||
? `${asPath.includes("/satker/") == true ? asPath : ""}/image/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 2
|
||||
? `/video/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 3
|
||||
? `/document/detail/${row.slug}`
|
||||
: `/audio/detail/${row.slug}`
|
||||
}
|
||||
>
|
||||
<h3>{row.title}</h3>
|
||||
</Link>
|
||||
<p className="text-xs flex flex-row items-center gap-1 mt-1 text-white">
|
||||
{getPublicLocaleTimestamp(new Date(row?.createdAt))} WIB {" | "}
|
||||
<Icon icon="formkit:eye" width="15" height="15" /> {row?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
<div className="flex flex-col space-y-3 mx-auto w-full lg:w-2/3">
|
||||
<Skeleton className="h-[310px] lg:h-[420px] rounded-xl" />
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-[250px]" />
|
||||
<Skeleton className="h-4 w-[200px]" />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Carousel className="lg:w-2/3 lg:h-full ">
|
||||
<CarouselContent>
|
||||
{content?.map((row: any) => (
|
||||
<CarouselItem key={row?.id}>
|
||||
<div className="relative h-[310px] lg:h-[420px]">
|
||||
<Image src={row?.thumbnailLink} alt="" width={1920} height={1080} 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-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">{row?.categoryName}</span>
|
||||
<Link
|
||||
href={
|
||||
Number(row.fileType?.id) == 1
|
||||
? `${asPath.includes("/satker/") == true ? asPath : ""}/image/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 2
|
||||
? `/video/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 3
|
||||
? `/document/detail/${row.slug}`
|
||||
: `/audio/detail/${row.slug}`
|
||||
}
|
||||
>
|
||||
<h3>{row.title}</h3>
|
||||
</Link>
|
||||
<p className="text-xs flex flex-row items-center gap-1 mt-1 text-white">
|
||||
{getPublicLocaleTimestamp(new Date(row?.createdAt))} WIB {" | "}
|
||||
<Icon icon="formkit:eye" width="15" height="15" /> {row?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
)}
|
||||
|
||||
{/* Section Kanan */}
|
||||
<div>
|
||||
{isBannerLoading ? (
|
||||
<>
|
||||
<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="items-center hidden md:block gap-4 max-w-sm mx-auto mb-3 lg:flex">
|
||||
<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="hidden md:block items-center gap-4 max-w-sm mx-auto mb-3 lg:flex">
|
||||
<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="hidden md:block items-center gap-4 max-w-sm mx-auto mb-3 lg:flex">
|
||||
<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="hidden md:block items-center gap-4 max-w-sm mx-auto lg:flex">
|
||||
<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">
|
||||
{content?.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">
|
||||
<Image width={720} height={480} 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={
|
||||
Number(item?.fileType?.id) == 1
|
||||
? `${asPath.includes("/satker/") == true ? asPath : ""}/image/detail/${item?.slug}`
|
||||
: Number(item?.fileType?.id) == 2
|
||||
? `/video/detail/${item?.slug}`
|
||||
: Number(item?.fileType?.id) == 3
|
||||
? `/document/detail/${item?.slug}`
|
||||
: `/audio/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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import { useParams, usePathname, useRouter } from "next/navigation";
|
|||
import React, { useEffect, useState } from "react";
|
||||
import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import { getPublicLocaleTimestamp } from "@/utils/globals";
|
||||
import { formatDateToIndonesian, getPublicLocaleTimestamp, textEllipsis } from "@/utils/globals";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||
import Image from "next/image";
|
||||
|
||||
const HeaderBanner = () => {
|
||||
const router = useRouter();
|
||||
|
|
@ -14,7 +15,6 @@ const HeaderBanner = () => {
|
|||
const poldaName: any = params?.polda_name;
|
||||
const asPath: any = usePathname();
|
||||
const [content, setContent] = useState([]);
|
||||
|
||||
const [isBannerLoading, setIsBannerLoading] = useState(true);
|
||||
const [centerPadding, setCenterPadding] = useState<any>();
|
||||
|
||||
|
|
@ -70,49 +70,130 @@ const HeaderBanner = () => {
|
|||
};
|
||||
return (
|
||||
<div>
|
||||
{/* Header */}
|
||||
<div className="p-6 lg:px-16 flex flex-col lg:flex-row">
|
||||
{/* Header Left */}
|
||||
<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">
|
||||
{isBannerLoading ? (
|
||||
<SkeletonTheme highlightColor="#f2f2f2">
|
||||
<Skeleton className="w-[100%] h-[480px]" />
|
||||
</SkeletonTheme>
|
||||
) : (
|
||||
<div className="mt-3">
|
||||
<Carousel className="w-full h-full">
|
||||
<CarouselContent>
|
||||
{content?.map((row: any) => (
|
||||
<CarouselItem key={row?.id} className="basis-1/2">
|
||||
<div className="relative h-[310px] lg:h-[420px]">
|
||||
<img src={row?.thumbnailLink} alt="" className="w-full h-[310px] lg:h-[420px] rounded-lg" />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm 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">{row?.categoryName}</span>
|
||||
<Link
|
||||
href={
|
||||
Number(row.fileType?.id) == 1
|
||||
? `${asPath.includes("/polda/") == true ? asPath : ""}/image/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 2
|
||||
? `/video/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 3
|
||||
? `/document/detail/${row.slug}`
|
||||
: `/audio/detail/${row.slug}`
|
||||
}
|
||||
>
|
||||
<h3>{row.title}</h3>
|
||||
</Link>
|
||||
<p className="text-xs flex flex-row items-center gap-1 mt-1 text-white">
|
||||
{getPublicLocaleTimestamp(new Date(row?.createdAt))} WIB {" | "}
|
||||
<Icon icon="formkit:eye" width="15" height="15" /> {row?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
<div className="flex flex-col space-y-3 mx-auto w-full lg:w-2/3">
|
||||
<Skeleton className="h-[310px] lg:h-[420px] rounded-xl" />
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-[250px]" />
|
||||
<Skeleton className="h-4 w-[200px]" />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Carousel className="lg:w-2/3 lg:h-full ">
|
||||
<CarouselContent>
|
||||
{content?.map((row: any) => (
|
||||
<CarouselItem key={row?.id}>
|
||||
<div className="relative h-[310px] lg:h-[420px]">
|
||||
<Image src={row?.thumbnailLink} alt="" width={1920} height={1080} className="w-full h-[310px] lg:h-full rounded-lg object-cover" />
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm 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">{row?.categoryName}</span>
|
||||
<Link
|
||||
href={
|
||||
Number(row.fileType?.id) == 1
|
||||
? `${asPath.includes("/polda/") == true ? asPath : ""}/image/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 2
|
||||
? `/video/detail/${row.slug}`
|
||||
: Number(row.fileType?.id) == 3
|
||||
? `/document/detail/${row.slug}`
|
||||
: `/audio/detail/${row.slug}`
|
||||
}
|
||||
>
|
||||
<h3>{row.title}</h3>
|
||||
</Link>
|
||||
<p className="text-xs flex flex-row items-center gap-1 mt-1 text-white">
|
||||
{getPublicLocaleTimestamp(new Date(row?.createdAt))} WIB {" | "}
|
||||
<Icon icon="formkit:eye" width="15" height="15" /> {row?.clickCount}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
)}
|
||||
|
||||
{/* Header Right */}
|
||||
<div>
|
||||
{isBannerLoading ? (
|
||||
<>
|
||||
<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="items-center hidden md:block gap-4 max-w-sm mx-auto mb-3 lg:flex">
|
||||
<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="hidden md:block items-center gap-4 max-w-sm mx-auto mb-3 lg:flex">
|
||||
<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="hidden md:block items-center gap-4 max-w-sm mx-auto mb-3 lg:flex">
|
||||
<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="hidden md:block items-center gap-4 max-w-sm mx-auto lg:flex">
|
||||
<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">
|
||||
{content?.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">
|
||||
<Image width={720} height={480} 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={
|
||||
Number(item?.fileType?.id) == 1
|
||||
? `${asPath.includes("/polda/") == true ? asPath : ""}/image/detail/${item?.slug}`
|
||||
: Number(item?.fileType?.id) == 2
|
||||
? `/video/detail/${item?.slug}`
|
||||
: Number(item?.fileType?.id) == 3
|
||||
? `/document/detail/${item?.slug}`
|
||||
: `/audio/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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { Link } from "@/i18n/routing";
|
|||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { getInfoProfile, getListPorvinces, getUsersTeams } from "@/service/landing/landing";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const HeaderManagement = () => {
|
||||
const [profile, setProfile] = useState<any>();
|
||||
|
|
@ -12,6 +13,7 @@ const HeaderManagement = () => {
|
|||
const [, setUser] = useState();
|
||||
const [selectedTab, setSelectedTab] = useState("video");
|
||||
const params = useParams();
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
// const currentRoute = router.pathname;
|
||||
// const profilePicture = Cookies.get("profile_picture");
|
||||
|
|
@ -67,24 +69,24 @@ const HeaderManagement = () => {
|
|||
return (
|
||||
<div>
|
||||
{/* Header */}
|
||||
<div className="bg-[#504e52] p-10 lg:p-12">
|
||||
<div className="bg-[#cccccc] p-5 lg:p-8">
|
||||
<div className="flex flex-col lg:flex-row justify-center lg:justify-between mx-6 lg:mx-10">
|
||||
<div className="flex items-center gap-2 ">
|
||||
<img src="/assets/avatar-profile.png" alt="avatar" className="w-14 h-14" />
|
||||
<img src="/assets/gg-profile.png" alt="avatar" className="w-14 h-14" />
|
||||
<div className="flex flex-col mx-2">
|
||||
<p className="text-white text-sm font-semibold">{profile?.fullname}</p>
|
||||
<p className="text-white text-sm font-light">{profile?.username}</p>
|
||||
<p className="text-white text-sm font-light">
|
||||
Aktif Sejak
|
||||
<p className="text-black text-sm font-semibold">{profile?.fullname}</p>
|
||||
<p className="text-black text-sm font-light">{profile?.username}</p>
|
||||
<p className="text-black text-sm font-light">
|
||||
{t("activeSince")}
|
||||
{`${new Date(profile?.createdAt).getDate()}/${new Date(profile?.createdAt).getMonth() + 1}/${new Date(profile?.createdAt).getFullYear()} ${new Date(profile?.createdAt).getHours()}:${new Date(
|
||||
profile?.createdAt
|
||||
).getMinutes()}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Link href="/profile" className="flex justify-center items-center text-white gap-2 mt-3 lg:mt-0">
|
||||
<Icon icon="tdesign:setting-1-filled" />
|
||||
<p className="text-sm lg:text-base">Pengaturan</p>
|
||||
<Link href="/profile" className="flex justify-center items-center text-black gap-2 mt-3 lg:mt-0">
|
||||
<p className="text-sm lg:text-base">{t("fullProfile")}</p>
|
||||
<Icon icon="ri:arrow-right-s-line" className="h-5 w-5" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -486,12 +486,12 @@ const Navbar = () => {
|
|||
<DropdownMenuGroup>
|
||||
{[
|
||||
{
|
||||
name: "Profile & Settings",
|
||||
name: t("profileSetting"),
|
||||
icon: "heroicons:user",
|
||||
href: "/profile",
|
||||
},
|
||||
{
|
||||
name: "Kelola Konten",
|
||||
name: t("contentManagement"),
|
||||
icon: "stash:save-ribbon-duotone",
|
||||
href: "/content-management/galery",
|
||||
},
|
||||
|
|
@ -1058,12 +1058,12 @@ const Navbar = () => {
|
|||
<DropdownMenuGroup>
|
||||
{[
|
||||
{
|
||||
name: "Profile & Settings",
|
||||
name: t("profileSetting"),
|
||||
icon: "heroicons:user",
|
||||
href: "/profile",
|
||||
},
|
||||
{
|
||||
name: "Kelola Konten",
|
||||
name: t("contentManagement"),
|
||||
icon: "stash:save-ribbon-duotone",
|
||||
href: "/content-management/galery",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { getInfoProfile, getListPorvinces, getUsersTeams } from "@/service/landi
|
|||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const SidebarManagement = () => {
|
||||
const [profile, setProfile] = useState<any>();
|
||||
|
|
@ -13,6 +14,7 @@ const SidebarManagement = () => {
|
|||
const [selectedTab, setSelectedTab] = useState("video");
|
||||
const params = useParams();
|
||||
const pathname = usePathname();
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
// const currentRoute = router.pathname;
|
||||
// const profilePicture = Cookies.get("profile_picture");
|
||||
|
|
@ -67,7 +69,7 @@ const SidebarManagement = () => {
|
|||
return (
|
||||
<div className="p-4 lg:p-12 w-full lg:w-1/3 ">
|
||||
<div className="border rounded-2xl border-black m-4">
|
||||
<h1 className="text-xl p-5">Tentang Saya</h1>
|
||||
<h1 className="text-xl p-5">{t("aboutMe")}</h1>
|
||||
<div>
|
||||
<ul className="px-10 mb-4">
|
||||
<li className="mb-5 font-light">
|
||||
|
|
@ -75,19 +77,19 @@ const SidebarManagement = () => {
|
|||
<p>{profile?.email}</p>
|
||||
</li>
|
||||
<li className="mb-5 font-light">
|
||||
<p className="font-semibold">No Handphone :</p>
|
||||
<p className="font-semibold">{t("number")} :</p>
|
||||
<p>{profile?.phoneNumber}</p>
|
||||
</li>
|
||||
<li className="mb-5 font-light">
|
||||
<p className="font-semibold">Alamat :</p>
|
||||
<p className="font-semibold">{t("address")} :</p>
|
||||
<p>{profile?.address}</p>
|
||||
</li>
|
||||
<li className="mb-5 font-light">
|
||||
<p className="font-semibold">Kategori :</p>
|
||||
<p className="font-semibold">{t("category")} :</p>
|
||||
<p>{profile?.institute?.categoryRole?.name}</p>
|
||||
</li>
|
||||
<li className="mb-5 font-light">
|
||||
<p className="font-semibold">Instansi/Perusahaan :</p>
|
||||
<p className="font-semibold">{t("company")} :</p>
|
||||
<p>{profile?.institute?.name}</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -99,7 +101,9 @@ const SidebarManagement = () => {
|
|||
<div className={`${pathname?.includes("/content-management/galery") ? "bg-slate-500 text-white" : ""} hover:bg-slate-500 hover:text-white cursor-pointer p-4 rounded-lg flex justify-between`}>
|
||||
<div className="flex items-center gap-2 text-lg">
|
||||
<Icon icon="material-symbols-light:perm-media-rounded" />
|
||||
<p className="text-sm">Galeri {profile?.institute?.name}</p>
|
||||
<p className="text-sm">
|
||||
{t("gallery")} {profile?.institute?.name}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
|
|
@ -110,7 +114,7 @@ const SidebarManagement = () => {
|
|||
<div className={`${pathname?.includes("/content-management/download") ? "bg-slate-500 text-white" : ""} hover:bg-slate-500 hover:text-white cursor-pointer p-4 rounded-lg flex justify-between`}>
|
||||
<div className="flex items-center gap-2 text-lg">
|
||||
<Icon icon="heroicons:photo-solid" />
|
||||
<p className="text-sm">Galeri Saya</p>
|
||||
<p className="text-sm">{t("myGallery")} </p>
|
||||
</div>
|
||||
<div>
|
||||
<Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
|
|
@ -121,7 +125,7 @@ const SidebarManagement = () => {
|
|||
<div className={`${pathname?.includes("/content-management/rewrite") ? "bg-slate-500 text-white" : ""} hover:bg-slate-500 hover:text-white cursor-pointer p-4 rounded-lg flex justify-between`}>
|
||||
<div className="flex items-center gap-2 text-lg">
|
||||
<Icon icon="material-symbols-light:perm-media-rounded" />
|
||||
<p className="text-sm">Galeri Rewrite</p>
|
||||
<p className="text-sm">{t("gallery")} Rewrite</p>
|
||||
</div>
|
||||
<div>
|
||||
<Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
|
|
@ -132,7 +136,7 @@ const SidebarManagement = () => {
|
|||
<div className={`${pathname?.includes("/content-management/users") ? "bg-slate-500 text-white" : ""} hover:bg-slate-500 hover:text-white cursor-pointer p-4 rounded-lg flex justify-between`}>
|
||||
<div className="flex items-center gap-2 text-lg">
|
||||
<Icon icon="mdi:users-group" />
|
||||
<p className="text-sm">Tim Pengguna</p>
|
||||
<p className="text-sm">{t("userTeam")}</p>
|
||||
</div>
|
||||
<div>
|
||||
<Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import React, { useEffect, useState } from "react";
|
|||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
import { FiFile, FiImage, FiMusic, FiYoutube } from "react-icons/fi";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Input } from "../ui/input";
|
||||
|
||||
const WelcomePolda = () => {
|
||||
const router = useRouter();
|
||||
|
|
@ -10,7 +12,7 @@ const WelcomePolda = () => {
|
|||
const params = useParams();
|
||||
const poldaName: any = params?.polda_name;
|
||||
const [categorySelect, setCategorySelect] = useState("0");
|
||||
const [search, setSearch] = useState();
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
useEffect(() => {
|
||||
function initState() {
|
||||
|
|
@ -25,11 +27,11 @@ const WelcomePolda = () => {
|
|||
<div className="max-w-screen-xl mx-auto text-center">
|
||||
{/* Heading */}
|
||||
<h1 className="text-2xl md:text-3xl font-bold text-gray-800 dark:text-white">
|
||||
Selamat Datang di <span className="text-[#bb3523] dark:text-white">Polda</span> <span className="capitalize">{poldaName.replace("-", " ")}</span>
|
||||
{t("welcome")} <span className="text-[#bb3523] dark:text-white">Polda</span> <span className="capitalize">{poldaName.replace("-", " ")}</span>
|
||||
</h1>
|
||||
<div className="w-[80%] h-1 bg-[#bb3523] mx-auto mt-2"></div>
|
||||
<p className="text-sm md:text-base text-gray-500 dark:text-gray-100 mt-4">
|
||||
Liputan resmi yang bersumber dari kegiatan Polri di Polda <span className="capitalize">{poldaName.replace("-", " ")}</span>
|
||||
{t("polda")} <span className="capitalize">{poldaName.replace("-", " ")}</span>
|
||||
</p>
|
||||
|
||||
{/* Search Form */}
|
||||
|
|
@ -45,7 +47,7 @@ const WelcomePolda = () => {
|
|||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
Konten
|
||||
{t("content")}
|
||||
<svg className="flex items-center justify-center" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" fill-rule="evenodd" d="m6 7l6 6l6-6l2 2l-8 8l-8-8z" />
|
||||
</svg>
|
||||
|
|
@ -55,25 +57,25 @@ const WelcomePolda = () => {
|
|||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700c flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiYoutube className="mr-2" />
|
||||
Audio Visual
|
||||
{t("video")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700 flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiMusic className="mr-2" />
|
||||
Audio
|
||||
{t("audio")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700 flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiImage className="mr-2" />
|
||||
Foto
|
||||
{t("image")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700 flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiFile className="mr-2" />
|
||||
Teks
|
||||
{t("text")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
|
|
@ -87,15 +89,13 @@ const WelcomePolda = () => {
|
|||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" placeholder="Pencarian" className="w-full py-2 px-2 text-sm text-gray-700 dark:text-gray-100 focus:outline-none" />
|
||||
<Input type="text" placeholder={t("search")} className="w-full py-2 px-2 text-sm text-gray-700 dark:text-gray-100 focus:outline-none" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search Input */}
|
||||
|
||||
{/* Button */}
|
||||
<button className="flex justify-center items-center px-6 w-full lg:w-[20%] py-2 bg-[#bb3523] gap-2 text-white rounded-lg hover:bg-red-700">
|
||||
Cari Liputan <Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
{t("searchCoverage")} <Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import React, { useEffect, useState } from "react";
|
|||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
import { FiFile, FiImage, FiMusic, FiYoutube } from "react-icons/fi";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { capitalize } from "@/utils/globals";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const WelcomeSatker = () => {
|
||||
const router = useRouter();
|
||||
|
|
@ -13,7 +13,7 @@ const WelcomeSatker = () => {
|
|||
const params = useParams();
|
||||
const satkerName: any = params?.satker_name;
|
||||
const [categorySelect, setCategorySelect] = useState("0");
|
||||
const [search, setSearch] = useState();
|
||||
const t = useTranslations("LandingPage");
|
||||
|
||||
useEffect(() => {
|
||||
function initState() {
|
||||
|
|
@ -28,11 +28,11 @@ const WelcomeSatker = () => {
|
|||
<div className="max-w-screen-xl mx-auto text-center">
|
||||
{/* Heading */}
|
||||
<h1 className="text-2xl md:text-3xl font-bold text-gray-800 dark:text-white">
|
||||
Selamat Datang di <span className="text-[#bb3523] dark:text-white">Satker</span> <span className="capitalize">{satkerName.replace("-", " ")}</span>
|
||||
{t("welcome")} <span className="text-[#bb3523] dark:text-white">Satker</span> <span className="capitalize">{satkerName.replace("-", " ")}</span>
|
||||
</h1>
|
||||
<div className="w-[80%] h-1 bg-[#bb3523] mx-auto mt-2"></div>
|
||||
<p className="text-sm md:text-base text-gray-500 dark:text-gray-100 mt-4">
|
||||
Liputan resmi yang bersumber dari kegiatan Polri di Satker <span className="capitalize">{satkerName.replace("-", " ")}</span>
|
||||
{t("satker")} <span className="capitalize">{satkerName.replace("-", " ")}</span>
|
||||
</p>
|
||||
|
||||
{/* Search Form */}
|
||||
|
|
@ -48,7 +48,7 @@ const WelcomeSatker = () => {
|
|||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
Konten
|
||||
{t("content")}
|
||||
<svg className="flex items-center justify-center" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" fill-rule="evenodd" d="m6 7l6 6l6-6l2 2l-8 8l-8-8z" />
|
||||
</svg>
|
||||
|
|
@ -58,25 +58,25 @@ const WelcomeSatker = () => {
|
|||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700c flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiYoutube className="mr-2" />
|
||||
Audio Visual
|
||||
{t("video")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700 flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiMusic className="mr-2" />
|
||||
Audio
|
||||
{t("audio")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700 flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiImage className="mr-2" />
|
||||
Foto
|
||||
{t("image")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||
<span className="text-default-700 flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiFile className="mr-2" />
|
||||
Teks
|
||||
{t("text")}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
|
|
@ -90,15 +90,13 @@ const WelcomeSatker = () => {
|
|||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" placeholder="Pencarian" className="w-full py-2 px-2 text-sm text-gray-700 dark:text-gray-100 focus:outline-none" />
|
||||
<input type="text" placeholder={t("search")} className="w-full py-2 px-2 text-sm text-gray-700 dark:text-gray-100 focus:outline-none" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search Input */}
|
||||
|
||||
{/* Button */}
|
||||
<button className="flex justify-center items-center px-6 w-full lg:w-[20%] py-2 bg-[#bb3523] gap-2 text-white rounded-lg hover:bg-red-700">
|
||||
Cari Liputan <Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
{t("searchCoverage")} <Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -454,7 +454,70 @@
|
|||
"addressInst": "Input the complete address of your institution",
|
||||
"identityEmpty": "Identity number cannot be empty",
|
||||
"policeNumber": "Police Registration Number",
|
||||
"breakingNews": "BREAKING NEWS"
|
||||
"breakingNews": "BREAKING NEWS",
|
||||
"changeProfile": "Change Profile",
|
||||
"userProfile": "User Profile",
|
||||
"changePhoto": "Change Photo",
|
||||
"changePass": "Change Password",
|
||||
"pleaseChange": "Please change your personal data in the following form.",
|
||||
"identityNumber": "Identity Number",
|
||||
"noImage": "No Image",
|
||||
"deletePhoto": "Delete Photo",
|
||||
"activeSince": "Active since",
|
||||
"fullProfile": "View full profile",
|
||||
"aboutMe": "About Me",
|
||||
"company": "Agency/Company",
|
||||
"gallery": "Gallery",
|
||||
"myGallery": "My Gallery",
|
||||
"userTeam": "User Team",
|
||||
"my": "My",
|
||||
"team": "Team",
|
||||
"teamMembers": "Team Members",
|
||||
"reasonReport": "Reasons for Reporting Account",
|
||||
"saveData": "Save Data ?",
|
||||
"language": "Language",
|
||||
"selectLanguage": "Select Language",
|
||||
"contextType": "Context Type",
|
||||
"selectContext": "Select Context",
|
||||
"article": "Article",
|
||||
"transcript": "Transcript",
|
||||
"writingStyle": "Writing Style",
|
||||
"selectWriting": "Select Writing Style",
|
||||
"articleSize": "Article Size",
|
||||
"selectSize": "Select Size",
|
||||
"title": "Title",
|
||||
"mainKeyword": "Main Keyword",
|
||||
"newDescription": "New Description",
|
||||
"back": "Back",
|
||||
"notifList": "Notification List",
|
||||
"userFeedback": "User Feedback",
|
||||
"ratings": "Please provide your rating regarding the ease of access to the MediaHUB Polri website.",
|
||||
"ratings2": "Please give your rating regarding the appearance of the MediaHUB Polri website.",
|
||||
"ratings3": "Please give your rating regarding the content of MediaHUB Polri",
|
||||
"contactUs": "Contact Us",
|
||||
"writeMessage": "Write a Message",
|
||||
"leaveMessage": "Please leave your message in the column provided",
|
||||
"name": "Name",
|
||||
"subject": "Subject",
|
||||
"selectSubject": "Select Subject",
|
||||
"question": "Question",
|
||||
"criticism": "Criticism",
|
||||
"suggestion": "Suggestion",
|
||||
"messages": "Messages",
|
||||
"profileSetting": "Profile & Settings",
|
||||
"enterName": "Enter your full name",
|
||||
"writeYourMessage": "Write your message",
|
||||
"question1": "WHAT CONTENT IS ON MEDIAHUB AND WHAT CATEGORIES ARE THERE IN IT?",
|
||||
"answer1": "MediaHub has a variety of content such as news, videos, and documents categorized into topics such as education, entertainment, and current affairs.",
|
||||
"question2": "HOW CAN MEDIAHUB CONTENT BE DOWNLOADED?",
|
||||
"answer2": "You can download content by clicking the download button available on each content on the MediaHub page.",
|
||||
"question3": "WHO CAN REGISTER AS A MEDIAHUB USER?",
|
||||
"answer3": "Anyone who has an interest in the content on MediaHub can register as a user, either for personal or professional purposes.",
|
||||
"question4": "WHAT IS MEDIAHUB? AND WHAT ARE THE FEATURES IN IT?",
|
||||
"answer4": "MediaHub is a platform that provides various informative and educational content. Key features include search, download, and personalization of content.",
|
||||
"welcome": "Welcome To",
|
||||
"polda": "Official coverage sourced from Polri activities at Polda",
|
||||
"satker": "Official coverage sourced from Polri activities at Satker"
|
||||
},
|
||||
"FilterPage": {
|
||||
"image": "Image",
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@
|
|||
"updatedOn": "Diupdate pada",
|
||||
"creator": "Kreator :",
|
||||
"delete": "Hapus",
|
||||
"imageSize": "Opsi Ukuran Poto",
|
||||
"imageSize": "Opsi Ukuran Foto",
|
||||
"downloadAll": "Download Semua File?",
|
||||
"share": "Bagikan",
|
||||
"shareTo": "Bagikan ke Email",
|
||||
|
|
@ -409,7 +409,7 @@
|
|||
"fullName": "Nama Lengkap",
|
||||
"enterFullName": "Masukkan Nama Lengkap Anda",
|
||||
"enterUsername": "Masukkan Username Anda",
|
||||
"number": "Nomor Telepon",
|
||||
"number": "Nomor Handphone",
|
||||
"enterNumber": "Masukkan Nomor Telepon Anda",
|
||||
"enterEmail": "Masukkan Email Anda",
|
||||
"address": "Alamat",
|
||||
|
|
@ -454,8 +454,70 @@
|
|||
"addressInst": "Masukkan Alamat lengkap institusi anda",
|
||||
"identityEmpty": "Nomor identitas tidak boleh kosong",
|
||||
"policeNumber": "Nomor Registrasi Polri (NRP)",
|
||||
"breakingNews": "BERITA TERKINI"
|
||||
|
||||
"breakingNews": "BERITA TERKINI",
|
||||
"changeProfile": "Ubah Profil",
|
||||
"userProfile": "Profil Pengguna",
|
||||
"changePhoto": "Ubah Foto",
|
||||
"changePass": "Ubah Password",
|
||||
"pleaseChange": "Silahkan ubah data pribadi Anda pada form berikut.",
|
||||
"identityNumber": "Nomor Identitas",
|
||||
"noImage": "Tanpa Foto",
|
||||
"deletePhoto": "Hapus Foto",
|
||||
"activeSince": "Aktif Sejak",
|
||||
"fullProfile": "Lihat profil lengkap",
|
||||
"aboutMe": "Tentang Saya",
|
||||
"company": "Instansi/Perusahaan",
|
||||
"gallery": "Galeri",
|
||||
"myGallery": "Galeri Saya",
|
||||
"userTeam": "Tim Pengguna",
|
||||
"my": "Saya",
|
||||
"team": "Tim",
|
||||
"teamMembers": "Anggota Tim",
|
||||
"reasonReport": "Alasan Report Akun",
|
||||
"saveData": "Simpan Data ?",
|
||||
"language": "Bahasa",
|
||||
"selectLanguage": "Pilih Bahasa",
|
||||
"contextType": "Jenis Konteks",
|
||||
"selectContext": "Pilih Konteks",
|
||||
"article": "Artikel",
|
||||
"transcript": "Transkrip",
|
||||
"writingStyle": "Gaya Penulisan",
|
||||
"selectWriting": "Pilih Gaya Penulisan",
|
||||
"articleSize": "Ukuran Artikel",
|
||||
"selectSize": "Pilih Ukuran Artikel",
|
||||
"title": "Judul",
|
||||
"mainKeyword": "Kata Kunci",
|
||||
"newDescription": "Deskripsi Baru",
|
||||
"back": "Kembali",
|
||||
"notifList": "List Notifikasi",
|
||||
"userFeedback": "Feedback Pengguna",
|
||||
"ratings": "Silakan berikan rating Anda terkait dengan kemudahan akses website MediaHUB Polri.",
|
||||
"ratings2": "Silakan berikan rating Anda terkait dengan tampilan website MediaHUB Polri.",
|
||||
"ratings3": "Silahkan berikan rating Anda terkait dengan konten MediaHUB Polri.",
|
||||
"contactUs": "Hubungi Kami",
|
||||
"writeMessage": "Tulis Pesan",
|
||||
"leaveMessage": "Silahkan tinggalkan pesan Anda pada kolom yang tersedia.",
|
||||
"name": "Nama",
|
||||
"subject": "Subjek",
|
||||
"selectSubject": "Pilih Subjek",
|
||||
"question": "Pertanyaan",
|
||||
"criticism": "Kritik",
|
||||
"suggestion": "Saran",
|
||||
"messages": "Pesan",
|
||||
"profileSetting": "Profil & Pengaturan",
|
||||
"enterName": "Masukkan Nama Lengkap Anda",
|
||||
"writeYourMessage": "Write your message",
|
||||
"question1": "APA SAJA KONTEN-KONTEN YANG ADA DI MEDIAHUB DAN KATEGORI DI DALAMNYA?",
|
||||
"answer1": "MediaHub memiliki beragam konten seperti berita, video, dan dokumen yang dikategorikan dalam topik seperti edukasi, hiburan, dan informasi terkini.",
|
||||
"question2": "BAGAIMANA KONTEN DARI MEDIAHUB DAPAT DIUNDUH?",
|
||||
"answer2": "Anda dapat mengunduh konten dengan klik tombol unduh yang tersedia pada setiap konten di halaman MediaHub.",
|
||||
"question3": "SIAPA SAJA YANG DAPAT MENDAFTARKAN DIRI SEBAGAI PENGGUNA MEDIAHUB?",
|
||||
"answer3": "Semua orang yang memiliki minat terhadap konten di MediaHub dapat mendaftar sebagai pengguna, baik untuk personal maupun profesional.",
|
||||
"question4": "APA ITU MEDIAHUB? DAN APA SAJA FITUR YANG ADA DI DALAMNYA?",
|
||||
"answer4": "MediaHub adalah platform yang menyediakan berbagai konten informatif dan edukatif. Fitur utama meliputi pencarian, pengunduhan, dan personalisasi konten.",
|
||||
"welcome": "Selamat Datang di",
|
||||
"polda": "Liputan resmi yang bersumber dari kegiatan Polri di Polda",
|
||||
"satker": "Liputan resmi yang bersumber dari kegiatan Polri di Satker"
|
||||
},
|
||||
"FilterPage": {
|
||||
"image": "Foto",
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 812 B |
|
|
@ -63,6 +63,11 @@ export async function getProfile(token: any) {
|
|||
return httpGetInterceptorWithToken(url, token);
|
||||
}
|
||||
|
||||
export async function getSubjects() {
|
||||
const url = 'inbox/subjects';
|
||||
return httpGetInterceptor( url );
|
||||
}
|
||||
|
||||
export async function getInfoProfile() {
|
||||
const url = "users/info";
|
||||
return httpGetInterceptor(url);
|
||||
|
|
|
|||
|
|
@ -200,3 +200,8 @@ export async function deleteBlogComments(slug: any) {
|
|||
const url = `blog/comments?id=${slug}`;
|
||||
return httpDeleteInterceptor(url);
|
||||
}
|
||||
|
||||
export async function sendMessage(data: any) {
|
||||
const url = 'inbox';
|
||||
return httpPostInterceptor( url, data );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,7 @@ export const generateLocalizedPath = (href: string, locale: string): string => {
|
|||
return `/${locale}${href}`;
|
||||
};
|
||||
|
||||
export function textEllipsis(
|
||||
str: string,
|
||||
maxLength: number,
|
||||
{ side = "end", ellipsis = "..." } = {}
|
||||
) {
|
||||
export function textEllipsis(str: string, maxLength: number, { side = "end", ellipsis = "..." } = {}) {
|
||||
if (str !== undefined && str?.length > maxLength) {
|
||||
switch (side) {
|
||||
case "start":
|
||||
|
|
@ -27,7 +23,7 @@ export function textEllipsis(
|
|||
|
||||
export function formatDateToIndonesian(d: Date) {
|
||||
try {
|
||||
const dateString = format(d, "d MMMM yyyy HH:mm", { locale: id });
|
||||
const dateString = format(d, "d/MM/yy HH:mm", { locale: id });
|
||||
return dateString;
|
||||
} catch (error) {
|
||||
return "";
|
||||
|
|
@ -64,6 +60,14 @@ export function getOnlyDate(date: Date) {
|
|||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
export function getOnlyDateSlash(date: Date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
|
||||
return `${day}/${month}/${year}`;
|
||||
}
|
||||
|
||||
export function getOnlyMonthAndYear(d: Date) {
|
||||
const pad = (n: any, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
||||
return `${pad(d.getMonth() + 1)}/${pad(d.getFullYear(), 4)}`;
|
||||
|
|
@ -71,10 +75,7 @@ export function getOnlyMonthAndYear(d: Date) {
|
|||
|
||||
export function getPublicLocaleTimestamp(d: any) {
|
||||
const pad = (n: any, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
||||
return `${pad(d.getDate())}/${pad(d.getMonth() + 1)}/${pad(
|
||||
d.getFullYear(),
|
||||
4
|
||||
)} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
||||
return `${pad(d.getDate())}/${pad(d.getMonth() + 1)}/${pad(d.getFullYear(), 4)} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
||||
}
|
||||
|
||||
export function capitalize(s: any) {
|
||||
|
|
@ -87,13 +88,9 @@ export function capitalize(s: any) {
|
|||
}
|
||||
|
||||
export function getLocaleTimestamp(d: Date): string {
|
||||
const pad = (n: number, s: number = 2): string =>
|
||||
`${new Array(s).fill(0)}${n}`.slice(-s);
|
||||
const pad = (n: number, s: number = 2): string => `${new Array(s).fill(0)}${n}`.slice(-s);
|
||||
|
||||
return `${pad(d.getDate())}-${pad(d.getMonth() + 1)}-${pad(
|
||||
d.getFullYear(),
|
||||
4
|
||||
)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||
return `${pad(d.getDate())}-${pad(d.getMonth() + 1)}-${pad(d.getFullYear(), 4)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||
}
|
||||
|
||||
export function getLocaleTime(d: Date) {
|
||||
|
|
@ -102,9 +99,7 @@ export function getLocaleTime(d: Date) {
|
|||
}
|
||||
export function getTimestamp(d: Date) {
|
||||
const pad = (n: any, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
||||
return `${pad(d.getFullYear(), 4)}-${pad(d.getMonth() + 1)}-${pad(
|
||||
d.getDate()
|
||||
)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||
return `${pad(d.getFullYear(), 4)}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||
}
|
||||
|
||||
export function secondToTimes(sec: number) {
|
||||
|
|
@ -118,10 +113,7 @@ export function secondToTimes(sec: number) {
|
|||
|
||||
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 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";
|
||||
|
|
|
|||
Loading…
Reference in New Issue