Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod
This commit is contained in:
commit
166c3c8143
|
|
@ -2,7 +2,7 @@ import * as React from "react";
|
||||||
import { ColumnDef } from "@tanstack/react-table";
|
import { ColumnDef } from "@tanstack/react-table";
|
||||||
|
|
||||||
import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
|
import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn, getCookiesDecrypt } from "@/lib/utils";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
|
|
@ -78,7 +78,7 @@ const columns: ColumnDef<any>[] = [
|
||||||
enableHiding: false,
|
enableHiding: false,
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
|
const levelNumber = getCookiesDecrypt("ulne");
|
||||||
async function doDelete(id: any) {
|
async function doDelete(id: any) {
|
||||||
// loading();
|
// loading();
|
||||||
const data = {
|
const data = {
|
||||||
|
|
@ -132,7 +132,7 @@ const columns: ColumnDef<any>[] = [
|
||||||
<MoreVertical className="h-4 w-4 text-default-800" />
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="p-0" align="end">
|
{/* <DropdownMenuContent className="p-0" align="end">
|
||||||
<Link href={`/admin/settings/iklan/detail/${row.original.id}`}>
|
<Link href={`/admin/settings/iklan/detail/${row.original.id}`}>
|
||||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
<Eye className="w-4 h-4 me-1.5" />
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
|
@ -152,6 +152,33 @@ const columns: ColumnDef<any>[] = [
|
||||||
<Trash2 className="w-4 h-4 me-1.5" />
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
Delete
|
Delete
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent> */}
|
||||||
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
|
<Link href={`/admin/settings/iklan/detail/${row.original.id}`}>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
View
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{levelNumber === "1" && (
|
||||||
|
<>
|
||||||
|
<Link href={`/admin/settings/iklan/update/${row.original.id}`}>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<SquarePen className="w-4 h-4 me-1.5" />
|
||||||
|
Edit
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => handleDeleteAdvertisements(row.original.id)}
|
||||||
|
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
|
||||||
|
>
|
||||||
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import {
|
||||||
UploadIcon,
|
UploadIcon,
|
||||||
UserIcon,
|
UserIcon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn, getCookiesDecrypt } from "@/lib/utils";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
|
|
@ -94,6 +94,9 @@ const AdvertisementsList = () => {
|
||||||
const [statusFilter, setStatusFilter] = React.useState<number[]>([]);
|
const [statusFilter, setStatusFilter] = React.useState<number[]>([]);
|
||||||
const [page, setPage] = React.useState(1);
|
const [page, setPage] = React.useState(1);
|
||||||
const [totalPage, setTotalPage] = React.useState(1);
|
const [totalPage, setTotalPage] = React.useState(1);
|
||||||
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
const levelNumber = getCookiesDecrypt("ulne");
|
||||||
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data: dataTable,
|
data: dataTable,
|
||||||
columns,
|
columns,
|
||||||
|
|
@ -203,23 +206,27 @@ const AdvertisementsList = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<div className="flex-none">
|
{levelNumber === "1" && (
|
||||||
<Button
|
<div className="flex-none">
|
||||||
disabled={dataTable.length == 4}
|
<Link href={"/admin/settings/iklan/create"}>
|
||||||
onClick={() => router.push("/admin/settings/iklan/create")}
|
<Button
|
||||||
color="primary"
|
disabled={dataTable.length == 4}
|
||||||
className="text-white"
|
color="primary"
|
||||||
size="md"
|
className="text-white"
|
||||||
>
|
size="md"
|
||||||
<UploadIcon size={18} className="mr-2" />
|
>
|
||||||
Tambah Iklan
|
<UploadIcon size={18} className="mr-2" />
|
||||||
</Button>
|
Tambah Iklan
|
||||||
{dataTable.length == 4 && (
|
</Button>
|
||||||
<p className="text-sm text-red-400 pt-1">
|
</Link>
|
||||||
Jumlah Iklan Sudah Maksimal (4)
|
{dataTable.length == 4 && (
|
||||||
</p>
|
<p className="text-sm text-red-400 pt-1">
|
||||||
)}
|
Jumlah Iklan Sudah Maksimal (4)
|
||||||
</div>
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* <TambahIklanModal /> */}
|
{/* <TambahIklanModal /> */}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between ">
|
<div className="flex justify-between ">
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
Trash2,
|
Trash2,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
|
|
@ -20,6 +20,7 @@ import { Link } from "@/components/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
const useTableColumns = () => {
|
const useTableColumns = () => {
|
||||||
const t = useTranslations("Table");
|
const t = useTranslations("Table");
|
||||||
|
|
@ -37,7 +38,6 @@ const useTableColumns = () => {
|
||||||
onCheckedChange={(val) => table.toggleAllPageRowsSelected(!!val)}
|
onCheckedChange={(val) => table.toggleAllPageRowsSelected(!!val)}
|
||||||
aria-label="Pilih semua pada halaman ini"
|
aria-label="Pilih semua pada halaman ini"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
),
|
),
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
@ -140,15 +140,23 @@ const useTableColumns = () => {
|
||||||
enableHiding: false,
|
enableHiding: false,
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const isDisabled = row.original.isPublish;
|
const isDisabled = row.original.isPublish;
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleClick = (e: React.MouseEvent) => {
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
console.log("Ctrl + Click detected");
|
||||||
|
}
|
||||||
|
// Paksa buka menu meskipun ctrl ditekan
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu open={open} onOpenChange={setOpen}>
|
||||||
<DropdownMenuTrigger asChild disabled={isDisabled}>
|
<DropdownMenuTrigger asChild disabled={isDisabled}>
|
||||||
<Button
|
<Button
|
||||||
size="icon"
|
size="icon"
|
||||||
className={`bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent ${
|
onClick={handleClick}
|
||||||
isDisabled ? "cursor-not-allowed opacity-50" : ""
|
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
|
||||||
}`}
|
|
||||||
disabled={isDisabled}
|
|
||||||
>
|
>
|
||||||
<span className="sr-only">Open menu</span>
|
<span className="sr-only">Open menu</span>
|
||||||
<MoreVertical className="h-4 w-4 text-default-800" />
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
|
|
@ -159,7 +167,7 @@ const useTableColumns = () => {
|
||||||
href={`/contributor/content/spit/convert/${row.original.contentId}`}
|
href={`/contributor/content/spit/convert/${row.original.contentId}`}
|
||||||
>
|
>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className={`p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none ${
|
className={`cursor-pointer p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none ${
|
||||||
isDisabled ? "cursor-not-allowed opacity-50" : ""
|
isDisabled ? "cursor-not-allowed opacity-50" : ""
|
||||||
}`}
|
}`}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import * as React from "react";
|
||||||
import { ColumnDef } from "@tanstack/react-table";
|
import { ColumnDef } from "@tanstack/react-table";
|
||||||
|
|
||||||
import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
|
import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn, getCookiesDecrypt } from "@/lib/utils";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
|
|
@ -206,6 +206,15 @@ const useTableColumns = () => {
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
const levelNumber = getCookiesDecrypt("ulne");
|
||||||
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
|
const contentLevelNumber =
|
||||||
|
row.original.createdBy?.userLevel?.levelNumber;
|
||||||
|
const isSameLevelOrLower =
|
||||||
|
levelNumber &&
|
||||||
|
contentLevelNumber &&
|
||||||
|
+levelNumber <= +contentLevelNumber;
|
||||||
|
|
||||||
async function deleteProcess(id: any) {
|
async function deleteProcess(id: any) {
|
||||||
loading();
|
loading();
|
||||||
|
|
@ -268,7 +277,24 @@ const useTableColumns = () => {
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{!isDone && (
|
{/* {!isDone && (
|
||||||
|
<>
|
||||||
|
<Link href={`/contributor/task/update/${row.original.id}`}>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<SquarePen className="w-4 h-4 me-1.5" />
|
||||||
|
Edit
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</Link>
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => TaskDelete(row.original.id)}
|
||||||
|
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
|
||||||
|
>
|
||||||
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</>
|
||||||
|
)} */}
|
||||||
|
{!isDone && isSameLevelOrLower && (
|
||||||
<>
|
<>
|
||||||
<Link href={`/contributor/task/update/${row.original.id}`}>
|
<Link href={`/contributor/task/update/${row.original.id}`}>
|
||||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ import FileUploader from "../shared/file-uploader";
|
||||||
import { Icon } from "@/components/ui/icon";
|
import { Icon } from "@/components/ui/icon";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { useRouter } from "@/i18n/routing";
|
||||||
|
|
||||||
const calendarSchema = z.object({
|
const calendarSchema = z.object({
|
||||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
|
@ -64,6 +65,7 @@ interface Detail {
|
||||||
|
|
||||||
export function TambahIklanDetail() {
|
export function TambahIklanDetail() {
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
|
const router = useRouter();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const t = useTranslations("Schedule");
|
const t = useTranslations("Schedule");
|
||||||
const { id } = useParams() as { id: string };
|
const { id } = useParams() as { id: string };
|
||||||
|
|
@ -376,6 +378,7 @@ export function TambahIklanDetail() {
|
||||||
].map(({ label, value }) => (
|
].map(({ label, value }) => (
|
||||||
<label key={value} className="flex items-center gap-2">
|
<label key={value} className="flex items-center gap-2">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
disabled
|
||||||
id={value}
|
id={value}
|
||||||
checked={selectedPlacement === value}
|
checked={selectedPlacement === value}
|
||||||
onCheckedChange={() => handlePlacementSelect(value)}
|
onCheckedChange={() => handlePlacementSelect(value)}
|
||||||
|
|
@ -506,6 +509,7 @@ export function TambahIklanDetail() {
|
||||||
name="title"
|
name="title"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Input
|
<Input
|
||||||
|
readOnly
|
||||||
size={"md"}
|
size={"md"}
|
||||||
type="text"
|
type="text"
|
||||||
value={detail?.title}
|
value={detail?.title}
|
||||||
|
|
@ -540,6 +544,7 @@ export function TambahIklanDetail() {
|
||||||
name="description"
|
name="description"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Textarea
|
<Textarea
|
||||||
|
readOnly
|
||||||
rows={3}
|
rows={3}
|
||||||
value={detail?.description}
|
value={detail?.description}
|
||||||
onChange={field.onChange}
|
onChange={field.onChange}
|
||||||
|
|
@ -554,12 +559,22 @@ export function TambahIklanDetail() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-right">
|
{/* <div className="text-right">
|
||||||
<Link href={"admin/settings/iklan"}>
|
<Link href={"admin/settings/iklan"}>
|
||||||
<Button type="button" variant={"outline"} color="primary">
|
<Button type="button" variant={"outline"} color="primary">
|
||||||
Kembali
|
Kembali
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
</div> */}
|
||||||
|
<div className="text-right">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => router.back()}
|
||||||
|
>
|
||||||
|
Kembali
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import FileUploader from "../shared/file-uploader";
|
||||||
import { Icon } from "@/components/ui/icon";
|
import { Icon } from "@/components/ui/icon";
|
||||||
import { close } from "@/config/swal";
|
import { close } from "@/config/swal";
|
||||||
import { listDataAdvertisements } from "@/service/broadcast/broadcast";
|
import { listDataAdvertisements } from "@/service/broadcast/broadcast";
|
||||||
|
import { useRouter } from "@/i18n/routing";
|
||||||
|
|
||||||
const calendarSchema = z.object({
|
const calendarSchema = z.object({
|
||||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
|
@ -54,6 +55,7 @@ interface FileUploaded {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TambahIklanModal() {
|
export function TambahIklanModal() {
|
||||||
|
const router = useRouter();
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const t = useTranslations("Schedule");
|
const t = useTranslations("Schedule");
|
||||||
|
|
@ -222,7 +224,7 @@ export function TambahIklanModal() {
|
||||||
text: "Iklan berhasil ditambahkan.",
|
text: "Iklan berhasil ditambahkan.",
|
||||||
confirmButtonText: "OK",
|
confirmButtonText: "OK",
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
window.location.reload();
|
router.push("/admin/settings/iklan");
|
||||||
});
|
});
|
||||||
|
|
||||||
Cookies.set("scheduleId", response?.data?.data.id, {
|
Cookies.set("scheduleId", response?.data?.data.id, {
|
||||||
|
|
|
||||||
|
|
@ -250,34 +250,38 @@ const Navbar = () => {
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
|
|
||||||
<PopoverContent className="flex flex-col gap-2 w-fit px-6 py-4 rounded-md shadow-md bg-white dark:bg-black">
|
<PopoverContent className="flex flex-col gap-2 w-fit px-6 py-4 rounded-md shadow-md bg-white dark:bg-black">
|
||||||
<button
|
<Link
|
||||||
onClick={() => router.push(prefixPath + "/image/filter")}
|
href={prefixPath + "/image/filter"}
|
||||||
|
// onClick={() => router.push(prefixPath + "/image/filter")}
|
||||||
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
>
|
>
|
||||||
<FiImage className="mr-2" />
|
<FiImage className="mr-2" />
|
||||||
{t("image", { defaultValue: "Image" })}
|
{t("image", { defaultValue: "Image" })}
|
||||||
</button>
|
</Link>
|
||||||
<button
|
<Link
|
||||||
onClick={() => router.push(prefixPath + "/video/filter")}
|
href={prefixPath + "/video/filter"}
|
||||||
|
// onClick={() => router.push(prefixPath + "/video/filter")}
|
||||||
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
>
|
>
|
||||||
<FiYoutube className="mr-2" />
|
<FiYoutube className="mr-2" />
|
||||||
{t("video", { defaultValue: "Video" })}
|
{t("video", { defaultValue: "Video" })}
|
||||||
</button>
|
</Link>
|
||||||
<button
|
<Link
|
||||||
onClick={() => router.push(prefixPath + "/document/filter")}
|
href={prefixPath + "/document/filter"}
|
||||||
|
// onClick={() => router.push(prefixPath + "/document/filter")}
|
||||||
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
>
|
>
|
||||||
<FiFile className="mr-2" />
|
<FiFile className="mr-2" />
|
||||||
{t("text", { defaultValue: "Text" })}
|
{t("text", { defaultValue: "Text" })}
|
||||||
</button>
|
</Link>
|
||||||
<button
|
<Link
|
||||||
onClick={() => router.push(prefixPath + "/audio/filter")}
|
href={prefixPath + "/audio/filter"}
|
||||||
|
// onClick={() => router.push(prefixPath + "/audio/filter")}
|
||||||
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
>
|
>
|
||||||
<FiMusic className="mr-2" />
|
<FiMusic className="mr-2" />
|
||||||
{t("audio", { defaultValue: "Audio" })}
|
{t("audio", { defaultValue: "Audio" })}
|
||||||
</button>
|
</Link>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
||||||
|
|
@ -399,7 +403,7 @@ const Navbar = () => {
|
||||||
<ThemeSwitcher />
|
<ThemeSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="hidden custom-lg-button:relative text-gray-600 dark:text-white ">
|
<div className=" custom-lg-button:relative text-gray-600 dark:text-white ">
|
||||||
{/* <input
|
{/* <input
|
||||||
value={onSearch}
|
value={onSearch}
|
||||||
onChange={(e) => setOnSearch(e.target.value)}
|
onChange={(e) => setOnSearch(e.target.value)}
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,10 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
<h2 className="flex items-center text-lg md:text-xl font-bold text-[#bb3523] border-b-2 border-[#bb3523] uppercase">
|
<h2 className="flex items-center text-lg md:text-xl font-bold text-[#bb3523] border-b-2 border-[#bb3523] uppercase">
|
||||||
{pathname?.split("/")[1] == "in" ? (
|
{pathname?.split("/")[1] == "in" ? (
|
||||||
<>
|
<>
|
||||||
<span className="text-[#bb3523] ">{t("content", { defaultValue: "Content" })}</span>
|
<span className="text-[#bb3523] ">
|
||||||
|
{t("content", { defaultValue: "Content" })}
|
||||||
|
</span>
|
||||||
|
|
||||||
{props.type == "popular"
|
{props.type == "popular"
|
||||||
? "Terpopuler"
|
? "Terpopuler"
|
||||||
: props.type == "latest"
|
: props.type == "latest"
|
||||||
|
|
@ -153,10 +156,22 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
|
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
|
||||||
<TabsList className="flex gap-2 bg-transparent p-0">
|
<TabsList className="flex gap-2 bg-transparent p-0">
|
||||||
{[
|
{[
|
||||||
{ label: t("image", { defaultValue: "Image" }), value: "image" },
|
{
|
||||||
{ label: t("video", { defaultValue: "Video" }), value: "video" },
|
label: t("image", { defaultValue: "Image" }),
|
||||||
{ label: t("text", { defaultValue: "Text" }), value: "document" },
|
value: "image",
|
||||||
{ label: t("audio", { defaultValue: "Audio" }), value: "audio" },
|
},
|
||||||
|
{
|
||||||
|
label: t("video", { defaultValue: "Video" }),
|
||||||
|
value: "video",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("text", { defaultValue: "Text" }),
|
||||||
|
value: "document",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("audio", { defaultValue: "Audio" }),
|
||||||
|
value: "audio",
|
||||||
|
},
|
||||||
].map((tab) => (
|
].map((tab) => (
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
key={tab.value}
|
key={tab.value}
|
||||||
|
|
@ -194,12 +209,12 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
className="md:basis-1/2 lg:basis-1/3"
|
className="md:basis-1/2 lg:basis-1/3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
// onClick={() =>
|
||||||
router.push(
|
// router.push(
|
||||||
prefixPath + `/image/detail/${image?.slug}`
|
// prefixPath + `/image/detail/${image?.slug}`
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
className="cursor-pointer relative group overflow-hidden bg-white dark:bg-black dark:border dark:border-gray-500 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300"
|
className="relative group overflow-hidden bg-white dark:bg-black dark:border dark:border-gray-500 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300"
|
||||||
>
|
>
|
||||||
{/* Image with motion effect */}
|
{/* Image with motion effect */}
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
@ -207,17 +222,24 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
whileHover={{ scale: 0.95 }}
|
whileHover={{ scale: 0.95 }}
|
||||||
transition={{ duration: 0.3 }}
|
transition={{ duration: 0.3 }}
|
||||||
>
|
>
|
||||||
<Image
|
<Link
|
||||||
priority={true}
|
href={
|
||||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
prefixPath + `/image/detail/${image?.slug}`
|
||||||
shimmer(700, 475)
|
}
|
||||||
)}`}
|
>
|
||||||
width={2560}
|
{" "}
|
||||||
height={1440}
|
<Image
|
||||||
alt="image"
|
priority={true}
|
||||||
src={image?.smallThumbnailLink}
|
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||||
className="w-full h-full object-cover"
|
shimmer(700, 475)
|
||||||
/>
|
)}`}
|
||||||
|
width={2560}
|
||||||
|
height={1440}
|
||||||
|
alt="image"
|
||||||
|
src={image?.smallThumbnailLink}
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Badge category */}
|
{/* Badge category */}
|
||||||
|
|
@ -248,15 +270,15 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
{image?.categoryName?.toUpperCase() ??
|
{image?.categoryName?.toUpperCase() ??
|
||||||
"Giat Pimpinan"}
|
"Giat Pimpinan"}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<Link
|
||||||
className="
|
href={
|
||||||
text-sm lg:text-base font-semibold text-black dark:text-white
|
prefixPath + `/image/detail/${image?.slug}`
|
||||||
line-clamp-4 /* LIMIT to 2 lines if plugin available */
|
}
|
||||||
/* or use min-h-[3rem] as fallback */
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{image?.title}
|
<p className="text-sm lg:text-base font-semibold text-black dark:text-white line-clamp-4">
|
||||||
</p>
|
{image?.title}
|
||||||
|
</p>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{/* Optional metadata area (uncomment if needed) */}
|
{/* Optional metadata area (uncomment if needed) */}
|
||||||
{/*
|
{/*
|
||||||
|
|
@ -271,7 +293,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
))}
|
))}
|
||||||
</CarouselContent>
|
</CarouselContent>
|
||||||
|
|
||||||
<div className="flex justify-center mt-4">
|
<div className="flex justify-center mt-2">
|
||||||
{Array.from({ length: count }).map((_, index) => (
|
{Array.from({ length: count }).map((_, index) => (
|
||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
|
|
@ -290,7 +312,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
) : (
|
) : (
|
||||||
<p className="flex items-center justify-center">
|
<p className="flex items-center justify-center">
|
||||||
<Image
|
<Image
|
||||||
priority={true}
|
priority={true}
|
||||||
width={1920}
|
width={1920}
|
||||||
height={1080}
|
height={1080}
|
||||||
src="/assets/empty-data.png"
|
src="/assets/empty-data.png"
|
||||||
|
|
@ -308,13 +330,14 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
key={audio?.id}
|
key={audio?.id}
|
||||||
className="md:basis-1/2 lg:basis-1/3"
|
className="md:basis-1/2 lg:basis-1/3"
|
||||||
>
|
>
|
||||||
<div
|
<Link
|
||||||
onClick={() =>
|
href={prefixPath + `/audio/detail/${audio?.slug}`}
|
||||||
router.push(
|
// onClick={() =>
|
||||||
prefixPath + `/audio/detail/${audio?.slug}`
|
// router.push(
|
||||||
)
|
// prefixPath + `/audio/detail/${audio?.slug}`
|
||||||
}
|
// )
|
||||||
className="cursor-pointer bg-white dark:bg-black dark:border dark:border-gray-500 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden"
|
// }
|
||||||
|
className="bg-white dark:bg-black dark:border dark:border-gray-500 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden"
|
||||||
>
|
>
|
||||||
{/* Icon Background */}
|
{/* Icon Background */}
|
||||||
<div className="flex items-center justify-center bg-[#bb3523] w-full h-[170px] text-white">
|
<div className="flex items-center justify-center bg-[#bb3523] w-full h-[170px] text-white">
|
||||||
|
|
@ -347,7 +370,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
<Icon icon="formkit:eye" width="15" height="15" /> {audio?.clickCount}
|
<Icon icon="formkit:eye" width="15" height="15" /> {audio?.clickCount}
|
||||||
</p> */}
|
</p> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Link>
|
||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
))}
|
))}
|
||||||
</CarouselContent>
|
</CarouselContent>
|
||||||
|
|
@ -371,7 +394,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
) : (
|
) : (
|
||||||
<p className="flex items-center justify-center">
|
<p className="flex items-center justify-center">
|
||||||
<Image
|
<Image
|
||||||
priority={true}
|
priority={true}
|
||||||
width={1920}
|
width={1920}
|
||||||
height={1080}
|
height={1080}
|
||||||
src="/assets/empty-data.png"
|
src="/assets/empty-data.png"
|
||||||
|
|
@ -390,12 +413,12 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
className="md:basis-1/2 lg:basis-1/3"
|
className="md:basis-1/2 lg:basis-1/3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
// onClick={() =>
|
||||||
router.push(
|
// router.push(
|
||||||
prefixPath + `/video/detail/${video?.slug}`
|
// prefixPath + `/video/detail/${video?.slug}`
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
className="cursor-pointer relative group overflow-hidden bg-white dark:bg-black dark:border dark:border-gray-500 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300"
|
className="relative group overflow-hidden bg-white dark:bg-black dark:border dark:border-gray-500 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300"
|
||||||
>
|
>
|
||||||
{/* Image with motion effect */}
|
{/* Image with motion effect */}
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
@ -403,17 +426,23 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
whileHover={{ scale: 0.95 }}
|
whileHover={{ scale: 0.95 }}
|
||||||
transition={{ duration: 0.3 }}
|
transition={{ duration: 0.3 }}
|
||||||
>
|
>
|
||||||
<Image
|
<Link
|
||||||
priority={true}
|
href={
|
||||||
placeholder={`data:image/svg+xml;base64,${toBase64(
|
prefixPath + `/video/detail/${video?.slug}`
|
||||||
shimmer(700, 475)
|
}
|
||||||
)}`}
|
>
|
||||||
alt="video"
|
<Image
|
||||||
width={2560}
|
priority={true}
|
||||||
height={1440}
|
placeholder={`data:image/svg+xml;base64,${toBase64(
|
||||||
src={video?.smallThumbnailLink}
|
shimmer(700, 475)
|
||||||
className="w-full h-full object-cover"
|
)}`}
|
||||||
/>
|
alt="video"
|
||||||
|
width={2560}
|
||||||
|
height={1440}
|
||||||
|
src={video?.smallThumbnailLink}
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Badge category */}
|
{/* Badge category */}
|
||||||
|
|
@ -444,10 +473,15 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
{video?.categoryName?.toUpperCase() ??
|
{video?.categoryName?.toUpperCase() ??
|
||||||
"Giat Pimpinan"}
|
"Giat Pimpinan"}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<Link
|
||||||
className="text-sm lg:text-base font-semibold text-black dark:text-white line-clamp-5">
|
href={
|
||||||
{video?.title}
|
prefixPath + `/video/detail/${video?.slug}`
|
||||||
</p>
|
}
|
||||||
|
>
|
||||||
|
<p className="text-sm lg:text-base font-semibold text-black dark:text-white line-clamp-5">
|
||||||
|
{video?.title}
|
||||||
|
</p>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{/* Optional metadata area (uncomment if needed) */}
|
{/* Optional metadata area (uncomment if needed) */}
|
||||||
{/*
|
{/*
|
||||||
|
|
@ -482,7 +516,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
) : (
|
) : (
|
||||||
<p className="flex items-center justify-center">
|
<p className="flex items-center justify-center">
|
||||||
<Image
|
<Image
|
||||||
priority={true}
|
priority={true}
|
||||||
width={1920}
|
width={1920}
|
||||||
height={1080}
|
height={1080}
|
||||||
src="/assets/empty-data.png"
|
src="/assets/empty-data.png"
|
||||||
|
|
@ -500,15 +534,18 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
className="md:basis-1/2 lg:basis-1/3"
|
className="md:basis-1/2 lg:basis-1/3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
// onClick={() =>
|
||||||
router.push(
|
// router.push(
|
||||||
prefixPath + `/document/detail/${text?.slug}`
|
// prefixPath + `/document/detail/${text?.slug}`
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
className="cursor-pointer rounded-lg shadow-md overflow-hidden bg-white dark:bg-black dark:border dark:border-gray-500"
|
className="rounded-lg shadow-md overflow-hidden bg-white dark:bg-black dark:border dark:border-gray-500"
|
||||||
>
|
>
|
||||||
{/* Ikon di tengah dengan latar kuning */}
|
{/* Ikon di tengah dengan latar kuning */}
|
||||||
<div className="bg-[#e0c350] flex items-center justify-center h-[170px] text-white">
|
<Link
|
||||||
|
href={prefixPath + `/document/detail/${text?.slug}`}
|
||||||
|
className="bg-[#e0c350] flex items-center justify-center h-[170px] text-white"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="150"
|
width="150"
|
||||||
|
|
@ -520,7 +557,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
d="M5 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V5.414a1.5 1.5 0 0 0-.44-1.06L9.647 1.439A1.5 1.5 0 0 0 8.586 1zM4 3a1 1 0 0 1 1-1h3v2.5A1.5 1.5 0 0 0 9.5 6H12v7a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1zm7.793 2H9.5a.5.5 0 0 1-.5-.5V2.207zM7 7.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M7.5 9a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM7 11.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M5.5 8a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1M6 9.5a.5.5 0 1 1-1 0a.5.5 0 0 1 1 0M5.5 12a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1"
|
d="M5 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V5.414a1.5 1.5 0 0 0-.44-1.06L9.647 1.439A1.5 1.5 0 0 0 8.586 1zM4 3a1 1 0 0 1 1-1h3v2.5A1.5 1.5 0 0 0 9.5 6H12v7a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1zm7.793 2H9.5a.5.5 0 0 1-.5-.5V2.207zM7 7.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M7.5 9a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM7 11.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M5.5 8a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1M6 9.5a.5.5 0 1 1-1 0a.5.5 0 0 1 1 0M5.5 12a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</Link>
|
||||||
|
|
||||||
{/* Konten bawah */}
|
{/* Konten bawah */}
|
||||||
<div className="p-4 flex flex-col gap-2">
|
<div className="p-4 flex flex-col gap-2">
|
||||||
|
|
@ -530,10 +567,15 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Judul */}
|
{/* Judul */}
|
||||||
<div className="font-semibold text-gray-900 dark:text-white text-xl leading-snug line-clamp-4">
|
<Link
|
||||||
{text?.title}
|
href={
|
||||||
</div>
|
prefixPath + `/document/detail/${text?.slug}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<p className="font-semibold text-gray-900 dark:text-white text-xl leading-snug line-clamp-4">
|
||||||
|
{text?.title}
|
||||||
|
</p>
|
||||||
|
</Link>
|
||||||
{/* Meta info */}
|
{/* Meta info */}
|
||||||
{/* <div className="text-gray-500 flex items-center text-xs gap-2">
|
{/* <div className="text-gray-500 flex items-center text-xs gap-2">
|
||||||
<span>
|
<span>
|
||||||
|
|
@ -579,7 +621,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
) : (
|
) : (
|
||||||
<p className="flex items-center justify-center">
|
<p className="flex items-center justify-center">
|
||||||
<Image
|
<Image
|
||||||
priority={true}
|
priority={true}
|
||||||
width={1920}
|
width={1920}
|
||||||
height={1080}
|
height={1080}
|
||||||
src="/assets/empty-data.png"
|
src="/assets/empty-data.png"
|
||||||
|
|
@ -592,9 +634,17 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center flex-row justify-center mt-3">
|
<div className="flex items-center flex-row justify-center mt-3">
|
||||||
<div onClick={() => router.push(prefixPath + `/${selectedTab}/filter?sortBy=${props.type}`)} className="cursor-pointer border text-[#bb3523] rounded-lg text-sm lg:text-md px-4 py-1 border-[#bb3523] hover:text-white hover:bg-[#bb3523]">
|
<Link
|
||||||
|
href={prefixPath + `/${selectedTab}/filter?sortBy=${props.type}`}
|
||||||
|
// onClick={() =>
|
||||||
|
// router.push(
|
||||||
|
// prefixPath + `/${selectedTab}/filter?sortBy=${props.type}`
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
className="cursor-pointer border text-[#bb3523] rounded-lg text-sm lg:text-md px-4 py-1 border-[#bb3523] hover:text-white hover:bg-[#bb3523]"
|
||||||
|
>
|
||||||
{t("seeAll", { defaultValue: "See All" })}
|
{t("seeAll", { defaultValue: "See All" })}
|
||||||
</div>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue