fix: input search in all content, add menu sidebar in polda and satker approver

This commit is contained in:
Sabda Yagra 2025-11-10 22:06:43 +07:00
parent eaa1628fde
commit 5b6ffd0863
6 changed files with 236 additions and 180 deletions

View File

@ -60,7 +60,7 @@ const TableAudio = () => {
const [showData, setShowData] = React.useState("10");
const [page, setPage] = React.useState(1);
const [search, setSearch] = React.useState("");
const searchTimeout = React.useRef<NodeJS.Timeout | null>(null);
const [searchTimeout, setSearchTimeout] = React.useState<any>(null);
const [categories, setCategories] = React.useState<any[]>([]);
const [selectedCategories, setSelectedCategories] = React.useState<number[]>(
[]
@ -121,7 +121,7 @@ const TableAudio = () => {
filterByCreator,
filterBySource,
filterByCreatorGroup,
search,
// search,
showData,
page,
]);
@ -183,14 +183,30 @@ const TableAudio = () => {
}
}
// ✅ Debounced search
// const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
// const value = e.target.value;
// setSearch(value);
// if (searchTimeout.current) clearTimeout(searchTimeout.current);
// searchTimeout.current = setTimeout(() => {
// fetchData(true, value);
// }, 500);
// };
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setSearch(value);
if (searchTimeout.current) clearTimeout(searchTimeout.current);
searchTimeout.current = setTimeout(() => {
// Hapus timer lama
if (searchTimeout) {
clearTimeout(searchTimeout);
}
// Set timer baru untuk 3 detik
const timeout = setTimeout(() => {
fetchData(true, value);
}, 500);
}, 2000);
setSearchTimeout(timeout);
};
const handleSearchFilterBySource = (
@ -249,15 +265,15 @@ const TableAudio = () => {
<div className="w-full overflow-x-auto">
<div className="flex flex-col md:flex-row md:justify-between items-center md:px-5">
{/* 🔍 Search bar */}
<div className="w-full md:w-[250px] px-2">
<div className="w-full md:w-[200px] lg:w-[300px] px-2">
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className="h-4 w-4 dark:text-white" />
<Search className="h-6 w-6 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Cari Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white text-[16px]"
value={search}
onChange={handleSearch}
/>

View File

@ -62,6 +62,7 @@ const TableImage = () => {
const [showData, setShowData] = React.useState("10");
const [page, setPage] = React.useState(1);
const [search, setSearch] = React.useState("");
const [searchTimeout, setSearchTimeout] = React.useState<any>(null);
// === FILTER STATES ===
const [categories, setCategories] = React.useState<any[]>([]);
@ -120,7 +121,7 @@ const TableImage = () => {
filterByCreator,
filterBySource,
filterByCreatorGroup,
search,
// search,
showData,
page,
]);
@ -209,10 +210,27 @@ const TableImage = () => {
);
};
// const handleSearch: any = (e: React.ChangeEvent<HTMLInputElement>) => {
// const value = e.target.value;
// setSearch(value);
// fetchData(true, value);
// };
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setSearch(value);
fetchData(true, value);
// Hapus timer lama
if (searchTimeout) {
clearTimeout(searchTimeout);
}
// Set timer baru untuk 3 detik
const timeout = setTimeout(() => {
fetchData(true, value);
}, 2000);
setSearchTimeout(timeout);
};
const handleSearchFilterByCreator = (
@ -247,15 +265,15 @@ const TableImage = () => {
<div className="w-full overflow-x-auto">
{/* 🔍 FILTER & SEARCH BAR */}
<div className="flex flex-col md:flex-row lg:flex-row md:justify-between lg:justify-between items-center md:px-5 lg:px-5">
<div className="w-full md:w-[200px] lg:w-[200px] px-2">
<div className="w-full md:w-[200px] lg:w-[300px] px-2">
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className="h-4 w-4 dark:text-white" />
<Search className="h-6 w-6 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Cari Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white text-[16px]"
value={search}
onChange={handleSearch}
/>

View File

@ -247,15 +247,15 @@ const TableSPIT = () => {
return (
<div className="w-full">
<div className="flex justify-between items-center px-5">
<div className="w-[150px] md:w-[250px] lg:w-[250px]">
<div className="w-[150px] md:w-[250px] lg:w-[300px]">
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
<Search className=" h-6 w-6 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white text-[16px]"
value={search}
onChange={handleSearch}
/>

View File

@ -61,7 +61,7 @@ const TableTeks = () => {
const [showData, setShowData] = React.useState("10");
const [page, setPage] = React.useState(1);
const [search, setSearch] = React.useState("");
const searchTimeout = React.useRef<NodeJS.Timeout | null>(null);
const [searchTimeout, setSearchTimeout] = React.useState<any>(null);
// === FILTER STATES ===
const [categories, setCategories] = React.useState<any[]>([]);
@ -125,7 +125,7 @@ const TableTeks = () => {
filterByCreator,
filterBySource,
filterByCreatorGroup,
search,
// search,
showData,
page,
]);
@ -187,14 +187,30 @@ const TableTeks = () => {
}
}
// ✅ Debounced search
// const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
// const value = e.target.value;
// setSearch(value);
// if (searchTimeout.current) clearTimeout(searchTimeout.current);
// searchTimeout.current = setTimeout(() => {
// fetchData(true, value);
// }, 500);
// };
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setSearch(value);
if (searchTimeout.current) clearTimeout(searchTimeout.current);
searchTimeout.current = setTimeout(() => {
// Hapus timer lama
if (searchTimeout) {
clearTimeout(searchTimeout);
}
// Set timer baru untuk 3 detik
const timeout = setTimeout(() => {
fetchData(true, value);
}, 500);
}, 2000);
setSearchTimeout(timeout);
};
const handleSearchFilterBySource = (
@ -253,15 +269,15 @@ const TableTeks = () => {
<div className="w-full overflow-x-auto">
<div className="flex flex-col md:flex-row md:justify-between items-center md:px-5">
{/* 🔍 Search bar */}
<div className="w-full md:w-[250px] px-2">
<div className="w-full md:w-[200px] lg:w-[300px] px-2">
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className="h-4 w-4 dark:text-white" />
<Search className="h-6 w-6 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Cari Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white text-[16px]"
value={search}
onChange={handleSearch}
/>

View File

@ -62,7 +62,7 @@ const TableVideo = () => {
const [showData, setShowData] = React.useState("10");
const [page, setPage] = React.useState(1);
const [search, setSearch] = React.useState("");
const searchTimeout = React.useRef<NodeJS.Timeout | null>(null);
const [searchTimeout, setSearchTimeout] = React.useState<any>(null);
// === FILTER STATES ===
const [categories, setCategories] = React.useState<any[]>([]);
@ -126,7 +126,7 @@ const TableVideo = () => {
filterByCreator,
filterBySource,
filterByCreatorGroup,
search,
// search,
showData,
page,
]);
@ -214,14 +214,32 @@ const TableVideo = () => {
);
}
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setSearch(value);
if (searchTimeout.current) clearTimeout(searchTimeout.current);
searchTimeout.current = setTimeout(() => {
fetchData(true, value);
}, 500);
};
// const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
// const value = e.target.value;
// setSearch(value);
// if (searchTimeout.current) clearTimeout(searchTimeout.current);
// searchTimeout.current = setTimeout(() => {
// fetchData(true, value);
// }, 500);
// };
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setSearch(value);
// Hapus timer lama
if (searchTimeout) {
clearTimeout(searchTimeout);
}
// Set timer baru untuk 3 detik
const timeout = setTimeout(() => {
fetchData(true, value);
}, 2000);
setSearchTimeout(timeout);
};
const handleSearchFilterByCreator = (
e: React.ChangeEvent<HTMLInputElement>
@ -257,15 +275,15 @@ const TableVideo = () => {
<div className="w-full overflow-x-auto">
<div className="flex flex-col md:flex-row md:justify-between items-center md:px-5">
{/* 🔍 Search bar */}
<div className="w-full md:w-[250px] px-2">
<div className="w-full md:w-[200px] lg:w-[300px] px-2">
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className="h-4 w-4 dark:text-white" />
<Search className="h-6 w-6 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Cari Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white text-[16px]"
value={search}
onChange={handleSearch}
/>

View File

@ -2642,9 +2642,8 @@ export function getMenuList(pathname: string, t: any): Group[] {
(Number(roleId) == 3 || Number(roleId) == 14 || Number(roleId) == 15) &&
Number(levelNumber) == 3
) {
const hideForRole3 = Number(roleId) === 3;
if (Number(userParentLevelId) != 761) {
if (Number(userParentLevelId) != 761)
{
menusSelected = [
{
groupLabel: t("apps"),
@ -2699,17 +2698,15 @@ export function getMenuList(pathname: string, t: any): Group[] {
icon: "heroicons:share",
children: [],
},
...(!hideForRole3
? [
{
href: "/contributor/content/spit",
label: "spit",
active: pathname.includes("/content/spit"),
icon: "heroicons:credit-card",
children: [],
},
]
: []),
// {
// href: "/contributor/content/spit",
// label: "spit",
// active: pathname.includes("/content/spit"),
// icon: "heroicons:credit-card",
// children: [],
// },
// {
// href: "/contributor/content/nulis-ai",
// label: "nulis ai",
@ -2735,39 +2732,36 @@ export function getMenuList(pathname: string, t: any): Group[] {
},
],
},
...(!hideForRole3
? [
{
groupLabel: "",
id: "planning",
menus: [
{
id: "planning",
href: "/contributor/planning",
label: t("planning"),
active: pathname.includes("/planning"),
icon: "pajamas:planning",
submenus: [
{
href: "/contributor/planning/mediahub",
label: "mediaHub",
active: pathname.includes("/planning/mediahub"),
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/contributor/planning/medsos-mediahub",
label: "medsos mediahub",
active: pathname.includes("/planning/medsos-mediahub"),
icon: "heroicons:shopping-cart",
children: [],
},
],
},
],
},
]
: []),
// {
// groupLabel: "",
// id: "planning",
// menus: [
// {
// id: "planning",
// href: "/contributor/planning",
// label: t("planning"),
// active: pathname.includes("/planning"),
// icon: "pajamas:planning",
// submenus: [
// {
// href: "/contributor/planning/mediahub",
// label: "mediaHub",
// active: pathname.includes("/planning/mediahub"),
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "/contributor/planning/medsos-mediahub",
// label: "medsos mediahub",
// active: pathname.includes("/planning/medsos-mediahub"),
// icon: "heroicons:shopping-cart",
// children: [],
// },
// ],
// },
// ],
// },
{
groupLabel: "",
id: "task",
@ -2818,24 +2812,21 @@ export function getMenuList(pathname: string, t: any): Group[] {
},
],
},
...(!hideForRole3
? [
{
groupLabel: "",
id: "blog",
menus: [
{
id: "blog",
href: "/contributor/blog",
label: t("blog"),
active: pathname.includes("/blog"),
icon: "fluent:clipboard-text-32-regular",
submenus: [],
},
],
},
]
: []),
// {
// groupLabel: "",
// id: "blog",
// menus: [
// {
// id: "blog",
// href: "/contributor/blog",
// label: t("blog"),
// active: pathname.includes("/blog"),
// icon: "fluent:clipboard-text-32-regular",
// submenus: [],
// },
// ],
// },
{
groupLabel: "",
id: "curatedcontent",
@ -2878,46 +2869,43 @@ export function getMenuList(pathname: string, t: any): Group[] {
},
],
},
...(!hideForRole3
? [
{
groupLabel: "",
id: "settings",
menus: [
{
id: "settings",
href: "/admin/settings",
label: t("settings"),
active: pathname.includes("/settinng"),
icon: "material-symbols:settings",
submenus: [
{
href: "/admin/settings/banner",
label: "Banner",
active: pathname === "/admin/settings/banner",
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/admin/settings/popup",
label: "Pop Up",
active: pathname === "/admin/settings/popup",
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/admin/settings/iklan",
label: "Iklan",
active: pathname === "/admin/settings/iklan",
icon: "heroicons:arrow-trending-up",
children: [],
},
],
},
],
},
]
: []),
// {
// groupLabel: "",
// id: "settings",
// menus: [
// {
// id: "settings",
// href: "/admin/settings",
// label: t("settings"),
// active: pathname.includes("/settinng"),
// icon: "material-symbols:settings",
// submenus: [
// {
// href: "/admin/settings/banner",
// label: "Banner",
// active: pathname === "/admin/settings/banner",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "/admin/settings/popup",
// label: "Pop Up",
// active: pathname === "/admin/settings/popup",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "/admin/settings/iklan",
// label: "Iklan",
// active: pathname === "/admin/settings/iklan",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// ],
// },
// ],
// },
];
} else if (Number(userParentLevelId) == 761) {
menusSelected = [
@ -3141,42 +3129,42 @@ export function getMenuList(pathname: string, t: any): Group[] {
},
],
},
// {
// groupLabel: "",
// id: "settings",
// menus: [
// {
// id: "settings",
// href: "/admin/settings",
// label: t("settings"),
// active: pathname.includes("/settinng"),
// icon: "material-symbols:settings",
// submenus: [
// {
// href: "/admin/settings/banner",
// label: "Banner",
// active: pathname === "/admin/settings/banner",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "/admin/settings/popup",
// label: "Pop Up",
// active: pathname === "/admin/settings/popup",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// {
// href: "/admin/settings/iklan",
// label: "Iklan",
// active: pathname === "/admin/settings/iklan",
// icon: "heroicons:arrow-trending-up",
// children: [],
// },
// ],
// },
// ],
// },
{
groupLabel: "",
id: "settings",
menus: [
{
id: "settings",
href: "/admin/settings",
label: t("settings"),
active: pathname.includes("/settinng"),
icon: "material-symbols:settings",
submenus: [
{
href: "/admin/settings/banner",
label: "Banner",
active: pathname === "/admin/settings/banner",
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/admin/settings/popup",
label: "Pop Up",
active: pathname === "/admin/settings/popup",
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/admin/settings/iklan",
label: "Iklan",
active: pathname === "/admin/settings/iklan",
icon: "heroicons:arrow-trending-up",
children: [],
},
],
},
],
},
];
}
} else if (Number(roleId) == 9) {