feat:update data tableu,menu sidebar polda
This commit is contained in:
commit
9d948c8fb6
|
|
@ -592,7 +592,7 @@ const DetailAudio = () => {
|
||||||
<div className="text-gray-500 flex flex-col lg:flex-row justify-between items-center border-t mt-4">
|
<div className="text-gray-500 flex flex-col lg:flex-row justify-between items-center border-t mt-4">
|
||||||
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
||||||
<p className="text-xs lg:text-sm">
|
<p className="text-xs lg:text-sm">
|
||||||
{t("by")} <span className="font-semibold text-black">{detailDataAudio?.uploadedBy?.userLevel?.name}</span>
|
{t("by")} <span className="font-semibold text-black dark:text-white">{detailDataAudio?.uploadedBy?.userLevel?.name}</span>
|
||||||
</p>
|
</p>
|
||||||
{/* <p className="text-xs lg:text-sm">
|
{/* <p className="text-xs lg:text-sm">
|
||||||
| {t("updatedOn")} {detailDataAudio?.updatedAt} WIB |
|
| {t("updatedOn")} {detailDataAudio?.updatedAt} WIB |
|
||||||
|
|
@ -621,7 +621,7 @@ const DetailAudio = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bagian Kanan */}
|
{/* Bagian Kanan */}
|
||||||
<div className="md:w-1/4 p-4 h-fit bg-gray-300 rounded-lg mx-4">
|
<div className="md:w-1/4 p-4 h-fit bg-[#f7f7f7] dark:bg-slate-600 rounded-lg mx-4">
|
||||||
{isSaved ? (
|
{isSaved ? (
|
||||||
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||||
<Icon icon="material-symbols:bookmark" width={40} />
|
<Icon icon="material-symbols:bookmark" width={40} />
|
||||||
|
|
@ -724,7 +724,7 @@ const DetailAudio = () => {
|
||||||
|
|
||||||
<div className="w-full mb-8">
|
<div className="w-full mb-8">
|
||||||
{/* Comment */}
|
{/* Comment */}
|
||||||
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7] dark:bg-slate-600">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<p className="flex items-start text-lg">{t("comment")}</p>
|
<p className="flex items-start text-lg">{t("comment")}</p>
|
||||||
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import "react-datepicker/dist/react-datepicker.css";
|
||||||
import { close, loading } from "@/config/swal";
|
import { close, loading } from "@/config/swal";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
|
import { Reveal } from "@/components/landing-page/Reveal";
|
||||||
|
|
||||||
const columns: ColumnDef<any>[] = [
|
const columns: ColumnDef<any>[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -475,6 +476,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
{/* Right */}
|
{/* Right */}
|
||||||
<div className="w-full lg:w-[75%]">
|
<div className="w-full lg:w-[75%]">
|
||||||
|
<Reveal>
|
||||||
<div className="flex flex-col items-end mb-4">
|
<div className="flex flex-col items-end mb-4">
|
||||||
<h2 className="text-lg font-semibold">{t("sortBy")} </h2>
|
<h2 className="text-lg font-semibold">{t("sortBy")} </h2>
|
||||||
<select defaultValue={sortBy == "popular" ? "terpopuler" : "terbaru"} onChange={(e) => handleSorting(e)} className="border rounded-md py-2 px-3 focus:ring-red-500 focus:border-red-500">
|
<select defaultValue={sortBy == "popular" ? "terpopuler" : "terbaru"} onChange={(e) => handleSorting(e)} className="border rounded-md py-2 px-3 focus:ring-red-500 focus:border-red-500">
|
||||||
|
|
@ -552,6 +554,7 @@ const FilterPage = () => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<LandingPagination table={table} totalData={totalData} totalPage={totalPage} />
|
<LandingPagination table={table} totalData={totalData} totalPage={totalPage} />
|
||||||
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -95,35 +95,35 @@ const ContactForm = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form method="POST" id="form" onSubmit={handleSubmit(onSubmit)} 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 dark:bg-black p-6">
|
||||||
<Reveal>
|
<Reveal>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center justify-center mb-6">
|
<div className="flex items-center justify-center mb-6">
|
||||||
<img src="/assets/icons-contact.png" alt="contact" />
|
<img src="/assets/icons-contact.png" alt="contact" />
|
||||||
<h2 className="ml-4 text-2xl font-bold">{t("contactUs")}</h2>
|
<h2 className="ml-4 text-2xl font-bold">{t("contactUs")}</h2>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-lg font-semibold text-gray-800 mb-1">{t("writeMessage")}</h3>
|
<h3 className="text-lg font-semibold text-gray-800 dark:text-white mb-1">{t("writeMessage")}</h3>
|
||||||
<p className="text-sm text-gray-600 mb-6">{t("leaveMessage")}</p>
|
<p className="text-sm text-gray-600 dark:text-white mb-6">{t("leaveMessage")}</p>
|
||||||
|
|
||||||
{/* Form */}
|
{/* Form */}
|
||||||
<form>
|
<form>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("name")}</label>
|
<label className="block text-sm font-medium text-gray-700 dark:text-white 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 />
|
<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>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">Email</label>
|
<label className="block text-sm font-medium text-gray-700 dark:text-white 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 ${errors.email ? "block" : ""}`} {...register("email")} 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>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("number")} (Optional)</label>
|
<label className="block text-sm font-medium text-gray-700 dark:text-white 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" />
|
<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>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("subject")}</label>
|
<label className="block text-sm font-medium text-gray-700 dark:text-white mb-1">{t("subject")}</label>
|
||||||
<select
|
<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" : ""}`}
|
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) })}
|
{...register("subjects", { onChange: (e) => handleSubjects(e) })}
|
||||||
|
|
@ -144,7 +144,7 @@ const ContactForm = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">{t("messages")}</label>
|
<label className="block text-sm font-medium text-gray-700 dark:text-white 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>
|
<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>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -280,8 +280,10 @@ const page = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="font-semibold mb-3">
|
<div className="font-semibold mb-3 text-black gap-2">
|
||||||
<label htmlFor="description">Deskripsi Artikel</label>
|
<label htmlFor="description" className="text-black dark:text-white">
|
||||||
|
Deskripsi Artikel
|
||||||
|
</label>
|
||||||
<CustomEditor onChange={(e: any) => {}} initialData={articleBody || ""} />
|
<CustomEditor onChange={(e: any) => {}} initialData={articleBody || ""} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -134,8 +134,8 @@ const page = () => {
|
||||||
<DialogTrigger>
|
<DialogTrigger>
|
||||||
<div className="flex flex-col items-center border border-gray-500 p-2 bg-[#f8f8f8] rounded-md">
|
<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" />
|
<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="font-bold text-base text-black">{row?.fullname}</p>
|
||||||
<p className="text-sm font-light">{row?.username || "username"}</p>
|
<p className="text-sm font-light text-black">{row?.username || "username"}</p>
|
||||||
</div>
|
</div>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="flex flex-row justify-center" size="sm">
|
<DialogContent className="flex flex-row justify-center" size="sm">
|
||||||
|
|
|
||||||
|
|
@ -140,11 +140,19 @@ const DetailDocument = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sizes = [
|
const size = [{ label: "DOC" }, { label: "PPT" }, { label: "PDF" }];
|
||||||
{ label: "DOC", value: "...KB" },
|
|
||||||
{ label: "PPT", value: "...KB" },
|
function formatBytes(kb: any, decimals = 2) {
|
||||||
{ label: "PDF", value: "...KB" },
|
if (kb == 0 || kb == null) return "0 KB";
|
||||||
];
|
|
||||||
|
const k = 1024;
|
||||||
|
const dm = decimals < 0 ? 0 : decimals;
|
||||||
|
const sizes = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||||
|
|
||||||
|
const i = Math.floor(Math.log(kb) / Math.log(k));
|
||||||
|
|
||||||
|
return `${parseFloat((kb / k ** i).toFixed(dm))} ${sizes[i]}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function sendActivityLog(activityTypeId: number) {
|
async function sendActivityLog(activityTypeId: number) {
|
||||||
const data = {
|
const data = {
|
||||||
|
|
@ -422,6 +430,7 @@ const DetailDocument = () => {
|
||||||
<img src={detailDataDocument?.files[selectedDocument]?.url} alt="Main" className="rounded-lg w-auto h-fit" />
|
<img src={detailDataDocument?.files[selectedDocument]?.url} alt="Main" className="rounded-lg w-auto h-fit" />
|
||||||
<div className="absolute top-4 left-4"></div>
|
<div className="absolute top-4 left-4"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer Informasi */}
|
{/* Footer Informasi */}
|
||||||
<div className="text-gray-500 flex flex-col lg:flex-row justify-between items-center border-t mt-4">
|
<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">
|
{/* <p className="flex flex-row items-center mt-3">
|
||||||
|
|
@ -433,7 +442,7 @@ const DetailDocument = () => {
|
||||||
<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">
|
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
||||||
<p className="text-xs lg:text-sm">
|
<p className="text-xs lg:text-sm">
|
||||||
{t("by")} <span className="font-semibold text-black">{detailDataDocument?.uploadedBy?.userLevel?.name}</span>
|
{t("by")} <span className="font-semibold text-black dark:text-white">{detailDataDocument?.uploadedBy?.userLevel?.name}</span>
|
||||||
</p>
|
</p>
|
||||||
{/* <p className="text-xs lg:text-sm">
|
{/* <p className="text-xs lg:text-sm">
|
||||||
| {t("updatedOn")} {detailDataDocument?.updatedAt} WIB |
|
| {t("updatedOn")} {detailDataDocument?.updatedAt} WIB |
|
||||||
|
|
@ -443,7 +452,8 @@ const DetailDocument = () => {
|
||||||
{formatDateToIndonesian(new Date(detailDataDocument?.updatedAt))} {"WIB"}
|
{formatDateToIndonesian(new Date(detailDataDocument?.updatedAt))} {"WIB"}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs lg:text-sm flex justify-center items-center">
|
<p className="text-xs lg:text-sm flex justify-center items-center">
|
||||||
| <Icon icon="formkit:eye" width="15" height="15" />
|
|
|
||||||
|
<Icon icon="formkit:eye" width="15" height="15" />
|
||||||
{detailDataDocument?.clickCount}
|
{detailDataDocument?.clickCount}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -457,13 +467,13 @@ const DetailDocument = () => {
|
||||||
|
|
||||||
{/* Keterangan */}
|
{/* Keterangan */}
|
||||||
<div className="">
|
<div className="">
|
||||||
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8 text-justify space-y-4">{detailDataDocument?.title}</h1>
|
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8 text-justify">{detailDataDocument?.title}</h1>
|
||||||
<div dangerouslySetInnerHTML={{ __html: detailDataDocument?.htmlDescription }} />
|
<div className="font-light text-justify mb-5 space-y-4 lg:mb-0" dangerouslySetInnerHTML={{ __html: detailDataDocument?.htmlDescription }} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bagian Kanan */}
|
{/* Bagian Kanan */}
|
||||||
<div className="md:w-1/4 p-4 bg-[#f7f7f7] h-fit rounded-lg mx-4">
|
<div className="md:w-1/4 p-4 bg-[#f7f7f7] dark:bg-slate-600 h-fit rounded-lg mx-4">
|
||||||
{isSaved ? (
|
{isSaved ? (
|
||||||
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||||
<Icon icon="material-symbols:bookmark" width={40} />
|
<Icon icon="material-symbols:bookmark" width={40} />
|
||||||
|
|
@ -497,14 +507,14 @@ const DetailDocument = () => {
|
||||||
<h4 className="flex text-lg justify-center items-center font-semibold my-3">{t("docSize")}</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="border-t border-black my-4"></div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{sizes.map((size: any) => (
|
{size.map((size: any) => (
|
||||||
<div className="flex flex-row justify-between">
|
<div className="flex flex-row justify-between">
|
||||||
<div key={size.label} className="items-center flex flex-row gap-2 cursor-pointer">
|
<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" />
|
<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 className="text-sm">{size.label}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="text-sm">{size.value}</div>
|
<div className="text-sm">{formatBytes(size?.size)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
@ -564,7 +574,7 @@ const DetailDocument = () => {
|
||||||
|
|
||||||
<div className="w-full mb-8">
|
<div className="w-full mb-8">
|
||||||
{/* Comment */}
|
{/* Comment */}
|
||||||
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7] dark:bg-slate-600">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<p className="flex items-start text-lg">{t("comment")}</p>
|
<p className="flex items-start text-lg">{t("comment")}</p>
|
||||||
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
||||||
<div className="lg:w-[45%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
<div className="lg:w-[25%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
||||||
<Icon icon="stash:filter-light" fontSize={30} />
|
<Icon icon="stash:filter-light" fontSize={30} />
|
||||||
Filter
|
Filter
|
||||||
|
|
@ -508,6 +508,7 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right */}
|
{/* Right */}
|
||||||
|
<div className="w-full lg:w-[75%]">
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<div className="flex flex-col items-end mb-4">
|
<div className="flex flex-col items-end mb-4">
|
||||||
|
|
@ -575,6 +576,7 @@ const FilterPage = () => {
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ const FAQS: React.FC = () => {
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<div className="flex items-center justify-center mb-6">
|
<div className="flex items-center justify-center mb-6">
|
||||||
<img src="/assets/icons-faqs.png" alt="Faqs" />
|
<img src="/assets/icons-faqs.png" alt="Faqs" />
|
||||||
<h2 className="ml-4 text-lg lg:text-2xl font-bold text-gray-800">Frequently Asked Questions</h2>
|
<h2 className="ml-4 text-lg lg:text-2xl font-bold text-gray-800 dark:text-white">Frequently Asked Questions</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* FAQS Items */}
|
{/* FAQS Items */}
|
||||||
|
|
@ -50,10 +50,10 @@ const FAQS: React.FC = () => {
|
||||||
{faqs?.map((faq, index) => (
|
{faqs?.map((faq, index) => (
|
||||||
<div key={index} className="border-b border-gray-300 pb-2 cursor-pointer">
|
<div key={index} className="border-b border-gray-300 pb-2 cursor-pointer">
|
||||||
<div className="flex justify-between items-center" onClick={() => toggleFAQ(index)}>
|
<div className="flex justify-between items-center" onClick={() => toggleFAQ(index)}>
|
||||||
<h3 className="text-sm font-semibold text-gray-800">{faq.question}</h3>
|
<h3 className="text-sm font-semibold text-gray-800 dark:text-white">{faq.question}</h3>
|
||||||
<span className="text-gray-500 text-xl">{openIndex === index ? "−" : "+"}</span>
|
<span className="text-gray-500 dark:text-white text-xl">{openIndex === index ? "−" : "+"}</span>
|
||||||
</div>
|
</div>
|
||||||
{openIndex === index && <p className="text-gray-600 mt-2 text-sm">{faq.answer}</p>}
|
{openIndex === index && <p className="text-gray-600 dark:text-white mt-2 text-sm">{faq.answer}</p>}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const Rating: React.FC<RatingProps> = ({ label, onRate }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-between items-center mb-4">
|
<div className="flex justify-between items-center mb-4">
|
||||||
<span className="text-gray-800">{label}</span>
|
<span className="text-gray-800 dark:text-white">{label}</span>
|
||||||
<div className="flex space-x-1">
|
<div className="flex space-x-1">
|
||||||
{[1, 2, 3, 4, 5].map((star) => (
|
{[1, 2, 3, 4, 5].map((star) => (
|
||||||
<button key={star} onClick={() => handleClick(star)} className={`text-2xl ${star <= selected ? "text-yellow-500" : "text-gray-300"}`}>
|
<button key={star} onClick={() => handleClick(star)} className={`text-2xl ${star <= selected ? "text-yellow-500" : "text-gray-300"}`}>
|
||||||
|
|
@ -117,14 +117,16 @@ const FeedbackForm: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<div className="max-w-6xl flex flex-col mx-auto p-4 lg:p-40 gap-5">
|
<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">
|
<div className="flex items-center justify-center mb-6">
|
||||||
<img src="/assets/icons-feedback.png" alt="Feedback" />
|
<img src="/assets/icons-feedback.png" alt="Feedback" />
|
||||||
<h2 className="ml-4 text-[15px] lg:text-[32px] font-bold text-gray-800">{t("userFeedback")}</h2>
|
<h2 className="ml-4 text-[15px] lg:text-[32px] font-bold text-gray-800 dark:text-white">{t("userFeedback")}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-black dark:text-white">
|
||||||
<Rating label={t("ratings")} onRate={(rating) => handleRatingChange("accessibility", rating)} />
|
<Rating label={t("ratings")} onRate={(rating) => handleRatingChange("accessibility", rating)} />
|
||||||
<Rating label={t("ratings2")} onRate={(rating) => handleRatingChange("appearance", rating)} />
|
<Rating label={t("ratings2")} onRate={(rating) => handleRatingChange("appearance", rating)} />
|
||||||
<Rating label={t("ratings3")} onRate={(rating) => handleRatingChange("content", rating)} />
|
<Rating label={t("ratings3")} onRate={(rating) => handleRatingChange("content", rating)} />
|
||||||
|
</div>
|
||||||
<div className="flex justify-center">
|
<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">
|
<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">
|
||||||
{t("send")}
|
{t("send")}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@ import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
|
interface Size {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
const DetailInfo = () => {
|
const DetailInfo = () => {
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||||
|
|
@ -56,6 +61,7 @@ const DetailInfo = () => {
|
||||||
let typeString = "image";
|
let typeString = "image";
|
||||||
const t = useTranslations("LandingPage");
|
const t = useTranslations("LandingPage");
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
@ -149,13 +155,34 @@ const DetailInfo = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sizes = [
|
// const sizes = [
|
||||||
{ label: "XL", value: "3198 x 1798 px" },
|
// { label: "XL", value: "3198 x 1798 px" },
|
||||||
{ label: "L", value: "2399 x 1349 px" },
|
// { label: "L", value: "2399 x 1349 px" },
|
||||||
{ label: "M", value: "1599 x 899 px" },
|
// { label: "M", value: "1599 x 899 px" },
|
||||||
{ label: "S", value: "1066 x 599 px" },
|
// { label: "S", value: "1066 x 599 px" },
|
||||||
{ label: "XS", value: "800 x 450 px" },
|
// { label: "XS", value: "800 x 450 px" },
|
||||||
];
|
// ];
|
||||||
|
|
||||||
|
const scaleFactors = {
|
||||||
|
XL: 2,
|
||||||
|
L: 1.5,
|
||||||
|
M: 1.25,
|
||||||
|
S: 1,
|
||||||
|
XS: 0.75,
|
||||||
|
};
|
||||||
|
const sizes: Size[] = Object.entries(scaleFactors).map(([label, factor]) => {
|
||||||
|
const width = Number(main?.widthPixel);
|
||||||
|
const height = Number(main?.heightPixel);
|
||||||
|
|
||||||
|
if (isNaN(width) || isNaN(height) || width === 0) {
|
||||||
|
return { label, value: "Invalid size" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const newWidth = Math.round(width * factor);
|
||||||
|
const newHeight = Math.round((width * factor) / (width / height));
|
||||||
|
|
||||||
|
return { label, value: `${newWidth} x ${newHeight} px` };
|
||||||
|
});
|
||||||
|
|
||||||
async function sendActivityLog(activityTypeId: number) {
|
async function sendActivityLog(activityTypeId: number) {
|
||||||
const data = {
|
const data = {
|
||||||
|
|
@ -471,7 +498,7 @@ const DetailInfo = () => {
|
||||||
<div className="text-gray-500 flex flex-col lg:flex-row justify-between items-center border-t mt-4">
|
<div className="text-gray-500 flex flex-col lg:flex-row justify-between items-center border-t mt-4">
|
||||||
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
||||||
<p className="text-xs lg:text-sm">
|
<p className="text-xs lg:text-sm">
|
||||||
{t("by")} <span className="font-semibold text-black">{detailDataImage?.uploadedBy?.userLevel?.name}</span>
|
{t("by")} <span className="font-semibold text-black dark:text-white">{detailDataImage?.uploadedBy?.userLevel?.name}</span>
|
||||||
</p>
|
</p>
|
||||||
{/* <p className="text-xs lg:text-sm">
|
{/* <p className="text-xs lg:text-sm">
|
||||||
| {t("updatedOn")}
|
| {t("updatedOn")}
|
||||||
|
|
@ -503,7 +530,7 @@ const DetailInfo = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bagian Kanan */}
|
{/* Bagian Kanan */}
|
||||||
<div className="md:w-1/4 p-4 bg-[#f7f7f7] h-fit rounded-lg mx-4">
|
<div className="md:w-1/4 p-4 bg-[#f7f7f7] dark:bg-slate-600 h-fit rounded-lg mx-4">
|
||||||
{isSaved ? (
|
{isSaved ? (
|
||||||
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||||
<Icon icon="material-symbols:bookmark" width={40} />
|
<Icon icon="material-symbols:bookmark" width={40} />
|
||||||
|
|
@ -540,13 +567,11 @@ const DetailInfo = () => {
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{sizes.map((size: any) => (
|
{sizes.map((size: any) => (
|
||||||
<div className="flex flex-row justify-between">
|
<div className="flex flex-row justify-between">
|
||||||
<div key={size.label} className="items-center flex flex-row gap-2 cursor-pointer">
|
<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={(e) => setImageSizeSelected(e.target.value)} className="text-red-600 focus:ring-red-600" />
|
<input type="radio" name="size" value={size?.label} checked={selectedSize === size?.label} onChange={(e) => setImageSizeSelected(e.target.value)} className="text-red-600 focus:ring-red-600" />
|
||||||
<div className="text-sm">{size.label}</div>
|
<div className="text-sm">{size?.label}</div>
|
||||||
</div>
|
|
||||||
<div className="">
|
|
||||||
<div className="text-sm">{size.value}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-sm">{size?.value}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -605,7 +630,7 @@ const DetailInfo = () => {
|
||||||
|
|
||||||
<div className="w-full mb-8">
|
<div className="w-full mb-8">
|
||||||
{/* Comment */}
|
{/* Comment */}
|
||||||
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7] dark:bg-slate-600">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<p className="flex items-start text-lg">{t("comment")}</p>
|
<p className="flex items-start text-lg">{t("comment")}</p>
|
||||||
<Textarea placeholder={t("leaveComment")} className="flex w-full pb-12" onChange={getInputValue} />
|
<Textarea placeholder={t("leaveComment")} className="flex w-full pb-12" onChange={getInputValue} />
|
||||||
|
|
|
||||||
|
|
@ -382,7 +382,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
||||||
<div className="lg:w-[30%] h-fit w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
<div className="lg:w-[25%] h-fit w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
||||||
<Icon icon="stash:filter-light" fontSize={30} />
|
<Icon icon="stash:filter-light" fontSize={30} />
|
||||||
Filter
|
Filter
|
||||||
|
|
@ -484,7 +484,7 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right */}
|
{/* Right */}
|
||||||
<div className="w-full">
|
<div className="w-full lg:w-[75%]">
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex flex-col items-end mb-4">
|
<div className="flex flex-col items-end mb-4">
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ const UpdateSection = () => {
|
||||||
}, [pages]);
|
}, [pages]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-6xl h-screen flex flex-col mx-auto p-4 lg:p-24 gap-5">
|
<div className="max-w-6xl flex flex-col mx-auto p-4 lg:p-24 gap-5">
|
||||||
<div className="flex items-center justify-center mb-6">
|
<div className="flex items-center justify-center mb-6">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="60px" height="60px" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="60px" height="60px" viewBox="0 0 24 24">
|
||||||
<g fill="#bb3523" fill-rule="evenodd" clip-rule="evenodd">
|
<g fill="#bb3523" fill-rule="evenodd" clip-rule="evenodd">
|
||||||
|
|
@ -64,7 +64,7 @@ const UpdateSection = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="py-10 px-8 w-[400px] mt-3 border border-black rounded-lg flex flex-col">
|
<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">{t("notifList")}</h1>
|
<h1 className="mb-3 text-lg font-semibold">{t("notifList")}</h1>
|
||||||
<div className="hover:bg-slate-200 rounded-md">
|
<div className="rounded-md overflow-y-auto space-y-3">
|
||||||
{notifications?.map((list: any) => (
|
{notifications?.map((list: any) => (
|
||||||
<a className="flex flex-row items-center ml-1" href={"/" + list.redirectUrl}>
|
<a className="flex flex-row items-center ml-1" href={"/" + list.redirectUrl}>
|
||||||
{(() => {
|
{(() => {
|
||||||
|
|
@ -134,8 +134,8 @@ const UpdateSection = () => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})()}
|
})()}
|
||||||
<div className="ml-3">
|
<div className="flex flex-col ml-3">
|
||||||
<span className="block">{list.message}</span>
|
<span className="">{list.message}</span>
|
||||||
<span className="text-xs">{getTimestamp(new Date(list.createdAt))}</span>
|
<span className="text-xs">{getTimestamp(new Date(list.createdAt))}</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,8 @@ const IndeksDetail = () => {
|
||||||
{/* Footer Informasi */}
|
{/* Footer Informasi */}
|
||||||
<div className="text-gray-500 flex border-t mt-4">
|
<div className="text-gray-500 flex border-t mt-4">
|
||||||
<div className="flex mt-2">
|
<div className="flex mt-2">
|
||||||
<p className="text-xs lg:text-sm mb-2">
|
<p className="text-xs lg:text-sm mb-2 ">
|
||||||
{t("by")} <span className="font-semibold text-black">{indeksData?.uploaderName}</span> | {t("updatedOn")} {indeksData?.createdAt} WIB
|
{t("by")} <span className="font-semibold text-gray-500">{indeksData?.uploaderName}</span> | {t("updatedOn")} {indeksData?.createdAt} WIB
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -181,7 +181,7 @@ const IndeksDetail = () => {
|
||||||
|
|
||||||
{/* Comment */}
|
{/* Comment */}
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex flex-col py-5 p-0 lg:p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col py-5 p-0 lg:p-10 bg-[#f7f7f7] dark:bg-slate-600">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-16">
|
<div className="gap-5 flex flex-col px-4 lg:px-16">
|
||||||
<p className="flex items-start text-bases lg:text-lg">{t("comment")}</p>
|
<p className="flex items-start text-bases lg:text-lg">{t("comment")}</p>
|
||||||
<Textarea placeholder="Type your comments here." className="flex w-full" onChange={getInputValue} value={message} />
|
<Textarea placeholder="Type your comments here." className="flex w-full" onChange={getInputValue} value={message} />
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ const Indeks: React.FC = () => {
|
||||||
<h2 className="text-2xl font-bold mt-2">{indeks?.title}</h2>
|
<h2 className="text-2xl font-bold mt-2">{indeks?.title}</h2>
|
||||||
</Link>
|
</Link>
|
||||||
<p className="text-xs flex flex-row items-center gap-1 mt-1">
|
<p className="text-xs flex flex-row items-center gap-1 mt-1">
|
||||||
{formatDateToIndonesian(new Date(indeks?.createdAt))} {indeks?.timezone ? indeks?.timezone : "WIB"} | {" "}
|
{formatDateToIndonesian(new Date(indeks?.createdAt))} {indeks?.timezone ? indeks?.timezone : "WIB"} |{" "}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
|
|
@ -152,10 +152,10 @@ const Indeks: React.FC = () => {
|
||||||
<Image width={2560} height={1440} src={indeksBottom?.thumbnailLink} alt="" className="h-40 object-cover rounded-lg w-full lg:w-full lg:h-[300px]" />
|
<Image width={2560} height={1440} src={indeksBottom?.thumbnailLink} alt="" className="h-40 object-cover rounded-lg w-full lg:w-full lg:h-[300px]" />
|
||||||
<div className="flex flex-col justify-between w-full">
|
<div className="flex flex-col justify-between w-full">
|
||||||
<p className="text-sm">{indeksBottom?.date}</p>
|
<p className="text-sm">{indeksBottom?.date}</p>
|
||||||
<Link href={`/indeks/detail/${indeksBottom?.slug}`} className="text-2xl font-semibold text-gray-800">
|
<Link href={`/indeks/detail/${indeksBottom?.slug}`} className="text-2xl font-semibold text-gray-800 dark:text-white">
|
||||||
{indeksBottom?.title}
|
{indeksBottom?.title}
|
||||||
</Link>
|
</Link>
|
||||||
<p className="text-sm text-gray-600 mt-2">{indeksBottom?.description}</p>
|
<p className="text-sm text-gray-600 dark:text-white mt-2">{indeksBottom?.description}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -503,9 +503,9 @@ const Schedule = (props: any) => {
|
||||||
<div className="container relative py-4">
|
<div className="container relative py-4">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<a className="text-black flex flex-row w-fit gap-2 py-4 items-center cursor-pointer">
|
<a className="text-black dark:text-white flex flex-row w-fit gap-2 py-4 items-center cursor-pointer">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||||
<path fill="#000" d="M20 3H4a1 1 0 0 0-1 1v2.227l.008.223a3 3 0 0 0 .772 1.795L8 12.886V21a1 1 0 0 0 1.316.949l6-2l.108-.043A1 1 0 0 0 16 19v-6.586l4.121-4.12A3 3 0 0 0 21 6.171V4a1 1 0 0 0-1-1" />
|
<path fill="currentColor" d="M20 3H4a1 1 0 0 0-1 1v2.227l.008.223a3 3 0 0 0 .772 1.795L8 12.886V21a1 1 0 0 0 1.316.949l6-2l.108-.043A1 1 0 0 0 16 19v-6.586l4.121-4.12A3 3 0 0 0 21 6.171V4a1 1 0 0 0-1-1" />
|
||||||
</svg>
|
</svg>
|
||||||
Filter
|
Filter
|
||||||
<svg className="flex items-center justify-center" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
<svg className="flex items-center justify-center" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||||
|
|
@ -856,8 +856,8 @@ const Schedule = (props: any) => {
|
||||||
</p>
|
</p>
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
<p className="flex flex-row items-start gap-2 ">
|
<p className="flex flex-row items-center gap-2 ">
|
||||||
<Icon icon="bxs:map" width={30} />
|
<Icon icon="bxs:map" fontSize={20} />
|
||||||
{detail?.address}
|
{detail?.address}
|
||||||
</p>
|
</p>
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@ import parse from "html-react-parser";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
|
interface Size {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
const DetailVideo = () => {
|
const DetailVideo = () => {
|
||||||
const [selectedSize, setSelectedSize] = useState<string>("L");
|
const [selectedSize, setSelectedSize] = useState<string>("L");
|
||||||
const [selectedTab, setSelectedTab] = useState("video");
|
const [selectedTab, setSelectedTab] = useState("video");
|
||||||
|
|
@ -140,11 +145,10 @@ const DetailVideo = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const sizes = [
|
const sizes = [
|
||||||
{ label: "XL", value: "3198 x 1798 px" },
|
{ label: "FULL HD", value: "1920 x 1080 px" },
|
||||||
{ label: "L", value: "2399 x 1349 px" },
|
{ label: "HD", value: "1280 x 720 px" },
|
||||||
{ label: "M", value: "1599 x 899 px" },
|
{ label: "SD", value: "720 x 480 px" },
|
||||||
{ label: "S", value: "1066 x 599 px" },
|
{ label: "WEB", value: "640 x 360 px" },
|
||||||
{ label: "XS", value: "800 x 450 px" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
async function sendActivityLog(activityTypeId: number) {
|
async function sendActivityLog(activityTypeId: number) {
|
||||||
|
|
@ -438,7 +442,7 @@ const DetailVideo = () => {
|
||||||
<p className="mt-3">Kreator: {detailDataVideo?.creatorName}</p> */}
|
<p className="mt-3">Kreator: {detailDataVideo?.creatorName}</p> */}
|
||||||
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
|
||||||
<p className="text-xs lg:text-sm">
|
<p className="text-xs lg:text-sm">
|
||||||
{t("by")} <span className="font-semibold text-black">{detailDataVideo?.uploadedBy?.userLevel?.name}</span>
|
{t("by")} <span className="font-semibold text-black dark:text-white">{detailDataVideo?.uploadedBy?.userLevel?.name}</span>
|
||||||
</p>
|
</p>
|
||||||
{/* <p className="text-xs lg:text-sm">
|
{/* <p className="text-xs lg:text-sm">
|
||||||
| {t("updatedOn")}
|
| {t("updatedOn")}
|
||||||
|
|
@ -475,7 +479,7 @@ const DetailVideo = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bagian Kanan */}
|
{/* Bagian Kanan */}
|
||||||
<div className="md:w-1/4 p-4 bg-[#f7f7f7] rounded-lg mx-4 h-fit">
|
<div className="md:w-1/4 p-4 bg-[#f7f7f7] dark:bg-slate-600 rounded-lg mx-4 h-fit">
|
||||||
{isSaved ? (
|
{isSaved ? (
|
||||||
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
<a onClick={() => handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer">
|
||||||
<Icon icon="material-symbols:bookmark" width={40} />
|
<Icon icon="material-symbols:bookmark" width={40} />
|
||||||
|
|
@ -577,7 +581,7 @@ const DetailVideo = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full mb-8">
|
<div className="w-full mb-8">
|
||||||
{/* Comment */}
|
{/* Comment */}
|
||||||
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7]">
|
<div className="flex flex-col my-16 p-4 lg:p-10 bg-[#f7f7f7] dark:bg-slate-600">
|
||||||
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
<div className="gap-5 flex flex-col px-4 lg:px-14">
|
||||||
<p className="flex items-start text-lg">{t("comment")}</p>
|
<p className="flex items-start text-lg">{t("comment")}</p>
|
||||||
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
<Textarea placeholder="Type your comments here." className="flex w-full pb-12" onChange={getInputValue} />
|
||||||
|
|
|
||||||
|
|
@ -396,7 +396,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
||||||
<div className="lg:w-[55%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
<div className="lg:w-[25%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
<h2 className="text-lg font-semibold mb-4 flex items-center gap-1">
|
||||||
<Icon icon="stash:filter-light" fontSize={30} />
|
<Icon icon="stash:filter-light" fontSize={30} />
|
||||||
Filter
|
Filter
|
||||||
|
|
@ -510,8 +510,9 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right */}
|
{/* Right */}
|
||||||
|
<div className="w-full lg:w-[75%]">
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<div className="flex-1">
|
<div className="w-full">
|
||||||
<div className="flex flex-col items-end mb-4">
|
<div className="flex flex-col items-end mb-4">
|
||||||
<h2 className="text-lg font-semibold">{t("sortBy")}</h2>
|
<h2 className="text-lg font-semibold">{t("sortBy")}</h2>
|
||||||
<select defaultValue={sortBy == "popular" ? "terpopuler" : "terbaru"} onChange={(e) => handleSorting(e)} className="border rounded-md py-2 px-3 focus:ring-red-500 focus:border-red-500">
|
<select defaultValue={sortBy == "popular" ? "terpopuler" : "terbaru"} onChange={(e) => handleSorting(e)} className="border rounded-md py-2 px-3 focus:ring-red-500 focus:border-red-500">
|
||||||
|
|
@ -523,14 +524,14 @@ const FilterPage = () => {
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div className="flex flex-col lg:flex-row space-y-3 w-full justify-center items-center gap-3">
|
<div className="flex flex-col lg:flex-row space-y-3 w-full justify-center items-center gap-3">
|
||||||
<Skeleton className="h-[280px] w-[380px] rounded-xl" />
|
<Skeleton className="h-[260px] w-[360px] rounded-xl" />
|
||||||
<Skeleton className="h-[280px] w-[380px] rounded-xl" />
|
<Skeleton className="h-[260px] w-[360px] rounded-xl" />
|
||||||
<Skeleton className="h-[280px] w-[380px] rounded-xl" />
|
<Skeleton className="h-[260px] w-[360px] rounded-xl" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col lg:flex-row space-y-3 w-full justify-center items-center gap-3">
|
<div className="flex flex-col lg:flex-row space-y-3 w-full justify-center items-center gap-3">
|
||||||
<Skeleton className="h-[280px] w-[380px] rounded-xl" />
|
<Skeleton className="h-[260px] w-[360px] rounded-xl" />
|
||||||
<Skeleton className="h-[280px] w-[380px] rounded-xl" />
|
<Skeleton className="h-[260px] w-[360px] rounded-xl" />
|
||||||
<Skeleton className="h-[280px] w-[380px] rounded-xl" />
|
<Skeleton className="h-[260px] w-[360px] rounded-xl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -574,6 +575,7 @@ const FilterPage = () => {
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ const ForgotPassPage = () => {
|
||||||
<div className=" h-full flex flex-col ">
|
<div className=" h-full flex flex-col ">
|
||||||
<div className="max-w-[524px] mx-auto w-full md:px-[42px] md:py-[44px] p-7 text-2xl text-default-900 mb-3 flex flex-col justify-center h-full">
|
<div className="max-w-[524px] mx-auto w-full md:px-[42px] md:py-[44px] p-7 text-2xl text-default-900 mb-3 flex flex-col justify-center h-full">
|
||||||
<div className="flex justify-center items-center text-center mb-6 lg:hidden ">
|
<div className="flex justify-center items-center text-center mb-6 lg:hidden ">
|
||||||
<Link href="/">
|
{/* <Link href="/">
|
||||||
<Logo />
|
<Logo />
|
||||||
</Link>
|
</Link> */}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center 2xl:mb-10 mb-5">
|
<div className="text-center 2xl:mb-10 mb-5">
|
||||||
<h4 className="font-medium mb-4">Forgot Your Password?</h4>
|
<h4 className="font-medium mb-4">Forgot Your Password?</h4>
|
||||||
|
|
|
||||||
|
|
@ -482,8 +482,8 @@ const page = () => {
|
||||||
if (category != undefined) {
|
if (category != undefined) {
|
||||||
const resInstiution = await listInstitusi(category);
|
const resInstiution = await listInstitusi(category);
|
||||||
const res = await listProvince();
|
const res = await listProvince();
|
||||||
setInstitution(resInstiution?.data.data);
|
setInstitution(resInstiution?.data?.data);
|
||||||
setProvince(res?.data.data);
|
setProvince(res?.data?.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -518,7 +518,7 @@ const page = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
className="flex-1 w-full bg-white"
|
className="flex-1 w-full bg-white dark:bg-slate-600"
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
style={
|
style={
|
||||||
Number(category) < 5
|
Number(category) < 5
|
||||||
|
|
@ -580,7 +580,7 @@ const page = () => {
|
||||||
: {}
|
: {}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<p className="text-black text-2xl px-0 lg:px-20 font-semibold">{t("enterOTP")}</p>
|
<p className="text-black dark:text-white text-2xl px-0 lg:px-20 font-semibold">{t("enterOTP")}</p>
|
||||||
<p className="text-red-500 text-sm px-0 lg:px-20">{t("checkInbox")}</p>
|
<p className="text-red-500 text-sm px-0 lg:px-20">{t("checkInbox")}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -600,7 +600,7 @@ const page = () => {
|
||||||
{t("member")} <span className="text-red-500">*</span>
|
{t("member")} <span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<select
|
<select
|
||||||
className={`py-2 px-1 rounded-md border text-sm text-slate-400 border-slate-300 bg-white ${errors.association ? "block" : ""}`}
|
className={`py-2 px-1 rounded-md border text-sm text-slate-400 border-slate-300 bg-white dark:bg-slate-600 ${errors.association ? "block" : ""}`}
|
||||||
{...register("association")}
|
{...register("association")}
|
||||||
id="association"
|
id="association"
|
||||||
onChange={(e) => setAssociation(e.target.value)}
|
onChange={(e) => setAssociation(e.target.value)}
|
||||||
|
|
@ -689,7 +689,7 @@ const page = () => {
|
||||||
<b>{otpValidate}</b>
|
<b>{otpValidate}</b>
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row px-0 lg:px-28 justify-between items-center my-4">
|
<div className="flex flex-row px-0 lg:px-28 justify-between items-center my-4">
|
||||||
<a className="bg-slate-300 text-center rounded-lg mr-1 w-[200px] py-2 text-base cursor-pointer" onClick={() => handleResendOTP()}>
|
<a className="bg-slate-300 dark:bg-black text-center rounded-lg mr-1 w-[200px] py-2 text-base cursor-pointer" onClick={() => handleResendOTP()}>
|
||||||
{t("resending")} ({convertMilisecondsToHour(timerCount)})
|
{t("resending")} ({convertMilisecondsToHour(timerCount)})
|
||||||
</a>
|
</a>
|
||||||
<a className="bg-red-700 w-[200px] py-2 text-center text-white rounded-lg ml-1 cursor-pointer" onClick={() => handleVerifyOTP()}>
|
<a className="bg-red-700 w-[200px] py-2 text-center text-white rounded-lg ml-1 cursor-pointer" onClick={() => handleVerifyOTP()}>
|
||||||
|
|
@ -753,7 +753,7 @@ const page = () => {
|
||||||
<Label className="mb-2">
|
<Label className="mb-2">
|
||||||
Email <span className="text-red-500">*</span>
|
Email <span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input type="email" autoComplete="off" className={`${errors.email ? "block" : ""}`} {...register("email")} placeholder="Masukan Email Anda" disabled />
|
<Input type="email" autoComplete="off" className={`${errors.email ? "block" : "text-white"}`} {...register("email")} placeholder="Masukan Email Anda" disabled />
|
||||||
<div className="text-red-500">{errors.email?.message}</div>
|
<div className="text-red-500">{errors.email?.message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -781,7 +781,7 @@ const page = () => {
|
||||||
<option disabled selected>
|
<option disabled selected>
|
||||||
{t("selectInst")}
|
{t("selectInst")}
|
||||||
</option>
|
</option>
|
||||||
{institution.map((row: any) => (
|
{institution?.map((row: any) => (
|
||||||
<option value={row.id} key={row.id}>
|
<option value={row.id} key={row.id}>
|
||||||
{row?.name}
|
{row?.name}
|
||||||
</option>
|
</option>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const regions = [
|
||||||
{ name: "SIBER", slug: "siber", logo: "/assets/satker/siber.png" },
|
{ name: "SIBER", slug: "siber", logo: "/assets/satker/siber.png" },
|
||||||
{ name: "DIVKUM", slug: "divkum", logo: "/assets/satker/divkum.png" },
|
{ name: "DIVKUM", slug: "divkum", logo: "/assets/satker/divkum.png" },
|
||||||
{ name: "PUSKEU", slug: "puskeu", logo: "/assets/satker/puskeu.png" },
|
{ name: "PUSKEU", slug: "puskeu", logo: "/assets/satker/puskeu.png" },
|
||||||
|
{ name: "YANMA", slug: "yanma", logo: "/assets/satker/logo-yanma.png" },
|
||||||
{ name: "SSDM", slug: "ssdm", logo: "/assets/satker/ssdm.png" },
|
{ name: "SSDM", slug: "ssdm", logo: "/assets/satker/ssdm.png" },
|
||||||
{ name: "ITWASUM", slug: "itwasum", logo: "/assets/satker/itwasum.png" },
|
{ name: "ITWASUM", slug: "itwasum", logo: "/assets/satker/itwasum.png" },
|
||||||
{ name: "STIK-PTIK", slug: "stik-ptik", logo: "/assets/satker/stik-ptik.png" },
|
{ name: "STIK-PTIK", slug: "stik-ptik", logo: "/assets/satker/stik-ptik.png" },
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ const Footer = () => {
|
||||||
<img src="/assets/icon-privacy.png" alt="Privacy" />
|
<img src="/assets/icon-privacy.png" alt="Privacy" />
|
||||||
<p className="font-semibold text-lg">{t("privacy")}</p>
|
<p className="font-semibold text-lg">{t("privacy")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="container text-black space-y-2">{parse(String(privacy))}</div>
|
<div className="container text-black dark:text-white space-y-2">{parse(String(privacy))}</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -68,13 +68,13 @@ const Hero: React.FC = () => {
|
||||||
{heroData?.map((list: any) => (
|
{heroData?.map((list: any) => (
|
||||||
<CarouselItem key={list?.id}>
|
<CarouselItem key={list?.id}>
|
||||||
<div className="relative h-[310px] lg:h-[420px]">
|
<div className="relative h-[310px] lg:h-[420px]">
|
||||||
<Image src={list?.thumbnailLink} alt="gambar-utama" width={1920} height={1080} className="w-full h-[310px] lg:h-[420px] rounded-lg object-cover" />
|
<Image src={list?.thumbnailLink} alt="gambar-utama" width={1920} height={1080} className="w-full lg:w-[850px] h-[310px] lg:h-[420px] rounded-lg object-cover" />
|
||||||
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm text-black dark:text-white p-4 rounded-b-lg">
|
<div className="absolute bottom-0 left-0 right-0 bg-transparent backdrop-blur-sm text-black dark:text-white p-4 rounded-b-lg">
|
||||||
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-xs px-2 py-1">{list?.categoryName}</span>
|
<span className="text-white bg-[#bb3523] rounded-md w-full h-full font-semibold uppercase text-xs px-2 py-1">{list?.categoryName}</span>
|
||||||
<Link href={`${locale}/image/detail/${list?.slug}`}>
|
<Link href={`${locale}/image/detail/${list?.slug}`}>
|
||||||
<h2 className="text-lg font-bold mt-2">{list?.title}</h2>
|
<h2 className="text-lg text-slate-200 dark:text-white font-bold mt-2">{list?.title}</h2>
|
||||||
</Link>
|
</Link>
|
||||||
<p className="text-xs flex flex-row items-center gap-1 mt-1">
|
<p className="text-xs flex flex-row items-center text-slate-200 dark:text-white gap-1 mt-1">
|
||||||
{formatDateToIndonesian(new Date(list?.createdAt))} {list?.timezone ? list?.timezone : "WIB"}|{" "}
|
{formatDateToIndonesian(new Date(list?.createdAt))} {list?.timezone ? list?.timezone : "WIB"}|{" "}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
|
|
@ -89,8 +89,8 @@ const Hero: React.FC = () => {
|
||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
))}
|
))}
|
||||||
</CarouselContent>
|
</CarouselContent>
|
||||||
<CarouselPrevious />
|
<CarouselPrevious className="hover:bg-black ml-1 lg:ml-0" />
|
||||||
<CarouselNext />
|
<CarouselNext className="hover:bg-black mr-1 lg:mr-0" />
|
||||||
</Carousel>
|
</Carousel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -144,7 +144,7 @@ const Hero: React.FC = () => {
|
||||||
<div className="w-[280px] lg:w-auto">
|
<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>
|
<span className="text-white bg-[#bb3523] px-4 py-1 rounded-lg flex text-[8px] font-bold uppercase w-fit">{item?.categoryName}</span>
|
||||||
<Link href={`${locale}/image/detail/${item?.slug}`}>
|
<Link href={`${locale}/image/detail/${item?.slug}`}>
|
||||||
<h3 className="text-base font-bold mt-2">{textEllipsis(item?.title, 30)}</h3>
|
<h3 className="text-base font-bold mt-2 h-6 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">{item?.title}</h3>
|
||||||
</Link>
|
</Link>
|
||||||
<p className="text-[10px] flex flex-row items-center gap-1 text-gray-500 mt-1">
|
<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"} |{" "}
|
{formatDateToIndonesian(new Date(item?.createdAt))} {item?.timezone ? item?.timezone : "WIB"} |{" "}
|
||||||
|
|
|
||||||
|
|
@ -144,27 +144,14 @@ const Navbar = () => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-[#f7f7f7] dark:bg-black shadow-md sticky top-0 z-50">
|
<div className="bg-[#f7f7f7] dark:bg-black shadow-md sticky top-0 z-50">
|
||||||
<div className="flex items-center justify-between px-4 lg:px-20 py-4 gap-3">
|
<div className="flex items-center justify-between px-4 lg:px-20 py-4 gap-3">
|
||||||
|
<div className="flex flex-row gap-8">
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Link href={prefixPath} className="flex items-center">
|
<Link href={prefixPath} className="flex items-center">
|
||||||
<Image src="/assets/mediahub-logo.gif" alt="Media Hub Logo" width={200} height={300} className="object-contain" />
|
<Image src="/assets/mediahub-logo.gif" alt="Media Hub Logo" width={200} height={300} className="object-contain" />
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* Mobile Menu Toggle */}
|
|
||||||
<button className="text-black dark:text-white right-0 size-20 h-10 w-10 lg:hidden" onClick={() => setMenuOpen(!menuOpen)}>
|
|
||||||
{menuOpen ? (
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
||||||
<path fill="#000" d="m13.41 12l4.3-4.29a1 1 0 1 0-1.42-1.42L12 10.59l-4.29-4.3a1 1 0 0 0-1.42 1.42l4.3 4.29l-4.3 4.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0l4.29-4.3l4.29 4.3a1 1 0 0 0 1.42 0a1 1 0 0 0 0-1.42Z" />
|
|
||||||
</svg>
|
|
||||||
) : (
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
||||||
<path fill="#000" d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z" />
|
|
||||||
</svg>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Desktop Navigation */}
|
|
||||||
<div className="hidden lg:flex items-center gap-5">
|
|
||||||
{/* Nav Menu */}
|
{/* Nav Menu */}
|
||||||
|
<div className="hidden lg:flex items-center gap-5">
|
||||||
<NavigationMenu>
|
<NavigationMenu>
|
||||||
<NavigationMenuList>
|
<NavigationMenuList>
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
|
|
@ -251,7 +238,24 @@ const Navbar = () => {
|
||||||
</NavigationMenuItem>
|
</NavigationMenuItem>
|
||||||
</NavigationMenuList>
|
</NavigationMenuList>
|
||||||
</NavigationMenu>
|
</NavigationMenu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu Toggle */}
|
||||||
|
<button className="text-black dark:text-white right-0 size-20 h-10 w-10 lg:hidden" onClick={() => setMenuOpen(!menuOpen)}>
|
||||||
|
{menuOpen ? (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path fill="currentColor" d="m13.41 12l4.3-4.29a1 1 0 1 0-1.42-1.42L12 10.59l-4.29-4.3a1 1 0 0 0-1.42 1.42l4.3 4.29l-4.3 4.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0l4.29-4.3l4.29 4.3a1 1 0 0 0 1.42 0a1 1 0 0 0 0-1.42Z" />
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path fill="currentColor" d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z" />
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Desktop Navigation */}
|
||||||
|
<div className="hidden lg:flex items-center gap-5">
|
||||||
{roleId == undefined ? (
|
{roleId == undefined ? (
|
||||||
""
|
""
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -292,7 +296,7 @@ const Navbar = () => {
|
||||||
<span className="w-2 h-2 bg-red-500 rounded-full"></span>
|
<span className="w-2 h-2 bg-red-500 rounded-full"></span>
|
||||||
<span className="font-medium">{t("live")}</span>
|
<span className="font-medium">{t("live")}</span>
|
||||||
</Link> */}
|
</Link> */}
|
||||||
<div className="flex items-center space-x-1 ">
|
<div className="flex items-center">
|
||||||
<a href="https://tvradio.polri.go.id/">
|
<a href="https://tvradio.polri.go.id/">
|
||||||
<Image src="/assets/polriTv.png" width={100} height={120} alt="polritv" className="object-contain flex-auto " />
|
<Image src="/assets/polriTv.png" width={100} height={120} alt="polritv" className="object-contain flex-auto " />
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -379,7 +383,7 @@ const Navbar = () => {
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<a className="cursor-pointer" onClick={() => test()}>
|
<a className="cursor-pointer" onClick={() => test()}>
|
||||||
{" "}
|
{" "}
|
||||||
<Icon icon="basil:envelope-outline" color="black" width="30" />
|
<Icon icon="basil:envelope-outline" color="currentColor" width="30" className="text-black dark:text-white" />
|
||||||
</a>
|
</a>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-[320px] p-0 flex flex-col mt-2" align="end">
|
<PopoverContent className="w-[320px] p-0 flex flex-col mt-2" align="end">
|
||||||
|
|
@ -666,7 +670,7 @@ const Navbar = () => {
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
// Masuk and Daftar buttons for roleId === null
|
// Masuk and Daftar buttons for roleId === null
|
||||||
<div className="flex justify-center items-center mx-3 gap-5">
|
<div className="flex justify-center items-center mx-3 gap-8">
|
||||||
<Link href="/auth" className="w-full lg:w-max px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 text-center">
|
<Link href="/auth" className="w-full lg:w-max px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 text-center">
|
||||||
{t("logIn")}
|
{t("logIn")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
@ -704,7 +708,7 @@ const Navbar = () => {
|
||||||
|
|
||||||
{/* Mobile Menu */}
|
{/* Mobile Menu */}
|
||||||
{menuOpen && (
|
{menuOpen && (
|
||||||
<div className="lg:hidden absolute bg-[#f7f7f7] px-4 py-3 w-full space-y-3 z-50">
|
<div className="lg:hidden absolute bg-[#f7f7f7] dark:bg-slate-600 px-4 py-3 w-full space-y-3 z-50">
|
||||||
<NavigationMenu>
|
<NavigationMenu>
|
||||||
<NavigationMenuList>
|
<NavigationMenuList>
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
|
|
|
||||||
|
|
@ -129,8 +129,8 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
))}
|
))}
|
||||||
</CarouselContent>
|
</CarouselContent>
|
||||||
<CarouselPrevious />
|
<CarouselPrevious className="hover:bg-black" />
|
||||||
<CarouselNext />
|
<CarouselNext className="hover:bg-black -mr-6" />
|
||||||
</Carousel>
|
</Carousel>
|
||||||
) : (
|
) : (
|
||||||
<p className="flex items-center justify-center">
|
<p className="flex items-center justify-center">
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ export default function NewsTicker() {
|
||||||
}, 7000);
|
}, 7000);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [article.length]);
|
}, [article?.length]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed bottom-0 z-50 flex flex-row h-[60px] gap-3 w-full justify-between dark:bg-stone-800 bg-gray-50">
|
<div className="fixed bottom-0 z-50 flex flex-row h-[60px] gap-3 w-full justify-between dark:bg-stone-800 bg-gray-50">
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,13 @@
|
||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import { useLocale } from 'next-intl';
|
import { useLocale } from "next-intl";
|
||||||
import { useParams } from 'next/navigation';
|
import { useParams } from "next/navigation";
|
||||||
import { locales } from '@/config';
|
import { locales } from "@/config";
|
||||||
import { usePathname, useRouter } from '@/i18n/routing';
|
import { usePathname, useRouter } from "@/i18n/routing";
|
||||||
|
|
||||||
import { useTransition } from 'react';
|
import { useTransition } from "react";
|
||||||
import {
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
Select,
|
import Image from "next/image";
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select"
|
|
||||||
import Image from 'next/image';
|
|
||||||
|
|
||||||
export default function LocalSwitcher() {
|
export default function LocalSwitcher() {
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
|
|
@ -24,44 +18,25 @@ export default function LocalSwitcher() {
|
||||||
|
|
||||||
const onSelectChange = (nextLocale: string) => {
|
const onSelectChange = (nextLocale: string) => {
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
|
|
||||||
router.replace(pathname, { locale: nextLocale });
|
router.replace(pathname, { locale: nextLocale });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Select onValueChange={onSelectChange} defaultValue={localActive}>
|
<Select onValueChange={onSelectChange} defaultValue={localActive}>
|
||||||
<SelectTrigger className='w-[94px] border-none read-only:bg-transparent'>
|
<SelectTrigger className="w-[94px] border-none read-only:bg-transparent">
|
||||||
<SelectValue placeholder="Select a language" />
|
<SelectValue placeholder="Select a language" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent >
|
<SelectContent>
|
||||||
<SelectItem
|
<SelectItem value="en" className="border-none">
|
||||||
value="en"
|
<div className="flex items-center gap-1">
|
||||||
className='border-none'
|
<Image src="/images/all-img/flag-1.png" alt="flag" width={24} height={24} className="w-6 h-6 rounded-full" />
|
||||||
>
|
<span className="font-medium text-sm text-default-600 dark:text-default-700">En</span>
|
||||||
<div className='flex items-center gap-1'>
|
|
||||||
<Image
|
|
||||||
src="/images/all-img/flag-1.png"
|
|
||||||
alt='flag'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
className='w-6 h-6 rounded-full'
|
|
||||||
/>
|
|
||||||
<span className='font-medium text-sm text-default-600 dark:text-default-700'>En</span>
|
|
||||||
</div>
|
</div>
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem
|
<SelectItem value="in" className="border-none">
|
||||||
value="in"
|
<div className="flex items-center gap-1">
|
||||||
className='border-none'
|
<Image src="/images/all-img/flag-3.png" alt="flag" width={24} height={24} className="w-6 h-6 rounded-full" />
|
||||||
>
|
<span className="font-medium text-sm text-default-600 dark:text-default-700">In</span>
|
||||||
<div className='flex items-center gap-1'>
|
|
||||||
<Image
|
|
||||||
src="/images/all-img/flag-3.png"
|
|
||||||
alt='flag'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
className='w-6 h-6 rounded-full'
|
|
||||||
/>
|
|
||||||
<span className='font-medium text-sm text-default-600 dark:text-default-700'>In</span>
|
|
||||||
</div>
|
</div>
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
{/* <SelectItem value="ar">
|
{/* <SelectItem value="ar">
|
||||||
|
|
@ -78,6 +53,5 @@ export default function LocalSwitcher() {
|
||||||
</SelectItem> */}
|
</SelectItem> */}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import useEmblaCarousel, {
|
import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-react";
|
||||||
type UseEmblaCarouselType,
|
|
||||||
} from "embla-carousel-react";
|
|
||||||
import { ArrowLeft, ArrowRight } from "lucide-react";
|
import { ArrowLeft, ArrowRight } from "lucide-react";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
@ -42,22 +40,7 @@ function useCarousel() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Carousel = React.forwardRef<
|
const Carousel = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement> & CarouselProps>(({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }, ref) => {
|
||||||
HTMLDivElement,
|
|
||||||
React.HTMLAttributes<HTMLDivElement> & CarouselProps
|
|
||||||
>(
|
|
||||||
(
|
|
||||||
{
|
|
||||||
orientation = "horizontal",
|
|
||||||
opts,
|
|
||||||
setApi,
|
|
||||||
plugins,
|
|
||||||
className,
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
},
|
|
||||||
ref
|
|
||||||
) => {
|
|
||||||
const [carouselRef, api] = useEmblaCarousel(
|
const [carouselRef, api] = useEmblaCarousel(
|
||||||
{
|
{
|
||||||
...opts,
|
...opts,
|
||||||
|
|
@ -126,78 +109,40 @@ const Carousel = React.forwardRef<
|
||||||
carouselRef,
|
carouselRef,
|
||||||
api: api,
|
api: api,
|
||||||
opts,
|
opts,
|
||||||
orientation:
|
orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
|
||||||
orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
|
|
||||||
scrollPrev,
|
scrollPrev,
|
||||||
scrollNext,
|
scrollNext,
|
||||||
canScrollPrev,
|
canScrollPrev,
|
||||||
canScrollNext,
|
canScrollNext,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div ref={ref} onKeyDownCapture={handleKeyDown} className={cn("relative", className)} role="region" aria-roledescription="carousel" {...props}>
|
||||||
ref={ref}
|
|
||||||
onKeyDownCapture={handleKeyDown}
|
|
||||||
className={cn("relative", className)}
|
|
||||||
role="region"
|
|
||||||
aria-roledescription="carousel"
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</CarouselContext.Provider>
|
</CarouselContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
Carousel.displayName = "Carousel";
|
Carousel.displayName = "Carousel";
|
||||||
|
|
||||||
const CarouselContent = React.forwardRef<
|
const CarouselContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => {
|
||||||
HTMLDivElement,
|
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
|
||||||
>(({ className, ...props }, ref) => {
|
|
||||||
const { carouselRef, orientation } = useCarousel();
|
const { carouselRef, orientation } = useCarousel();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={carouselRef} className="overflow-hidden">
|
<div ref={carouselRef} className="overflow-hidden">
|
||||||
<div
|
<div ref={ref} className={cn("flex", orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col", className)} {...props} />
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"flex",
|
|
||||||
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
CarouselContent.displayName = "CarouselContent";
|
CarouselContent.displayName = "CarouselContent";
|
||||||
|
|
||||||
const CarouselItem = React.forwardRef<
|
const CarouselItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => {
|
||||||
HTMLDivElement,
|
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
|
||||||
>(({ className, ...props }, ref) => {
|
|
||||||
const { orientation } = useCarousel();
|
const { orientation } = useCarousel();
|
||||||
|
|
||||||
return (
|
return <div ref={ref} role="group" aria-roledescription="slide" className={cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4", className)} {...props} />;
|
||||||
<div
|
|
||||||
ref={ref}
|
|
||||||
role="group"
|
|
||||||
aria-roledescription="slide"
|
|
||||||
className={cn(
|
|
||||||
"min-w-0 shrink-0 grow-0 basis-full",
|
|
||||||
orientation === "horizontal" ? "pl-4" : "pt-4",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
CarouselItem.displayName = "CarouselItem";
|
CarouselItem.displayName = "CarouselItem";
|
||||||
|
|
||||||
const CarouselPrevious = React.forwardRef<
|
const CarouselPrevious = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
|
||||||
HTMLButtonElement,
|
|
||||||
React.ComponentProps<typeof Button>
|
|
||||||
>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
|
|
||||||
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -205,13 +150,7 @@ const CarouselPrevious = React.forwardRef<
|
||||||
ref={ref}
|
ref={ref}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
size={size}
|
size={size}
|
||||||
className={cn(
|
className={cn("absolute h-6 w-6 rounded-full text-white bg-black -ml-6", orientation === "horizontal" ? "-left-0 top-1/2 -translate-y-1/2" : "-top-0 left-1/2 -translate-x-1/2 rotate-90", className)}
|
||||||
"absolute h-6 w-6 rounded-full text-white bg-black -ml-6",
|
|
||||||
orientation === "horizontal"
|
|
||||||
? "-left-0 top-1/2 -translate-y-1/2"
|
|
||||||
: "-top-0 left-1/2 -translate-x-1/2 rotate-90",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
disabled={!canScrollPrev}
|
disabled={!canScrollPrev}
|
||||||
onClick={scrollPrev}
|
onClick={scrollPrev}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
@ -223,10 +162,7 @@ const CarouselPrevious = React.forwardRef<
|
||||||
});
|
});
|
||||||
CarouselPrevious.displayName = "CarouselPrevious";
|
CarouselPrevious.displayName = "CarouselPrevious";
|
||||||
|
|
||||||
const CarouselNext = React.forwardRef<
|
const CarouselNext = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
|
||||||
HTMLButtonElement,
|
|
||||||
React.ComponentProps<typeof Button>
|
|
||||||
>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
|
|
||||||
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -234,13 +170,7 @@ const CarouselNext = React.forwardRef<
|
||||||
ref={ref}
|
ref={ref}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
size={size}
|
size={size}
|
||||||
className={cn(
|
className={cn("absolute h-6 w-6 rounded-full bg-black text-white -mr-6", orientation === "horizontal" ? "-right-0 top-1/2 -translate-y-1/2" : "-bottom-0 left-1/2 -translate-x-1/2 rotate-90", className)}
|
||||||
"absolute h-6 w-6 rounded-full bg-black text-white -mr-4",
|
|
||||||
orientation === "horizontal"
|
|
||||||
? "-right-0 top-1/2 -translate-y-1/2"
|
|
||||||
: "-bottom-0 left-1/2 -translate-x-1/2 rotate-90",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
disabled={!canScrollNext}
|
disabled={!canScrollNext}
|
||||||
onClick={scrollNext}
|
onClick={scrollNext}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
@ -252,11 +182,4 @@ const CarouselNext = React.forwardRef<
|
||||||
});
|
});
|
||||||
CarouselNext.displayName = "CarouselNext";
|
CarouselNext.displayName = "CarouselNext";
|
||||||
|
|
||||||
export {
|
export { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
|
||||||
type CarouselApi,
|
|
||||||
Carousel,
|
|
||||||
CarouselContent,
|
|
||||||
CarouselItem,
|
|
||||||
CarouselPrevious,
|
|
||||||
CarouselNext,
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -433,7 +433,6 @@
|
||||||
"terms": "Terms and Conditions",
|
"terms": "Terms and Conditions",
|
||||||
"enterOTP": "Enter OTP Code",
|
"enterOTP": "Enter OTP Code",
|
||||||
"checkInbox": "Please check your email inbox or spam box.",
|
"checkInbox": "Please check your email inbox or spam box.",
|
||||||
"resending": "Resending",
|
|
||||||
"fullName": "Full Name",
|
"fullName": "Full Name",
|
||||||
"enterFullName": "Insert your full name",
|
"enterFullName": "Insert your full name",
|
||||||
"enterUsername": "Insert your Username",
|
"enterUsername": "Insert your Username",
|
||||||
|
|
@ -545,7 +544,8 @@
|
||||||
"answer4": "MediaHub is a platform that provides various informative and educational content. Key features include search, download, and personalization of content.",
|
"answer4": "MediaHub is a platform that provides various informative and educational content. Key features include search, download, and personalization of content.",
|
||||||
"welcome": "Welcome To",
|
"welcome": "Welcome To",
|
||||||
"polda": "Official coverage sourced from Polri activities at Polda",
|
"polda": "Official coverage sourced from Polri activities at Polda",
|
||||||
"satker": "Official coverage sourced from Polri activities at Satker"
|
"satker": "Official coverage sourced from Polri activities at Satker",
|
||||||
|
"resending": "Resending"
|
||||||
},
|
},
|
||||||
"FilterPage": {
|
"FilterPage": {
|
||||||
"image": "Image",
|
"image": "Image",
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,6 @@
|
||||||
"terms": "Syarat dan Ketentuan",
|
"terms": "Syarat dan Ketentuan",
|
||||||
"enterOTP": "Masukkan kode OTP",
|
"enterOTP": "Masukkan kode OTP",
|
||||||
"checkInbox": "Silahkan cek inbox atau kotak spam pada email Anda.",
|
"checkInbox": "Silahkan cek inbox atau kotak spam pada email Anda.",
|
||||||
"resending": "Kirim Ulang",
|
|
||||||
"fullName": "Nama Lengkap",
|
"fullName": "Nama Lengkap",
|
||||||
"enterFullName": "Masukkan Nama Lengkap Anda",
|
"enterFullName": "Masukkan Nama Lengkap Anda",
|
||||||
"enterUsername": "Masukkan Username Anda",
|
"enterUsername": "Masukkan Username Anda",
|
||||||
|
|
@ -546,7 +545,8 @@
|
||||||
"answer4": "MediaHub adalah platform yang menyediakan berbagai konten informatif dan edukatif. Fitur utama meliputi pencarian, pengunduhan, dan personalisasi konten.",
|
"answer4": "MediaHub adalah platform yang menyediakan berbagai konten informatif dan edukatif. Fitur utama meliputi pencarian, pengunduhan, dan personalisasi konten.",
|
||||||
"welcome": "Selamat Datang di",
|
"welcome": "Selamat Datang di",
|
||||||
"polda": "Liputan resmi yang bersumber dari kegiatan Polri di Polda",
|
"polda": "Liputan resmi yang bersumber dari kegiatan Polri di Polda",
|
||||||
"satker": "Liputan resmi yang bersumber dari kegiatan Polri di Satker"
|
"satker": "Liputan resmi yang bersumber dari kegiatan Polri di Satker",
|
||||||
|
"resending": "Kirim Ulang"
|
||||||
},
|
},
|
||||||
"FilterPage": {
|
"FilterPage": {
|
||||||
"image": "Foto",
|
"image": "Foto",
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 147 KiB |
Loading…
Reference in New Issue