merge
This commit is contained in:
commit
a98d16008c
|
|
@ -58,16 +58,6 @@ const columns: ColumnDef<any>[] = [
|
||||||
<span>{formatDateToIndonesian(row.getValue("createdAt"))}</span>
|
<span>{formatDateToIndonesian(row.getValue("createdAt"))}</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
accessorKey: "isStaticBanner",
|
|
||||||
header: "Static Banner",
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<StaticToogle
|
|
||||||
id={row.original.id}
|
|
||||||
initChecked={row.original.isStaticBanner}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
accessorKey: "statusName",
|
accessorKey: "statusName",
|
||||||
header: "Status Banner",
|
header: "Status Banner",
|
||||||
|
|
@ -75,7 +65,6 @@ const columns: ColumnDef<any>[] = [
|
||||||
<StatusToogle id={row.original.id} initChecked={row.original.isBanner} />
|
<StatusToogle id={row.original.id} initChecked={row.original.isBanner} />
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: "actions",
|
id: "actions",
|
||||||
accessorKey: "action",
|
accessorKey: "action",
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,7 @@ const ContentListBanner = () => {
|
||||||
const [selectedItems, setSelectedItems] = React.useState<number[]>([]);
|
const [selectedItems, setSelectedItems] = 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 [searchQuery, setSearchQuery] = React.useState("");
|
||||||
let typingTimer: any;
|
|
||||||
const doneTypingInterval = 1500;
|
|
||||||
|
|
||||||
const handleKeyUp = () => {
|
const handleKeyUp = () => {
|
||||||
clearTimeout(typingTimer);
|
clearTimeout(typingTimer);
|
||||||
|
|
@ -108,6 +106,21 @@ const ContentListBanner = () => {
|
||||||
typingTimer = setTimeout(doneTyping, doneTypingInterval);
|
typingTimer = setTimeout(doneTyping, doneTypingInterval);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let typingTimer: NodeJS.Timeout;
|
||||||
|
const doneTypingInterval = 1500;
|
||||||
|
|
||||||
|
const handleTyping = () => {
|
||||||
|
clearTimeout(typingTimer);
|
||||||
|
typingTimer = setTimeout(() => {
|
||||||
|
setPage(1);
|
||||||
|
fetchData();
|
||||||
|
}, doneTypingInterval);
|
||||||
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
fetchData();
|
||||||
|
}, [categoryFilter, statusFilter]);
|
||||||
|
|
||||||
async function doneTyping() {
|
async function doneTyping() {
|
||||||
fetchData();
|
fetchData();
|
||||||
}
|
}
|
||||||
|
|
@ -133,10 +146,11 @@ const ContentListBanner = () => {
|
||||||
const res = await listDataMedia(
|
const res = await listDataMedia(
|
||||||
page - 1,
|
page - 1,
|
||||||
showData,
|
showData,
|
||||||
"",
|
searchQuery,
|
||||||
categoryFilter?.sort().join(","),
|
categoryFilter?.sort().join(","),
|
||||||
statusFilter?.sort().join(",")
|
statusFilter?.sort().join(",")
|
||||||
);
|
);
|
||||||
|
|
||||||
const data = res?.data?.data;
|
const data = res?.data?.data;
|
||||||
const contentData = data?.content;
|
const contentData = data?.content;
|
||||||
contentData.forEach((item: any, index: number) => {
|
contentData.forEach((item: any, index: number) => {
|
||||||
|
|
@ -224,10 +238,19 @@ const ContentListBanner = () => {
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
onKeyUp={handleKeyUp}
|
value={searchQuery}
|
||||||
onKeyDown={handleKeyDown}
|
onChange={(e) => {
|
||||||
|
setSearchQuery(e.target.value);
|
||||||
|
handleTyping();
|
||||||
|
}}
|
||||||
className="max-w-[300px]"
|
className="max-w-[300px]"
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* <div className="flex flex-row gap-2">
|
{/* <div className="flex flex-row gap-2">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
|
|
@ -393,9 +416,12 @@ const ContentListBanner = () => {
|
||||||
alt={item.title}
|
alt={item.title}
|
||||||
className="w-full h-48 object-cover"
|
className="w-full h-48 object-cover"
|
||||||
/>
|
/>
|
||||||
<div className="p-3">
|
<Link
|
||||||
<h4 className="font-semibold text-sm truncate">{item.title}</h4>
|
href={`/contributor/content/image/detail/${item?.id}`}
|
||||||
</div>
|
className="p-3"
|
||||||
|
>
|
||||||
|
<h4 className="font-semibold text-sm">{item.title}</h4>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export default function AdminBanner() {
|
||||||
: "bg-white text-black "
|
: "bg-white text-black "
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
Kontent
|
Konten
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
rounded="md"
|
rounded="md"
|
||||||
|
|
|
||||||
|
|
@ -58,24 +58,13 @@ const columns: ColumnDef<any>[] = [
|
||||||
<span>{formatDateToIndonesian(row.getValue("createdAt"))}</span>
|
<span>{formatDateToIndonesian(row.getValue("createdAt"))}</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
accessorKey: "isStaticBanner",
|
|
||||||
header: "Static Banner",
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<StaticToogle
|
|
||||||
id={row.original.id}
|
|
||||||
initChecked={row.original.isStaticBanner}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
accessorKey: "statusName",
|
accessorKey: "statusName",
|
||||||
header: "Status Banner",
|
header: "Status Pop Up",
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<StatusToogle id={row.original.id} initChecked={row.original.isBanner} />
|
<StatusToogle id={row.original.id} initChecked={row.original.isInterstitial} />
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: "actions",
|
id: "actions",
|
||||||
accessorKey: "action",
|
accessorKey: "action",
|
||||||
|
|
|
||||||
|
|
@ -98,13 +98,18 @@ const PopUpListTable = () => {
|
||||||
loading();
|
loading();
|
||||||
let temp: any;
|
let temp: any;
|
||||||
|
|
||||||
const response = await listDataPopUp(
|
// const response = await listDataPopUp(
|
||||||
page - 1,
|
// page - 1,
|
||||||
showData,
|
// showData,
|
||||||
"",
|
// "",
|
||||||
categoryFilter?.sort().join(","),
|
// categoryFilter?.sort().join(","),
|
||||||
statusFilter?.sort().join(",")
|
// statusFilter?.sort().join(",")
|
||||||
);
|
// );
|
||||||
|
// const data = response?.data?.data?.content;
|
||||||
|
// console.log("banner", data);
|
||||||
|
// setGetData(data);
|
||||||
|
|
||||||
|
const response = await listBanner();
|
||||||
const data = response?.data?.data?.content;
|
const data = response?.data?.data?.content;
|
||||||
console.log("banner", data);
|
console.log("banner", data);
|
||||||
setGetData(data);
|
setGetData(data);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { useRouter } from "@/i18n/routing";
|
import { useRouter } from "@/i18n/routing";
|
||||||
import { setBanner } from "@/service/settings/settings";
|
import { setBanner, setPopUp } from "@/service/settings/settings";
|
||||||
|
|
||||||
export default function StatusToogle(props: {
|
export default function StatusToogle(props: {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -12,7 +12,7 @@ export default function StatusToogle(props: {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const disableBanner = async () => {
|
const disableBanner = async () => {
|
||||||
const response = await setBanner(id, false);
|
const response = await setPopUp(id, false);
|
||||||
|
|
||||||
if (response?.error) {
|
if (response?.error) {
|
||||||
toast({
|
toast({
|
||||||
|
|
@ -25,7 +25,7 @@ export default function StatusToogle(props: {
|
||||||
toast({
|
toast({
|
||||||
title: "Success ",
|
title: "Success ",
|
||||||
});
|
});
|
||||||
router.push("/admin/settings/banner?dataChange=true");
|
router.push("/admin/settings/popup?dataChange=true");
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Switch
|
<Switch
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,10 @@ const ContentListPopUp = () => {
|
||||||
const [selectedItems, setSelectedItems] = React.useState<number[]>([]);
|
const [selectedItems, setSelectedItems] = 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 [searchQuery, setSearchQuery] = React.useState("");
|
||||||
|
|
||||||
let typingTimer: any;
|
let typingTimer: NodeJS.Timeout;
|
||||||
const doneTypingInterval = 1500;
|
const doneTypingInterval = 2000;
|
||||||
|
|
||||||
const handleKeyUp = () => {
|
const handleKeyUp = () => {
|
||||||
clearTimeout(typingTimer);
|
clearTimeout(typingTimer);
|
||||||
|
|
@ -105,9 +106,16 @@ const ContentListPopUp = () => {
|
||||||
|
|
||||||
const handleKeyDown = () => {
|
const handleKeyDown = () => {
|
||||||
clearTimeout(typingTimer);
|
clearTimeout(typingTimer);
|
||||||
typingTimer = setTimeout(doneTyping, doneTypingInterval);
|
typingTimer = setTimeout(() => {
|
||||||
|
setPage(1);
|
||||||
|
fetchData();
|
||||||
|
}, doneTypingInterval);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
fetchData();
|
||||||
|
}, [categoryFilter, statusFilter]);
|
||||||
|
|
||||||
async function doneTyping() {
|
async function doneTyping() {
|
||||||
fetchData();
|
fetchData();
|
||||||
}
|
}
|
||||||
|
|
@ -127,13 +135,40 @@ const ContentListPopUp = () => {
|
||||||
});
|
});
|
||||||
}, [page, showData]);
|
}, [page, showData]);
|
||||||
|
|
||||||
|
// async function fetchData() {
|
||||||
|
// try {
|
||||||
|
// loading();
|
||||||
|
// const res = await listDataPopUp(
|
||||||
|
// page - 1,
|
||||||
|
// showData,
|
||||||
|
// "",
|
||||||
|
// categoryFilter?.sort().join(","),
|
||||||
|
// statusFilter?.sort().join(",")
|
||||||
|
// );
|
||||||
|
// const data = res?.data?.data;
|
||||||
|
// const contentData = data?.content;
|
||||||
|
// contentData.forEach((item: any, index: number) => {
|
||||||
|
// item.no = (page - 1) * Number(showData) + index + 1;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// console.log("contentData : ", data);
|
||||||
|
|
||||||
|
// setData(contentData);
|
||||||
|
// setTotalData(data?.totalElements);
|
||||||
|
// setTotalPage(data?.totalPages);
|
||||||
|
// close();
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("Error fetching tasks:", error);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
try {
|
try {
|
||||||
loading();
|
loading();
|
||||||
const res = await listDataPopUp(
|
const res = await listDataMedia(
|
||||||
page - 1,
|
page - 1,
|
||||||
showData,
|
showData,
|
||||||
"",
|
searchQuery, // <-- gunakan nilai pencarian
|
||||||
categoryFilter?.sort().join(","),
|
categoryFilter?.sort().join(","),
|
||||||
statusFilter?.sort().join(",")
|
statusFilter?.sort().join(",")
|
||||||
);
|
);
|
||||||
|
|
@ -224,10 +259,19 @@ const ContentListPopUp = () => {
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
onKeyUp={handleKeyUp}
|
value={searchQuery}
|
||||||
onKeyDown={handleKeyDown}
|
onChange={(e) => {
|
||||||
|
setSearchQuery(e.target.value);
|
||||||
|
handleKeyDown();
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
}}
|
||||||
className="max-w-[300px]"
|
className="max-w-[300px]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* <div className="flex flex-row gap-2">
|
{/* <div className="flex flex-row gap-2">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
|
|
@ -393,9 +437,12 @@ const ContentListPopUp = () => {
|
||||||
alt={item.title}
|
alt={item.title}
|
||||||
className="w-full h-48 object-cover"
|
className="w-full h-48 object-cover"
|
||||||
/>
|
/>
|
||||||
<div className="p-3">
|
<Link
|
||||||
<h4 className="font-semibold text-sm truncate">{item.title}</h4>
|
href={`/contributor/content/image/detail/${item?.id}`}
|
||||||
</div>
|
className="p-3"
|
||||||
|
>
|
||||||
|
<h4 className="font-semibold text-sm">{item.title}</h4>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export default function AdminPopup() {
|
||||||
: "bg-white text-black "
|
: "bg-white text-black "
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
Kontent
|
Konten
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
rounded="md"
|
rounded="md"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { Link, useRouter } from "@/components/navigation";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
import { deleteBlog } from "@/service/blog/blog";
|
import { deleteBlog } from "@/service/blog/blog";
|
||||||
import { error, loading } from "@/lib/swal";
|
import { error, loading, close } from "@/lib/swal";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
|
@ -126,6 +126,7 @@ const useTableColumns = ({
|
||||||
|
|
||||||
const handleDownload = async (id: string) => {
|
const handleDownload = async (id: string) => {
|
||||||
try {
|
try {
|
||||||
|
loading();
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`https://netidhub.com/api/media/report/download?id=${id}`,
|
`https://netidhub.com/api/media/report/download?id=${id}`,
|
||||||
{
|
{
|
||||||
|
|
@ -140,6 +141,7 @@ const useTableColumns = ({
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
link.click();
|
link.click();
|
||||||
link.remove();
|
link.remove();
|
||||||
|
close();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Download failed", error);
|
console.error("Download failed", error);
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ export default function ExecutiveDataDashboard() {
|
||||||
const state = Cookies.get("state");
|
const state = Cookies.get("state");
|
||||||
const provState = Cookies.get("state-prov");
|
const provState = Cookies.get("state-prov");
|
||||||
const t = useTranslations("AnalyticsDashboard");
|
const t = useTranslations("AnalyticsDashboard");
|
||||||
|
const [refreshTicket, setRefreshTicket] = useState(true);
|
||||||
|
|
||||||
const [ticket1, setTicket1] = useState("");
|
const [ticket1, setTicket1] = useState("");
|
||||||
const [ticket2, setTicket2] = useState("");
|
const [ticket2, setTicket2] = useState("");
|
||||||
|
|
@ -44,6 +45,7 @@ export default function ExecutiveDataDashboard() {
|
||||||
const [ticket4, setTicket4] = useState("");
|
const [ticket4, setTicket4] = useState("");
|
||||||
const [ticket5, setTicket5] = useState("");
|
const [ticket5, setTicket5] = useState("");
|
||||||
const [ticket6, setTicket6] = useState("");
|
const [ticket6, setTicket6] = useState("");
|
||||||
|
const [ticket7, setTicket7] = useState("");
|
||||||
const [isInternational, setIsInternational] = useState([false, false, false]);
|
const [isInternational, setIsInternational] = useState([false, false, false]);
|
||||||
|
|
||||||
const baseUrl = "https://analytic.sitani.info/";
|
const baseUrl = "https://analytic.sitani.info/";
|
||||||
|
|
@ -54,13 +56,40 @@ export default function ExecutiveDataDashboard() {
|
||||||
const view1 =
|
const view1 =
|
||||||
levelName == "MABES POLRI"
|
levelName == "MABES POLRI"
|
||||||
? isInternational[0]
|
? isInternational[0]
|
||||||
? "views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue-executive?"
|
? "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-polda-new?polda-selected=ALL"
|
||||||
: "views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue-executive?"
|
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-polda-new?polda-selected=ALL"
|
||||||
: safeLevelName.includes("POLDA")
|
: safeLevelName.includes("POLDA")
|
||||||
? `views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue?provinsi-polda=${state}&`
|
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-polda-new?polda-selected=${state}&`
|
||||||
: `views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue?provinsi-polda=${state}&`;
|
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-polda-new?polda-selected=${state}&`;
|
||||||
|
|
||||||
const view2 =
|
const view2 =
|
||||||
|
levelName == "MABES POLRI"
|
||||||
|
? isInternational[1]
|
||||||
|
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-content-interaction-per-satker?polda-selected=ALL"
|
||||||
|
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-satker?polda-selected=ALL"
|
||||||
|
: safeLevelName.includes("POLDA")
|
||||||
|
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-satker?polda-selected=SATKER POLRI&`
|
||||||
|
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-satker?polda-selected=SATKER POLRI&`;
|
||||||
|
|
||||||
|
const view3 =
|
||||||
|
levelName == "MABES POLRI"
|
||||||
|
? isInternational[2]
|
||||||
|
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-content-category-per-polda-new?polda-selected=ALL"
|
||||||
|
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-category-per-polda-new?polda-selected=ALL"
|
||||||
|
: safeLevelName.includes("POLDA")
|
||||||
|
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-category-per-polda-new?polda-selected=${state}&`
|
||||||
|
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-category-per-polda-new?polda-selected=${state}&`;
|
||||||
|
|
||||||
|
const view4 =
|
||||||
|
levelName == "MABES POLRI"
|
||||||
|
? isInternational[1]
|
||||||
|
? "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-category-per-satker?polda-selected=ALL"
|
||||||
|
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-category-per-satker?polda-selected=ALL"
|
||||||
|
: safeLevelName.includes("POLDA")
|
||||||
|
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-category-per-satker?polda-selected=SATKER POLRI&`
|
||||||
|
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-category-per-satker?polda-selected=SATKER POLRI&`;
|
||||||
|
|
||||||
|
const view5 =
|
||||||
levelName == "MABES POLRI"
|
levelName == "MABES POLRI"
|
||||||
? isInternational[1]
|
? isInternational[1]
|
||||||
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-published-produksi?"
|
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-published-produksi?"
|
||||||
|
|
@ -69,7 +98,7 @@ export default function ExecutiveDataDashboard() {
|
||||||
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-polda-executive?polda-selected=${state}&`
|
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-polda-executive?polda-selected=${state}&`
|
||||||
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-polda-executive?polda-selected=${state}&`;
|
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-polda-executive?polda-selected=${state}&`;
|
||||||
|
|
||||||
const view3 =
|
const view6 =
|
||||||
levelName == "MABES POLRI"
|
levelName == "MABES POLRI"
|
||||||
? isInternational[2]
|
? isInternational[2]
|
||||||
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-waktu-akses-pengguna?"
|
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-waktu-akses-pengguna?"
|
||||||
|
|
@ -78,59 +107,14 @@ export default function ExecutiveDataDashboard() {
|
||||||
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-waktu-akses-pengguna-polda-executive?polda-selected=${state}&`
|
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-waktu-akses-pengguna-polda-executive?polda-selected=${state}&`
|
||||||
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-waktu-akses-pengguna-polda-executive?polda-selected=${state}&`;
|
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-waktu-akses-pengguna-polda-executive?polda-selected=${state}&`;
|
||||||
|
|
||||||
const view4 =
|
|
||||||
levelName == "MABES POLRI"
|
|
||||||
? isInternational[1]
|
|
||||||
? "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda?"
|
|
||||||
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda?"
|
|
||||||
: safeLevelName.includes("POLDA")
|
|
||||||
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-polda-new?polda-selected=${state}&`
|
|
||||||
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-per-polda-new?polda-selected=${state}&`;
|
|
||||||
|
|
||||||
const view5 =
|
|
||||||
levelName == "MABES POLRI"
|
|
||||||
? isInternational[1]
|
|
||||||
? "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polres?"
|
|
||||||
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polres?"
|
|
||||||
: safeLevelName.includes("POLDA")
|
|
||||||
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polres?provinsi-polda=${state}&`
|
|
||||||
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polres?provinsi-polda=${state}&`;
|
|
||||||
|
|
||||||
const view6 =
|
|
||||||
levelName == "MABES POLRI"
|
|
||||||
? isInternational[1]
|
|
||||||
? "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-satker?"
|
|
||||||
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-satker?"
|
|
||||||
: safeLevelName.includes("POLDA")
|
|
||||||
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-satker?satker-selected=${state}&`
|
|
||||||
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-satker?satker-selected=${state}&`;
|
|
||||||
|
|
||||||
const view7 =
|
const view7 =
|
||||||
levelName == "MABES POLRI"
|
levelName == "MABES POLRI"
|
||||||
? isInternational[2]
|
? isInternational[2]
|
||||||
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-penugasan?"
|
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-penugasan-vertical-bar?"
|
||||||
: "views/2023_09_db-penugasan_rev100/db-penugasan?"
|
: "views/2023_09_db-penugasan_rev100/db-penugasan-vertical-bar?"
|
||||||
: safeLevelName.includes("POLDA")
|
: safeLevelName.includes("POLDA")
|
||||||
? `views/2023_09_db-penugasan_rev100/db-penugasan?polda-selected=${state}&`
|
? `views/2023_09_db-penugasan_rev100/db-penugasan-vertical-bar?polda-selected=${state}&`
|
||||||
: `views/2023_09_db-penugasan_rev100/db-penugasan?polda-selected=${state}&`;
|
: `views/2023_09_db-penugasan_rev100/db-penugasan-vertical-bar?polda-selected=${state}&`;
|
||||||
|
|
||||||
const view8 =
|
|
||||||
levelName == "MABES POLRI"
|
|
||||||
? isInternational[2]
|
|
||||||
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-konten-kategori-top10?"
|
|
||||||
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-konten-kategori-top10?"
|
|
||||||
: safeLevelName.includes("POLDA")
|
|
||||||
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda-new?polda-selected=${state}&`
|
|
||||||
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda-new?polda-selected=${state}&`;
|
|
||||||
|
|
||||||
const view9 =
|
|
||||||
levelName == "MABES POLRI"
|
|
||||||
? isInternational[3]
|
|
||||||
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-konten-kategori?"
|
|
||||||
: "views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-konten-kategori?"
|
|
||||||
: safeLevelName.includes("POLDA")
|
|
||||||
? `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-konten-kategori-polda?polda-selected=${state}&`
|
|
||||||
: `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-konten-kategori-polda?polda-selected=${state}&`;
|
|
||||||
|
|
||||||
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true";
|
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true";
|
||||||
|
|
||||||
|
|
@ -153,10 +137,13 @@ export default function ExecutiveDataDashboard() {
|
||||||
|
|
||||||
const response6 = await generateTicket();
|
const response6 = await generateTicket();
|
||||||
setTicket6(response6?.data?.data);
|
setTicket6(response6?.data?.data);
|
||||||
|
|
||||||
|
const response7 = await generateTicket();
|
||||||
|
setTicket7(response7?.data?.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
initState();
|
initState();
|
||||||
}, [isInternational]);
|
}, [isInternational, refreshTicket]);
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -178,7 +165,7 @@ export default function ExecutiveDataDashboard() {
|
||||||
<SiteBreadcrumb />
|
<SiteBreadcrumb />
|
||||||
<div>
|
<div>
|
||||||
<div className="my-3">
|
<div className="my-3">
|
||||||
<Tabs defaultValue="content-publish" className="w-full">
|
<Tabs defaultValue="content-publish" className="w-full" onValueChange={() => setRefreshTicket(!refreshTicket)}>
|
||||||
<TabsList className="flex-wrap bg-black">
|
<TabsList className="flex-wrap bg-black">
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="content-publish"
|
value="content-publish"
|
||||||
|
|
@ -217,19 +204,17 @@ export default function ExecutiveDataDashboard() {
|
||||||
{/* Polda */}
|
{/* Polda */}
|
||||||
{(levelNumber === "1" || levelNumber === "2") && (
|
{(levelNumber === "1" || levelNumber === "2") && (
|
||||||
<Card
|
<Card
|
||||||
className={`rounded-sm p-3 ${
|
className={`rounded-sm p-3 w-full`}
|
||||||
levelNumber === "2" ? "w-full" : "w-full"
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div className="flex flex-row justify-between">
|
{/* <div className="flex flex-row justify-between">
|
||||||
<p className="text-base font-semibold">
|
<p className="text-base font-semibold">
|
||||||
Upload konten hari ini Polda
|
Upload konten hari ini Polda
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div> */}
|
||||||
<div className="my-5">
|
<div className="my-5">
|
||||||
{ticket1 == "w-full" ? (
|
{ticket1 == "w-full" ? (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${baseUrl + view4 + param}`}
|
src={`${baseUrl + view1 + param}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="750"
|
height="750"
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
|
@ -237,7 +222,7 @@ export default function ExecutiveDataDashboard() {
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${url + ticket1}/${view4}${param}`}
|
src={`${url + ticket1}/${view1}${param}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="750"
|
height="750"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
|
|
@ -248,60 +233,26 @@ export default function ExecutiveDataDashboard() {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Satker */}
|
{/* Satker */}
|
||||||
{(levelNumber === "1" || levelNumber === "3") && (
|
{(levelNumber === "1") && (
|
||||||
<Card
|
<Card
|
||||||
className={`rounded-sm p-3 ${
|
className={`rounded-sm p-3 w-full`}
|
||||||
levelNumber === "3" ? "w-full" : "w-full"
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div className="flex flex-row justify-between">
|
{/* <div className="flex flex-row justify-between">
|
||||||
<p className="text-base font-semibold">
|
<p className="text-base font-semibold">
|
||||||
Upload konten hari ini Satker
|
Upload konten hari ini Satker
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div> */}
|
||||||
<div className="my-5">
|
<div className="my-5">
|
||||||
{ticket2 == "" ? (
|
{ticket2 == "" ? (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${baseUrl + view6 + param}`}
|
src={`${baseUrl + view2 + param}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="750"
|
height="750"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${url + ticket2}/${view6}${param}`}
|
src={`${url + ticket2}/${view2}${param}`}
|
||||||
width="100%"
|
|
||||||
height="750"
|
|
||||||
frameBorder="0"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Polres */}
|
|
||||||
{(levelNumber === "1" || levelNumber === "2") && (
|
|
||||||
<Card
|
|
||||||
className={`rounded-sm p-3 ${
|
|
||||||
levelNumber === "2" ? "w-full" : "w-full"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="flex flex-row justify-between">
|
|
||||||
<p className="text-base font-semibold">
|
|
||||||
Upload konten hari ini Polres
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="my-5">
|
|
||||||
{ticket3 == "" ? (
|
|
||||||
<iframe
|
|
||||||
src={`${baseUrl + view5 + param}`}
|
|
||||||
width="100%"
|
|
||||||
height="750"
|
|
||||||
frameBorder="0"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<iframe
|
|
||||||
src={`${url + ticket3}/${view5}${param}`}
|
|
||||||
width="100%"
|
width="100%"
|
||||||
height="750"
|
height="750"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
|
|
@ -313,56 +264,19 @@ export default function ExecutiveDataDashboard() {
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="content-category">
|
<TabsContent value="content-category">
|
||||||
|
{(levelNumber === "1" || levelNumber === "2") && (
|
||||||
<Card className="px-3 py-3">
|
<Card className="px-3 py-3">
|
||||||
<p className="text-lg">
|
|
||||||
<b>
|
|
||||||
{isInternational[2]
|
|
||||||
? "INTERACTION OF THE MOST POPULAR CATEGORIES AND TITLES"
|
|
||||||
: "INTERAKSI KATEGORI DAN JUDUL TERPOPULER"}
|
|
||||||
</b>
|
|
||||||
</p>
|
|
||||||
{levelName === "MABES POLRI" ? (
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<p>{t("choose_category")}</p>
|
|
||||||
<div className="flex flex-row gap-1 border-2 w-fit">
|
|
||||||
<Button
|
|
||||||
onClick={() => handleInternational(2, false)}
|
|
||||||
className={` hover:text-white rounded-none
|
|
||||||
${
|
|
||||||
isInternational[2]
|
|
||||||
? "bg-white text-black "
|
|
||||||
: "bg-black text-white "
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Indonesia
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={() => handleInternational(2, true)}
|
|
||||||
className={`hover:text-white rounded-none ${
|
|
||||||
isInternational[1]
|
|
||||||
? "bg-black text-white "
|
|
||||||
: "bg-white text-black "
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{t("international")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
<div className="my-5">
|
<div className="my-5">
|
||||||
{ticket3 == "" ? (
|
{ticket3 == "" ? (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${baseUrl + view8 + param}`}
|
src={`${baseUrl + view3 + param}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="750"
|
height="750"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${`${url + ticket3}/${view8}${param}`}`}
|
src={`${`${url + ticket3}/${view3}${param}`}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="750"
|
height="750"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
|
|
@ -370,25 +284,43 @@ export default function ExecutiveDataDashboard() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</TabsContent>
|
)}
|
||||||
<TabsContent value="popular-content">
|
|
||||||
<Card className="rounded-sm p-3 h-[750px]">
|
{levelNumber === "1" && (
|
||||||
<div className="flex flex-row justify-between">
|
<Card className="px-3 py-3">
|
||||||
<p className="text-base font-semibold">
|
|
||||||
Konten Paling Populer
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="my-5">
|
<div className="my-5">
|
||||||
{ticket4 == "" ? (
|
{ticket4 == "" ? (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${baseUrl + view2 + param}`}
|
src={`${baseUrl + view4 + param}`}
|
||||||
|
width="100%"
|
||||||
|
height="750"
|
||||||
|
frameBorder="0"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<iframe
|
||||||
|
src={`${`${url + ticket4}/${view4}${param}`}`}
|
||||||
|
width="100%"
|
||||||
|
height="750"
|
||||||
|
frameBorder="0"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="popular-content">
|
||||||
|
<Card className="rounded-sm p-3 h-[750px]">
|
||||||
|
<div className="my-5">
|
||||||
|
{ticket5 == "" ? (
|
||||||
|
<iframe
|
||||||
|
src={`${baseUrl + view5 + param}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="650"
|
height="650"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${`${url + ticket4}/${view2}${param}`}`}
|
src={`${`${url + ticket5}/${view5}${param}`}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="650"
|
height="650"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
|
|
@ -400,22 +332,17 @@ export default function ExecutiveDataDashboard() {
|
||||||
|
|
||||||
<TabsContent value="heatmap">
|
<TabsContent value="heatmap">
|
||||||
<Card className="rounded-sm p-3 h-[750px]">
|
<Card className="rounded-sm p-3 h-[750px]">
|
||||||
<div className="flex flex-row justify-between mx-3">
|
|
||||||
<p className="text-base font-semibold">
|
|
||||||
Heatmap Konten dan Kategori dengan Interaksi
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="my-5">
|
<div className="my-5">
|
||||||
{ticket5 == "" ? (
|
{ticket6 == "" ? (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${baseUrl + view3 + param}`}
|
src={`${baseUrl + view6 + param}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="600"
|
height="600"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${`${url + ticket5}/${view3}${param}`}`}
|
src={`${`${url + ticket6}/${view6}${param}`}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="600"
|
height="600"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
|
|
@ -425,42 +352,9 @@ export default function ExecutiveDataDashboard() {
|
||||||
</Card>
|
</Card>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="task">
|
<TabsContent value="task">
|
||||||
<div className="grid grid-cols-12 gap-5">
|
<Card className="rounded-sm p-3 h-[750px]">
|
||||||
<div className="lg:col-span-12 col-span-12">
|
|
||||||
<Card className="px-3 py-3">
|
|
||||||
{levelName === "MABES POLRI" ? (
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<p>{t("choose_category")}</p>
|
|
||||||
<div className="flex flex-row gap-1 border-2 w-fit">
|
|
||||||
<Button
|
|
||||||
onClick={() => handleInternational(2, false)}
|
|
||||||
className={` hover:text-white rounded-none
|
|
||||||
${
|
|
||||||
isInternational[2]
|
|
||||||
? "bg-white text-black "
|
|
||||||
: "bg-black text-white "
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Indonesia
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={() => handleInternational(2, true)}
|
|
||||||
className={`hover:text-white rounded-none ${
|
|
||||||
isInternational[1]
|
|
||||||
? "bg-black text-white "
|
|
||||||
: "bg-white text-black "
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{t("international")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
<div className="my-5">
|
<div className="my-5">
|
||||||
{ticket3 == "" ? (
|
{ticket7 == "" ? (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${baseUrl + view7 + param}`}
|
src={`${baseUrl + view7 + param}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
|
|
@ -469,7 +363,7 @@ export default function ExecutiveDataDashboard() {
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<iframe
|
<iframe
|
||||||
src={`${`${url + ticket3}/${view7}${param}`}`}
|
src={`${`${url + ticket7}/${view7}${param}`}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="750"
|
height="750"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
|
|
@ -477,8 +371,6 @@ export default function ExecutiveDataDashboard() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,21 +13,81 @@ import {
|
||||||
deleteKnowledgeBase,
|
deleteKnowledgeBase,
|
||||||
getKnowledgeBaseCategoryList,
|
getKnowledgeBaseCategoryList,
|
||||||
getKnowledgeBaseList,
|
getKnowledgeBaseList,
|
||||||
|
saveKnowledgeBase,
|
||||||
|
saveKnowledgeBaseCategory,
|
||||||
} from "@/service/master/knowledge-base";
|
} from "@/service/master/knowledge-base";
|
||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Plus, Trash, Trash2 } from "lucide-react";
|
import { Edit2Icon, Plus, Trash, Trash2 } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import CreateCategory from "./create-category";
|
import CreateCategory from "./create-category";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
import { deleteMedia } from "@/service/content/content";
|
import { deleteMedia } from "@/service/content/content";
|
||||||
import { error } from "@/lib/swal";
|
import { error } from "@/lib/swal";
|
||||||
|
import { close, loading } from "@/config/swal";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { toast } from "@/components/ui/use-toast";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
|
||||||
|
const FormSchema = z.object({
|
||||||
|
name: z.string().min(2, {
|
||||||
|
message: "Name must be at least 2 characters.",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const FormSchemaCreate = z.object({
|
||||||
|
title: z.string().min(2, {
|
||||||
|
message: "Judul minimal 2 karakter.",
|
||||||
|
}),
|
||||||
|
question: z.string().min(2, {
|
||||||
|
message: "Pertanyaan minimal 2 karakter.",
|
||||||
|
}),
|
||||||
|
answer: z.string().min(2, {
|
||||||
|
message: "Jawaban minimal 2 karakter.",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const KnowledgeBase = () => {
|
const KnowledgeBase = () => {
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const [categories, setCategories] = React.useState<any>([]);
|
const [categories, setCategories] = useState<any>([]);
|
||||||
const [questions, setQuestions] = React.useState<any>([]);
|
const [questions, setQuestions] = useState<any>([]);
|
||||||
|
const [selectedCategoryId, setSelectedCategoryId] = useState(0);
|
||||||
|
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
|
||||||
|
const [viewCreate, setViewCreate] = useState(false);
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
defaultValues: {
|
||||||
|
name: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formCreate = useForm<z.infer<typeof FormSchemaCreate>>({
|
||||||
|
resolver: zodResolver(FormSchemaCreate),
|
||||||
|
defaultValues: {
|
||||||
|
title: "",
|
||||||
|
question: "",
|
||||||
|
answer: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetchCategoryList();
|
fetchCategoryList();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
@ -37,7 +97,9 @@ const KnowledgeBase = () => {
|
||||||
const data = response?.data?.data;
|
const data = response?.data?.data;
|
||||||
if (data) {
|
if (data) {
|
||||||
setCategories(data);
|
setCategories(data);
|
||||||
fetchQuestions(data[0]?.id);
|
fetchQuestions(
|
||||||
|
selectedCategoryId === 0 ? data[0]?.id : selectedCategoryId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +112,7 @@ const KnowledgeBase = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
async function doDelete(id: any) {
|
async function doDelete(id: any) {
|
||||||
// loading();
|
loading();
|
||||||
const data = {
|
const data = {
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
|
|
@ -61,6 +123,7 @@ const KnowledgeBase = () => {
|
||||||
error(response.message);
|
error(response.message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
close();
|
||||||
success();
|
success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +135,7 @@ const KnowledgeBase = () => {
|
||||||
confirmButtonText: "OK",
|
confirmButtonText: "OK",
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
window.location.reload();
|
fetchQuestions(selectedCategoryId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +156,50 @@ const KnowledgeBase = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||||
|
save(data);
|
||||||
|
setIsDialogOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
formCreate.reset();
|
||||||
|
}, [viewCreate]);
|
||||||
|
|
||||||
|
async function save(data: any) {
|
||||||
|
loading();
|
||||||
|
const reqData = {
|
||||||
|
id: selectedCategoryId,
|
||||||
|
name: data.name,
|
||||||
|
};
|
||||||
|
const response = await saveKnowledgeBaseCategory(reqData);
|
||||||
|
if (response?.error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
toast({
|
||||||
|
title: "Task created successfully.",
|
||||||
|
});
|
||||||
|
fetchCategoryList();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onSubmitCreate(data: z.infer<typeof FormSchemaCreate>) {
|
||||||
|
const reqData = {
|
||||||
|
title: data.title,
|
||||||
|
categoryId:
|
||||||
|
selectedCategoryId === 0 ? categories[0]?.id : selectedCategoryId,
|
||||||
|
question: data.question,
|
||||||
|
answer: data.answer,
|
||||||
|
};
|
||||||
|
const response = await saveKnowledgeBase(reqData);
|
||||||
|
if (response?.error) {
|
||||||
|
error(response.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fetchQuestions(
|
||||||
|
selectedCategoryId === 0 ? categories[0]?.id : selectedCategoryId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SiteBreadcrumb />
|
<SiteBreadcrumb />
|
||||||
|
|
@ -108,6 +215,7 @@ const KnowledgeBase = () => {
|
||||||
value={`category-${index}`}
|
value={`category-${index}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
fetchQuestions(category?.id);
|
fetchQuestions(category?.id);
|
||||||
|
setSelectedCategoryId(category?.id);
|
||||||
}}
|
}}
|
||||||
className="group data-[state=active]:bg-secondary data-[state=active]:text-default rounded-md px-6 py-3 w-full justify-between flex items-center"
|
className="group data-[state=active]:bg-secondary data-[state=active]:text-default rounded-md px-6 py-3 w-full justify-between flex items-center"
|
||||||
>
|
>
|
||||||
|
|
@ -116,8 +224,58 @@ const KnowledgeBase = () => {
|
||||||
className="right-2 top-2 hidden group-hover:inline-flex"
|
className="right-2 top-2 hidden group-hover:inline-flex"
|
||||||
// onClick={() => deleteCategory(category?.id)}
|
// onClick={() => deleteCategory(category?.id)}
|
||||||
>
|
>
|
||||||
|
<div className="flex flex-row gap-2 items-center">
|
||||||
|
<Dialog
|
||||||
|
open={isDialogOpen}
|
||||||
|
onOpenChange={setIsDialogOpen}
|
||||||
|
>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<a
|
||||||
|
className="dark:bg-background dark:text-foreground"
|
||||||
|
onClick={() =>
|
||||||
|
form.setValue("name", category.name)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Edit2Icon size={18} />
|
||||||
|
</a>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader className="mb-4">
|
||||||
|
<DialogTitle>Edit Category</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="space-y-4"
|
||||||
|
>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel className="text-default-700">
|
||||||
|
Name
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter Title"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<Button type="submit">Submit</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
<Trash size={20} className="text-red-500" />
|
<Trash size={20} className="text-red-500" />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
))}
|
))}
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
@ -145,6 +303,7 @@ const KnowledgeBase = () => {
|
||||||
}}
|
}}
|
||||||
className="text-left"
|
className="text-left"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Trash
|
<Trash
|
||||||
size={20}
|
size={20}
|
||||||
className="text-red-500 hover:cursor-pointer"
|
className="text-red-500 hover:cursor-pointer"
|
||||||
|
|
@ -158,17 +317,87 @@ const KnowledgeBase = () => {
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
))}
|
))}
|
||||||
</Accordion>
|
</Accordion>
|
||||||
{questions?.length > 0 && (
|
|
||||||
<div className="flex gap-3">
|
<div className="flex gap-3">
|
||||||
<Button fullWidth size="md" variant="outline">
|
<Button fullWidth size="md" variant="outline">
|
||||||
<Plus className="w-6 h-6 me-1.5" />
|
<Plus className="w-6 h-6 me-1.5" />
|
||||||
Import
|
Import
|
||||||
</Button>
|
</Button>
|
||||||
<Button fullWidth size="md">
|
<Button
|
||||||
|
fullWidth
|
||||||
|
size="md"
|
||||||
|
onClick={() => setViewCreate(!viewCreate)}
|
||||||
|
>
|
||||||
<Plus className="w-6 h-6 me-1.5" />
|
<Plus className="w-6 h-6 me-1.5" />
|
||||||
Add Question
|
Add Question
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
{viewCreate && (
|
||||||
|
<div className="flex flex-col gap-2 py-6">
|
||||||
|
<Form {...formCreate}>
|
||||||
|
<form
|
||||||
|
onSubmit={formCreate.handleSubmit(onSubmitCreate)}
|
||||||
|
className="space-y-4"
|
||||||
|
>
|
||||||
|
<FormField
|
||||||
|
control={formCreate.control}
|
||||||
|
name="title"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel className="text-default-700">
|
||||||
|
Judul
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Masukkan Judul"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={formCreate.control}
|
||||||
|
name="question"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel className="text-default-700">
|
||||||
|
Pertanyaan
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Textarea
|
||||||
|
placeholder="Masukkan Pertanyaan"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={formCreate.control}
|
||||||
|
name="answer"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel className="text-default-700">
|
||||||
|
Jawaban
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Textarea
|
||||||
|
placeholder="Masukkan Jawaban"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<Button type="submit">Submit</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,80 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { useState } from "react";
|
import { use, useEffect, useState } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
import { MoreVertical } from "lucide-react";
|
import { MoreVertical, Trash2 } from "lucide-react";
|
||||||
|
import {
|
||||||
|
deleteDataFeedback,
|
||||||
|
getListFeedback,
|
||||||
|
postDataFeedback,
|
||||||
|
} from "@/service/settings/settings";
|
||||||
|
import { close, loading } from "@/config/swal";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
|
||||||
const FeedbackForm = () => {
|
const FeedbackForm = () => {
|
||||||
const [region, setRegion] = useState("nasional");
|
const [region, setRegion] = useState("nasional");
|
||||||
const [feedbackList, setFeedbackList] = useState<string[]>([
|
const [feedbackList, setFeedbackList] = useState<any>([]);
|
||||||
"Silahkan berikan rating Anda terkait dengan kemudahan akses website MediaHUB Polri",
|
|
||||||
"Silahkan berikan rating Anda terkait dengan konten MediaHUB Polri",
|
|
||||||
"Silahkan berikan rating Anda terkait dengan tampilan MediaHUB Polri",
|
|
||||||
]);
|
|
||||||
const [newFeedback, setNewFeedback] = useState("");
|
const [newFeedback, setNewFeedback] = useState("");
|
||||||
|
const [selectedFeedback, setSetSelectedFeedback] = useState(0);
|
||||||
|
|
||||||
const handleAddFeedback = () => {
|
useEffect(() => {
|
||||||
|
fetchFeedback();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchFeedback = async () => {
|
||||||
|
loading();
|
||||||
|
const res = await getListFeedback();
|
||||||
|
setFeedbackList(res?.data?.data);
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddFeedback = async () => {
|
||||||
if (newFeedback.trim()) {
|
if (newFeedback.trim()) {
|
||||||
setFeedbackList([...feedbackList, newFeedback.trim()]);
|
const req = {
|
||||||
|
question: newFeedback.trim(),
|
||||||
|
isInternational: region === "internasional",
|
||||||
|
};
|
||||||
|
loading();
|
||||||
|
const res = await postDataFeedback(req);
|
||||||
|
close();
|
||||||
|
fetchFeedback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleEditFeedback = async () => {
|
||||||
|
if (newFeedback.trim()) {
|
||||||
|
const req = {
|
||||||
|
id: selectedFeedback,
|
||||||
|
question: newFeedback.trim(),
|
||||||
|
isInternational: region === "internasional",
|
||||||
|
};
|
||||||
|
loading();
|
||||||
|
const res = await postDataFeedback(req);
|
||||||
|
close();
|
||||||
|
fetchFeedback();
|
||||||
|
setSetSelectedFeedback(0);
|
||||||
setNewFeedback("");
|
setNewFeedback("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deleteFeedback = async (id: number) => {
|
||||||
|
loading();
|
||||||
|
const res = await deleteDataFeedback(id);
|
||||||
|
console.log(res);
|
||||||
|
close();
|
||||||
|
fetchFeedback();
|
||||||
|
};
|
||||||
|
|
||||||
|
const doEdit = (id: number, question: string) => {
|
||||||
|
setSetSelectedFeedback(id);
|
||||||
|
setNewFeedback(question);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="bg-white rounded-md p-6 flex flex-col md:flex-row gap-6">
|
<div className="bg-white rounded-md p-6 flex flex-col md:flex-row gap-6">
|
||||||
|
|
@ -52,7 +106,16 @@ const FeedbackForm = () => {
|
||||||
className="min-h-[100px]"
|
className="min-h-[100px]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-row gap-1">
|
||||||
|
{selectedFeedback !== 0 && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={handleEditFeedback}
|
||||||
|
className="bg-white text-blue-600 border border-bue-600"
|
||||||
|
>
|
||||||
|
Ubah Feedback
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
onClick={handleAddFeedback}
|
onClick={handleAddFeedback}
|
||||||
className="bg-blue-600 text-white"
|
className="bg-blue-600 text-white"
|
||||||
|
|
@ -60,15 +123,40 @@ const FeedbackForm = () => {
|
||||||
Tambah Feedback
|
Tambah Feedback
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="md:w-1/2">
|
<div className="md:w-1/2">
|
||||||
<h3 className="font-semibold mb-2 border-b pb-1">Feedback</h3>
|
<h3 className="font-semibold mb-2 border-b pb-1">Feedback</h3>
|
||||||
<p className="font-medium mb-4">Pertanyaan</p>
|
<p className="font-medium mb-4">Pertanyaan</p>
|
||||||
<ul className="space-y-3">
|
<ul className="space-y-3">
|
||||||
{feedbackList.map((item, index) => (
|
{feedbackList.map((item: any) => (
|
||||||
<li key={index} className="flex justify-between items-start">
|
<li key={item.id} className="flex justify-between items-center">
|
||||||
<span>{item}</span>
|
<span>{item.question}</span>
|
||||||
<MoreVertical className="w-4 h-4 text-gray-600 cursor-pointer" />
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open menu</span>
|
||||||
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => doEdit(item.id, item.question)}
|
||||||
|
className="p-2 border-b rounded-none focus:bg-slate-300"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={() => deleteFeedback(item.id)}
|
||||||
|
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -107,8 +107,9 @@ const FilterPage = () => {
|
||||||
let prefixPath = poldaName ? `/polda/${poldaName}` : "/";
|
let prefixPath = poldaName ? `/polda/${poldaName}` : "/";
|
||||||
const t = useTranslations("FilterPage");
|
const t = useTranslations("FilterPage");
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState<any>(true);
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -119,6 +120,7 @@ const FilterPage = () => {
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const pageFromUrl = searchParams?.get("page");
|
const pageFromUrl = searchParams?.get("page");
|
||||||
if (pageFromUrl) {
|
if (pageFromUrl) {
|
||||||
|
|
@ -185,21 +187,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
|
pageNumber
|
||||||
);
|
);
|
||||||
console.log("category", response);
|
|
||||||
setCategories(response?.data?.data?.content);
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -293,10 +323,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -560,6 +591,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ const FilterPage = () => {
|
||||||
let prefixPath = poldaName ? `/polda/${poldaName}` : "/";
|
let prefixPath = poldaName ? `/polda/${poldaName}` : "/";
|
||||||
const [isLoading, setIsLoading] = useState<any>(true);
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -176,21 +178,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
|
pageNumber
|
||||||
);
|
);
|
||||||
console.log("category", response);
|
|
||||||
setCategories(response?.data?.data?.content);
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -290,10 +320,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -576,6 +607,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,8 @@ const FilterPage = () => {
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
let prefixPath = poldaName ? `/polda/${poldaName}` : "/";
|
let prefixPath = poldaName ? `/polda/${poldaName}` : "/";
|
||||||
const [isLoading, setIsLoading] = useState<any>(true);
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
const t = useTranslations("FilterPage");
|
const t = useTranslations("FilterPage");
|
||||||
|
|
||||||
|
|
@ -182,22 +184,51 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
);
|
pageNumber
|
||||||
console.log("category", response);
|
); // halaman 1-based
|
||||||
setCategories(response?.data?.data?.content);
|
|
||||||
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function initState() {
|
function initState() {
|
||||||
if (dateRange[0] != null && dateRange[1] != null) {
|
if (dateRange[0] != null && dateRange[1] != null) {
|
||||||
|
|
@ -289,10 +320,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -586,6 +618,66 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1
|
||||||
|
? "bg-[#bb3523] text-white"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ const FilterPage = () => {
|
||||||
const t = useTranslations("FilterPage");
|
const t = useTranslations("FilterPage");
|
||||||
const [isLoading, setIsLoading] = useState<any>(true);
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -176,22 +178,51 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
);
|
pageNumber
|
||||||
console.log("category", response);
|
); // halaman 1-based
|
||||||
setCategories(response?.data?.data?.content);
|
|
||||||
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function initState() {
|
function initState() {
|
||||||
if (dateRange[0] != null && dateRange[1] != null) {
|
if (dateRange[0] != null && dateRange[1] != null) {
|
||||||
|
|
@ -283,10 +314,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -572,6 +604,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import {
|
||||||
formatDateToIndonesian,
|
formatDateToIndonesian,
|
||||||
getOnlyDate,
|
getOnlyDate,
|
||||||
getOnlyMonthAndYear,
|
getOnlyMonthAndYear,
|
||||||
|
secondToTimes,
|
||||||
} from "@/utils/globals";
|
} from "@/utils/globals";
|
||||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||||
import {
|
import {
|
||||||
|
|
@ -43,6 +44,7 @@ import {
|
||||||
CarouselPrevious,
|
CarouselPrevious,
|
||||||
} from "@/components/ui/carousel";
|
} from "@/components/ui/carousel";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
|
|
||||||
const columns: ColumnDef<any>[] = [
|
const columns: ColumnDef<any>[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -105,6 +107,17 @@ const FilterPage = () => {
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
||||||
const t = useTranslations("FilterPage");
|
const t = useTranslations("FilterPage");
|
||||||
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -174,21 +187,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
|
pageNumber
|
||||||
);
|
);
|
||||||
console.log("category", response);
|
|
||||||
setCategories(response?.data?.data?.content);
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -282,10 +323,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -441,7 +483,7 @@ const FilterPage = () => {
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|
||||||
<div className="flex flex-col md:flex-row items-start gap-5 p-10 bg-[#f7f7f7] dark:bg-black">
|
<div className="flex flex-col md:flex-row items-start gap-5 py-10 px-4 lg:px-20 bg-[#f7f7f7] dark:bg-black">
|
||||||
<p>
|
<p>
|
||||||
{" "}
|
{" "}
|
||||||
Audio {">"} <span className="font-bold">{t("allAudio")}</span>
|
Audio {">"} <span className="font-bold">{t("allAudio")}</span>
|
||||||
|
|
@ -451,8 +493,8 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 pl-4 lg:pl-20 py-4">
|
||||||
<div className="lg:w-[25%] w-full bg-[#f7f7f7] dark:bg-black p-4 rounded-lg shadow-md">
|
<div className="h-fit min-w-full lg:min-w-[280px] max-w-full lg:max-w-[300px] 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
|
||||||
|
|
@ -529,7 +571,7 @@ const FilterPage = () => {
|
||||||
{t("categories")}
|
{t("categories")}
|
||||||
</h3>
|
</h3>
|
||||||
<ul className="mt-2 space-y-2">
|
<ul className="mt-2 space-y-2">
|
||||||
{categories.map((category: any) => (
|
{categories?.map((category: any) => (
|
||||||
<li key={category?.id}>
|
<li key={category?.id}>
|
||||||
<label
|
<label
|
||||||
className="inline-flex items-center"
|
className="inline-flex items-center"
|
||||||
|
|
@ -549,6 +591,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
@ -603,9 +703,9 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Konten Kanan */}
|
{/* Right */}
|
||||||
|
<div className="w-full pr-4 lg:pr-16 pb-4">
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<div className="flex-1">
|
|
||||||
<div className="flex flex-col items-end mb-4">
|
<div className="flex flex-col items-end mb-4">
|
||||||
<h2 className="text-lg font-semibold">{t("sortBy")} </h2>
|
<h2 className="text-lg font-semibold">{t("sortBy")} </h2>
|
||||||
<select
|
<select
|
||||||
|
|
@ -618,22 +718,35 @@ const FilterPage = () => {
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isLoading ? (
|
||||||
|
<>
|
||||||
|
<div className="flex flex-col space-y-3 w-full justify-center items-center gap-3">
|
||||||
|
<Skeleton className="h-[100px] w-full rounded-xl" />
|
||||||
|
<Skeleton className="h-[100px] w-full rounded-xl" />
|
||||||
|
<Skeleton className="h-[100px] w-full rounded-xl" />
|
||||||
|
<Skeleton className="h-[100px] w-full rounded-xl" />
|
||||||
|
<Skeleton className="h-[100px] w-full rounded-xl" />
|
||||||
|
<Skeleton className="h-[100px] w-full rounded-xl" />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
{audioData?.length > 0 ? (
|
{audioData?.length > 0 ? (
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="flex flex-col gap-3">
|
||||||
{audioData?.map((image: any) => (
|
|
||||||
<Carousel className="w-full max-w-7xl mx-auto">
|
|
||||||
<CarouselContent>
|
|
||||||
{audioData?.map((audio: any) => (
|
{audioData?.map((audio: any) => (
|
||||||
<CarouselItem
|
<div key={audio?.id}>
|
||||||
key={audio?.id}
|
<div
|
||||||
className="md:basis-1/2 lg:basis-1/3"
|
// href={`/audio/detail/${audio?.slug}`}
|
||||||
|
onClick={() =>
|
||||||
|
router.push(
|
||||||
|
prefixPath + `/audio/detail/${audio?.slug}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="flex flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full"
|
||||||
>
|
>
|
||||||
<div className="flex flex-row gap-6">
|
<div className="flex justify-center lg:justify-between w-full gap-2 lg:gap-6">
|
||||||
<Link
|
<div className="flex flex-row gap-3">
|
||||||
href={`${prefixPath}/audio/detail/${audio?.slug}`}
|
<div className="flex items-center justify-center bg-red-500 text-white rounded-lg w-16 h-full lg:h-16">
|
||||||
className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full"
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-center bg-red-500 text-white rounded-lg w-16 h-8 lg:h-16">
|
|
||||||
<svg
|
<svg
|
||||||
width="32"
|
width="32"
|
||||||
height="34"
|
height="34"
|
||||||
|
|
@ -647,32 +760,64 @@ const FilterPage = () => {
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
<div className="flex flex-col flex-1">
|
<div className="flex flex-col lg:flex-row lg:gap-2">
|
||||||
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
|
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm items-center">
|
||||||
{formatDateToIndonesian(
|
{formatDateToIndonesian(
|
||||||
new Date(audio?.createdAt)
|
new Date(audio?.createdAt)
|
||||||
)}{" "}
|
)}{" "}
|
||||||
{audio?.timezone ? audio?.timezone : "WIB"} |{" "}
|
{audio?.timezone ? audio?.timezone : "WIB"}
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm items-center">
|
||||||
|
|
|
||||||
<Icon
|
<Icon
|
||||||
icon="formkit:eye"
|
icon="formkit:eye"
|
||||||
width="15"
|
width="15"
|
||||||
height="15"
|
height="15"
|
||||||
/>{" "}
|
/>
|
||||||
{audio?.clickCount}{" "}
|
{audio?.clickCount}{" "}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">
|
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm h-5 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">
|
||||||
{audio?.title}
|
{audio?.title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
</CarouselItem>
|
|
||||||
))}
|
<div className="flex flex-col lg:flex-row items-center place-content-end gap-3">
|
||||||
</CarouselContent>
|
<img
|
||||||
<CarouselPrevious />
|
src="/assets/wave.svg"
|
||||||
<CarouselNext />
|
alt="wave"
|
||||||
</Carousel>
|
className="h-5 lg:h-16"
|
||||||
|
/>
|
||||||
|
<svg
|
||||||
|
width="17"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 32 34"
|
||||||
|
fill="null"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<p className="text-xs lg:text-sm text-center">
|
||||||
|
{" "}
|
||||||
|
{audio?.duration
|
||||||
|
? secondToTimes(Number(audio?.duration))
|
||||||
|
: "00:00:00"}
|
||||||
|
</p>
|
||||||
|
<Icon
|
||||||
|
icon="ph:download-fill"
|
||||||
|
className="text-red-500"
|
||||||
|
fontSize={20}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -684,16 +829,18 @@ const FilterPage = () => {
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<LandingPagination
|
<LandingPagination
|
||||||
table={table}
|
table={table}
|
||||||
totalData={totalData}
|
totalData={totalData}
|
||||||
totalPage={totalPage}
|
totalPage={totalPage}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,8 @@ const FilterPage = () => {
|
||||||
const poldaName = params?.polda_name;
|
const poldaName = params?.polda_name;
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -167,22 +169,51 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// fetchContent();
|
||||||
|
// }, []);
|
||||||
|
// const fetchContent = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchContent();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const fetchContent = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
|
pageNumber
|
||||||
);
|
);
|
||||||
console.log("category", response);
|
|
||||||
setCategories(response?.data?.data?.content);
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function initState() {
|
function initState() {
|
||||||
if (dateRange[0] != null && dateRange[1] != null) {
|
if (dateRange[0] != null && dateRange[1] != null) {
|
||||||
|
|
@ -280,10 +311,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -457,8 +489,7 @@ const FilterPage = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
<div className="flex flex-row md:flex-row items-start gap-3 py-10 px-4 lg:px-20 bg-[#f7f7f7] dark:bg-black">
|
||||||
<div className="flex flex-col md:flex-row items-start gap-5 p-10 bg-[#f7f7f7] dark:bg-black">
|
|
||||||
<p>
|
<p>
|
||||||
{" "}
|
{" "}
|
||||||
{t("text")} {">"} <span className="font-bold">{t("allText")}</span>
|
{t("text")} {">"} <span className="font-bold">{t("allText")}</span>
|
||||||
|
|
@ -468,7 +499,7 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 pl-4 lg:pl-20 py-4">
|
||||||
<div className="lg:w-[25%] 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} />
|
||||||
|
|
@ -566,6 +597,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
@ -666,6 +755,7 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Konten Kanan */}
|
{/* Konten Kanan */}
|
||||||
|
<div className="w-full pr-4 lg:pr-16 pb-4">
|
||||||
<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">
|
||||||
|
|
@ -704,7 +794,9 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col flex-1 gap-2">
|
<div className="flex flex-col flex-1 gap-2">
|
||||||
<div className="text-gray-500 dark:text-gray-400 flex flex-row items-center gap-2 text-xs">
|
<div className="text-gray-500 dark:text-gray-400 flex flex-row items-center gap-2 text-xs">
|
||||||
{formatDateToIndonesian(new Date(document?.createdAt))}{" "}
|
{formatDateToIndonesian(
|
||||||
|
new Date(document?.createdAt)
|
||||||
|
)}{" "}
|
||||||
{document?.timezone ? document?.timezone : "WIB"} |{" "}
|
{document?.timezone ? document?.timezone : "WIB"} |{" "}
|
||||||
<Icon icon="formkit:eye" width="15" height="15" /> 518
|
<Icon icon="formkit:eye" width="15" height="15" /> 518
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -748,6 +840,7 @@ const FilterPage = () => {
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ const FilterPage = () => {
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
||||||
const t = useTranslations("FilterPage");
|
const t = useTranslations("FilterPage");
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -169,21 +171,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// fetchContent();
|
||||||
|
// }, []);
|
||||||
|
// const fetchContent = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchContent();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const fetchContent = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
|
pageNumber
|
||||||
);
|
);
|
||||||
console.log("category", response);
|
|
||||||
setCategories(response?.data?.data?.content);
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -277,10 +307,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -435,8 +466,7 @@ const FilterPage = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
<div className="flex flex-row md:flex-row items-start gap-3 py-10 px-4 lg:px-20 bg-[#f7f7f7] dark:bg-black">
|
||||||
<div className="flex flex-col md:flex-row items-start gap-5 p-10 bg-[#f7f7f7] dark:bg-black">
|
|
||||||
<p>
|
<p>
|
||||||
{" "}
|
{" "}
|
||||||
{t("image")} {">"} <span className="font-bold">{t("allImage")}</span>
|
{t("image")} {">"} <span className="font-bold">{t("allImage")}</span>
|
||||||
|
|
@ -446,7 +476,7 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex w-fit flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 pl-4 lg:pl-20 py-4">
|
||||||
<div className="lg:hidden flex justify-end mb-2">
|
<div className="lg:hidden flex justify-end mb-2">
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsFilterOpen(!isFilterOpen)}
|
onClick={() => setIsFilterOpen(!isFilterOpen)}
|
||||||
|
|
@ -553,6 +583,66 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1
|
||||||
|
? "bg-[#bb3523] text-white"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
@ -624,6 +714,7 @@ const FilterPage = () => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Konten Kanan */}
|
{/* Konten Kanan */}
|
||||||
|
<div className="w-full pr-4 lg:pr-16 pb-4">
|
||||||
<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">
|
||||||
|
|
@ -646,7 +737,9 @@ const FilterPage = () => {
|
||||||
className="hover:scale-110 transition-transform duration-300"
|
className="hover:scale-110 transition-transform duration-300"
|
||||||
>
|
>
|
||||||
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
||||||
<Link href={`${prefixPath}/image/detail/${image?.slug}`}>
|
<Link
|
||||||
|
href={`${prefixPath}/image/detail/${image?.slug}`}
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src={image?.thumbnailLink}
|
src={image?.thumbnailLink}
|
||||||
className="h-60 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center"
|
className="h-60 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center"
|
||||||
|
|
@ -695,6 +788,7 @@ const FilterPage = () => {
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ const FilterPage = () => {
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
let prefixPath = satkerName ? `/satker/${satkerName}` : "/";
|
||||||
const t = useTranslations("FilterPage");
|
const t = useTranslations("FilterPage");
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -165,21 +167,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// fetchContent();
|
||||||
|
// }, []);
|
||||||
|
// const fetchContent = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchContent();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const fetchContent = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
|
pageNumber
|
||||||
);
|
);
|
||||||
console.log("category", response);
|
|
||||||
setCategories(response?.data?.data?.content);
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -273,10 +303,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -452,8 +483,7 @@ const FilterPage = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
<div className="flex flex-row md:flex-row items-start gap-3 py-10 px-4 lg:px-20 bg-[#f7f7f7] dark:bg-black">
|
||||||
<div className="flex flex-col md:flex-row items-start gap-5 p-10 bg-[#f7f7f7] dark:bg-black">
|
|
||||||
<p>
|
<p>
|
||||||
{" "}
|
{" "}
|
||||||
{t("video")}
|
{t("video")}
|
||||||
|
|
@ -464,7 +494,7 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Left */}
|
{/* Left */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6 p-4">
|
<div className="flex flex-col lg:flex-row gap-6 pl-4 lg:pl-20 py-4">
|
||||||
<div className="lg:w-[25%] 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} />
|
||||||
|
|
@ -562,6 +592,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
@ -662,6 +750,7 @@ const FilterPage = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Konten Kanan */}
|
{/* Konten Kanan */}
|
||||||
|
<div className="w-full pr-4 lg:pr-16 pb-4">
|
||||||
<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">
|
||||||
|
|
@ -684,7 +773,9 @@ const FilterPage = () => {
|
||||||
className="hover:scale-110 transition-transform duration-300"
|
className="hover:scale-110 transition-transform duration-300"
|
||||||
>
|
>
|
||||||
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
<CardContent className="flex flex-col text-xs lg:text-sm w-full p-0">
|
||||||
<Link href={`${prefixPath}/video/detail/${video?.slug}`}>
|
<Link
|
||||||
|
href={`${prefixPath}/video/detail/${video?.slug}`}
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src={video?.thumbnailLink}
|
src={video?.thumbnailLink}
|
||||||
className="h-60 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center"
|
className="h-60 object-cover items-center justify-center cursor-pointer rounded-lg place-self-center"
|
||||||
|
|
@ -733,6 +824,7 @@ const FilterPage = () => {
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,8 @@ const FilterPage = () => {
|
||||||
const [isLoading, setIsLoading] = useState<any>(true);
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
const poldaName = params?.polda_name;
|
const poldaName = params?.polda_name;
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -176,21 +177,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
);
|
pageNumber
|
||||||
console.log("category", response);
|
); // halaman 1-based
|
||||||
setCategories(response?.data?.data?.content);
|
|
||||||
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -296,10 +325,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -563,6 +593,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,8 @@ const FilterPage = () => {
|
||||||
const [isLoading, setIsLoading] = useState<any>(true);
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
const poldaName = params?.polda_name;
|
const poldaName = params?.polda_name;
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -176,21 +178,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
);
|
pageNumber
|
||||||
console.log("category", response);
|
); // halaman 1-based
|
||||||
setCategories(response?.data?.data?.content);
|
|
||||||
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -296,10 +326,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -578,6 +609,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,8 @@ const FilterPage = () => {
|
||||||
const [isFilterOpen, setIsFilterOpen] = useState(true);
|
const [isFilterOpen, setIsFilterOpen] = useState(true);
|
||||||
const poldaName = params?.polda_name;
|
const poldaName = params?.polda_name;
|
||||||
const satkerName = params?.satker_name;
|
const satkerName = params?.satker_name;
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
|
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
|
|
@ -179,19 +181,50 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
initFetch();
|
// initFetch();
|
||||||
}, []);
|
// }, []);
|
||||||
const initFetch = async () => {
|
// const initFetch = async () => {
|
||||||
const response = await getPublicCategoryData(
|
// const response = await getPublicCategoryData(
|
||||||
poldaName && String(poldaName)?.length > 1 ? poldaName : satkerName && String(satkerName)?.length > 1 ? "satker-" + satkerName : "",
|
// poldaName && String(poldaName)?.length > 1
|
||||||
"",
|
// ? poldaName
|
||||||
locale == "en" ? true : false
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
);
|
// ? "satker-" + satkerName
|
||||||
console.log("category", response);
|
// : "",
|
||||||
setCategories(response?.data?.data?.content);
|
// "",
|
||||||
};
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchCategories(categoryPage);
|
||||||
|
}, [categoryPage]);
|
||||||
|
|
||||||
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
|
? poldaName
|
||||||
|
: satkerName && satkerName.length > 1
|
||||||
|
? "satker-" + satkerName
|
||||||
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
|
"",
|
||||||
|
isInt,
|
||||||
|
pageNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function initState() {
|
function initState() {
|
||||||
|
|
@ -296,10 +329,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -593,6 +627,66 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1
|
||||||
|
? "bg-[#bb3523] text-white"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,8 @@ const FilterPage = () => {
|
||||||
const [userLevels, setUserLevels] = useState([]);
|
const [userLevels, setUserLevels] = useState([]);
|
||||||
const t = useTranslations("FilterPage");
|
const t = useTranslations("FilterPage");
|
||||||
const [isLoading, setIsLoading] = useState<any>(true);
|
const [isLoading, setIsLoading] = useState<any>(true);
|
||||||
|
const [categoryPage, setCategoryPage] = useState(1);
|
||||||
|
const [categoryTotalPages, setCategoryTotalPages] = useState(1);
|
||||||
// const [startDate, endDate] = dateRange;
|
// const [startDate, endDate] = dateRange;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -171,21 +172,49 @@ const FilterPage = () => {
|
||||||
// setCategories(resCategory);
|
// setCategories(resCategory);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// initFetch();
|
||||||
|
// }, []);
|
||||||
|
// const initFetch = async () => {
|
||||||
|
// const response = await getPublicCategoryData(
|
||||||
|
// poldaName && String(poldaName)?.length > 1
|
||||||
|
// ? poldaName
|
||||||
|
// : satkerName && String(satkerName)?.length > 1
|
||||||
|
// ? "satker-" + satkerName
|
||||||
|
// : "",
|
||||||
|
// "",
|
||||||
|
// locale == "en" ? true : false
|
||||||
|
// );
|
||||||
|
// console.log("category", response);
|
||||||
|
// setCategories(response?.data?.data?.content);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
fetchCategories(categoryPage);
|
||||||
}, []);
|
}, [categoryPage]);
|
||||||
const initFetch = async () => {
|
|
||||||
const response = await getPublicCategoryData(
|
const fetchCategories = async (pageNumber: number) => {
|
||||||
poldaName && String(poldaName)?.length > 1
|
const groupParam =
|
||||||
|
poldaName && poldaName.length > 1
|
||||||
? poldaName
|
? poldaName
|
||||||
: satkerName && String(satkerName)?.length > 1
|
: satkerName && satkerName.length > 1
|
||||||
? "satker-" + satkerName
|
? "satker-" + satkerName
|
||||||
: "",
|
: "";
|
||||||
|
|
||||||
|
const isInt = locale === "en";
|
||||||
|
|
||||||
|
const response = await getPublicCategoryData(
|
||||||
|
groupParam,
|
||||||
"",
|
"",
|
||||||
locale == "en" ? true : false
|
isInt,
|
||||||
);
|
pageNumber
|
||||||
console.log("category", response);
|
); // halaman 1-based
|
||||||
setCategories(response?.data?.data?.content);
|
|
||||||
|
const content = response?.data?.data?.content || [];
|
||||||
|
const total = response?.data?.data?.totalPages || 1;
|
||||||
|
|
||||||
|
setCategories(content);
|
||||||
|
setCategoryTotalPages(total);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -290,10 +319,11 @@ const FilterPage = () => {
|
||||||
let filter = [...categoryFilter];
|
let filter = [...categoryFilter];
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
filter = [...categoryFilter, String(id)];
|
filter = [...filter, String(id)];
|
||||||
} else {
|
} else {
|
||||||
filter.splice(categoryFilter.indexOf(id), 1);
|
filter = filter.filter((item) => item !== String(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("checkbox filter", filter);
|
console.log("checkbox filter", filter);
|
||||||
setCategoryFilter(filter);
|
setCategoryFilter(filter);
|
||||||
router.push(`?category=${filter.join("&")}`);
|
router.push(`?category=${filter.join("&")}`);
|
||||||
|
|
@ -580,6 +610,64 @@ const FilterPage = () => {
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
<div className="mt-4 flex gap-2 justify-center items-center">
|
||||||
|
{/* Tombol Prev */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) => Math.max(prev - 1, 1))
|
||||||
|
}
|
||||||
|
disabled={categoryPage === 1}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m13.15 16.15l-3.625-3.625q-.125-.125-.175-.25T9.3 12t.05-.275t.175-.25L13.15 7.85q.075-.075.163-.112T13.5 7.7q.2 0 .35.138T14 8.2v7.6q0 .225-.15.363t-.35.137q-.05 0-.35-.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Nomor Halaman */}
|
||||||
|
{Array.from({ length: categoryTotalPages }, (_, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCategoryPage(i + 1)}
|
||||||
|
className={`px-3 py-1 border rounded ${
|
||||||
|
categoryPage === i + 1 ? "bg-[#bb3523] text-white" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i + 1}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Tombol Next */}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategoryPage((prev) =>
|
||||||
|
Math.min(prev + 1, categoryTotalPages)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={categoryPage === categoryTotalPages}
|
||||||
|
className="px-3 py-1 border rounded disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M10.5 16.3q-.2 0-.35-.137T10 15.8V8.2q0-.225.15-.362t.35-.138q.05 0 .35.15l3.625 3.625q.125.125.175.25t.05.275t-.05.275t-.175.25L10.85 16.15q-.075.075-.162.113t-.188.037"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/* Garis */}
|
{/* Garis */}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,14 @@ import Image from "next/image";
|
||||||
import Coverage from "./coverage";
|
import Coverage from "./coverage";
|
||||||
import Division from "./division";
|
import Division from "./division";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { useParams } from "next/navigation";
|
||||||
|
|
||||||
const AreaCoverageWorkUnits = () => {
|
const AreaCoverageWorkUnits = () => {
|
||||||
const [openPolda, setOpenPolda] = useState(false);
|
const [openPolda, setOpenPolda] = useState(false);
|
||||||
const [openSatker, setOpenSatker] = useState(false);
|
const [openSatker, setOpenSatker] = useState(false);
|
||||||
const t = useTranslations("LandingPage");
|
const t = useTranslations("LandingPage");
|
||||||
|
const params = useParams();
|
||||||
|
const locale = params?.locale;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (openPolda || openSatker) {
|
if (openPolda || openSatker) {
|
||||||
|
|
@ -31,13 +34,17 @@ const AreaCoverageWorkUnits = () => {
|
||||||
document.body.classList.remove("overflow-hidden");
|
document.body.classList.remove("overflow-hidden");
|
||||||
};
|
};
|
||||||
}, [openPolda, openSatker]);
|
}, [openPolda, openSatker]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{locale === "in" && (
|
||||||
<div className="mx-auto px-4 lg:px-0 py-6">
|
<div className="mx-auto px-4 lg:px-0 py-6">
|
||||||
<h2 className="text-start text-lg md:text-xl font-bold text-[#bb3523] border-b-2 border-[#bb3523] mb-4 uppercase">
|
<h2 className="text-start text-lg md:text-xl font-bold text-[#bb3523] border-b-2 border-[#bb3523] mb-4 uppercase">
|
||||||
{t("areaCoverage")}
|
{t("areaCoverage")}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="flex flex-col justify-center lg:flex-row gap-8 ">
|
<div className="flex flex-col justify-center lg:flex-row gap-8 ">
|
||||||
{/* POLDA */}
|
{/* POLDA */}
|
||||||
|
|
||||||
<Dialog open={openPolda} onOpenChange={setOpenPolda}>
|
<Dialog open={openPolda} onOpenChange={setOpenPolda}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<button
|
<button
|
||||||
|
|
@ -81,6 +88,7 @@ const AreaCoverageWorkUnits = () => {
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
{/* SATKER */}
|
{/* SATKER */}
|
||||||
|
|
||||||
<Dialog open={openSatker} onOpenChange={setOpenSatker}>
|
<Dialog open={openSatker} onOpenChange={setOpenSatker}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<button className="flex flex-col gap-2 justify-center items-center shadow-lg group rounded-xl py-5 w-full border-2 border-transparent hover:border-[#bb3523] transition-all duration-300">
|
<button className="flex flex-col gap-2 justify-center items-center shadow-lg group rounded-xl py-5 w-full border-2 border-transparent hover:border-[#bb3523] transition-all duration-300">
|
||||||
|
|
@ -115,6 +123,8 @@ const AreaCoverageWorkUnits = () => {
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import Image from "next/image";
|
||||||
const regions = [
|
const regions = [
|
||||||
{ name: "ITWASUM POLRI", slug: "itwasum", logo: "/logo/satker/ITWASUM.png" },
|
{ name: "ITWASUM POLRI", slug: "itwasum", logo: "/logo/satker/ITWASUM.png" },
|
||||||
{
|
{
|
||||||
name: "BAINTELKAM POLRI",
|
name: "BAINTELKAM POLRI ",
|
||||||
slug: "baintelkam",
|
slug: "baintelkam",
|
||||||
logo: "/logo/satker/BAINTELKAM.png",
|
logo: "/logo/satker/BAINTELKAM.png",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { getCalendarPagination } from "@/service/schedule/schedule";
|
import { getCalendarPagination } from "@/service/schedule/schedule";
|
||||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { useParams } from "next/navigation";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
interface CalendarItem {
|
interface CalendarItem {
|
||||||
|
|
@ -24,12 +25,13 @@ const EventCalender = () => {
|
||||||
const currentMonth = today.getMonth();
|
const currentMonth = today.getMonth();
|
||||||
const currentYear = today.getFullYear();
|
const currentYear = today.getFullYear();
|
||||||
const currentDate = today.getDate();
|
const currentDate = today.getDate();
|
||||||
|
|
||||||
const [events, setEvents] = useState<CalendarItem[]>([]);
|
const [events, setEvents] = useState<CalendarItem[]>([]);
|
||||||
const [selectedEvent, setSelectedEvent] = useState<CalendarItem | null>(null);
|
const [selectedEvent, setSelectedEvent] = useState<CalendarItem | null>(null);
|
||||||
const [month, setMonth] = useState(currentMonth);
|
const [month, setMonth] = useState(currentMonth);
|
||||||
const [year, setYear] = useState(currentYear);
|
const [year, setYear] = useState(currentYear);
|
||||||
const t = useTranslations("LandingPage");
|
const t = useTranslations("LandingPage");
|
||||||
|
const params = useParams();
|
||||||
|
const locale = params?.locale;
|
||||||
|
|
||||||
const monthNames = [
|
const monthNames = [
|
||||||
t("january"),
|
t("january"),
|
||||||
|
|
@ -164,6 +166,8 @@ const EventCalender = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{locale === "in" && (
|
||||||
<div className="mt-8 rounded-lg bg-white dark:bg-zinc-900 p-4 shadow">
|
<div className="mt-8 rounded-lg bg-white dark:bg-zinc-900 p-4 shadow">
|
||||||
<h2 className="text-lg font-bold text-red-600 border-b border-red-600 mb-4 pb-2">
|
<h2 className="text-lg font-bold text-red-600 border-b border-red-600 mb-4 pb-2">
|
||||||
{t("calendar")}
|
{t("calendar")}
|
||||||
|
|
@ -276,7 +280,8 @@ const EventCalender = () => {
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
selectedEvent.thumbnailUrl || "/images/default-event.png"
|
selectedEvent.thumbnailUrl ||
|
||||||
|
"/images/default-event.png"
|
||||||
}
|
}
|
||||||
alt={selectedEvent.title}
|
alt={selectedEvent.title}
|
||||||
className="w-full h-48 object-cover rounded-lg"
|
className="w-full h-48 object-cover rounded-lg"
|
||||||
|
|
@ -327,6 +332,8 @@ const EventCalender = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,11 @@ const HeroModal = ({
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const locale = params?.locale;
|
const locale = params?.locale;
|
||||||
const swiperRef = useRef<SwiperClass | null>(null);
|
const swiperRef = useRef<SwiperClass | null>(null);
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
|
if (pathname?.includes("/polda") || pathname?.includes("/satker")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let prefixPath = poldaName
|
let prefixPath = poldaName
|
||||||
? `/polda/${poldaName}`
|
? `/polda/${poldaName}`
|
||||||
|
|
@ -462,7 +467,7 @@ const HeroNew = (props: { group?: string }) => {
|
||||||
</Carousel>
|
</Carousel>
|
||||||
|
|
||||||
<div className="hidden lg:flex flex-col gap-3 absolute bottom-4 right-4 w-[520px] bg-black/40 p-4 rounded-lg z-10">
|
<div className="hidden lg:flex flex-col gap-3 absolute bottom-4 right-4 w-[520px] bg-black/40 p-4 rounded-lg z-10">
|
||||||
{newContent?.slice(0, 3).map((item: any) => (
|
{content?.slice(0, 3).map((item: any) => (
|
||||||
<li key={item?.id} className="flex gap-4 flex-row lg:w-full mx-2">
|
<li key={item?.id} className="flex gap-4 flex-row lg:w-full mx-2">
|
||||||
<div className="flex-shrink-0 w-32 rounded-lg">
|
<div className="flex-shrink-0 w-32 rounded-lg">
|
||||||
<Image
|
<Image
|
||||||
|
|
@ -476,7 +481,7 @@ const HeroNew = (props: { group?: string }) => {
|
||||||
className="w-full h-[100px] object-cover rounded-lg"
|
className="w-full h-[100px] object-cover rounded-lg"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-[280px] lg:w-[200px]">
|
<div className="w-[280px] lg:w-full">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
Number(item?.fileTypeId) == 1
|
Number(item?.fileTypeId) == 1
|
||||||
|
|
@ -487,14 +492,15 @@ const HeroNew = (props: { group?: string }) => {
|
||||||
? `${prefixPath}/document/detail/${item?.slug}`
|
? `${prefixPath}/document/detail/${item?.slug}`
|
||||||
: `${prefixPath}/audio/detail/${item?.slug}`
|
: `${prefixPath}/audio/detail/${item?.slug}`
|
||||||
}
|
}
|
||||||
|
className="flex flex-col justify-between"
|
||||||
>
|
>
|
||||||
<span className="py-1 rounded-lg flex text-red-600 font-bold uppercase w-fit">
|
<p className="rounded-lg flex text-red-600 font-bold uppercase w-fit">
|
||||||
{item?.categoryName}
|
{item?.categoryName}
|
||||||
</span>
|
</p>
|
||||||
<h3 className="text-base text-white font-bold h-6 hover:h-auto truncate hover:whitespace-normal hover:overflow-visible">
|
<h3 className="text-base text-white font-bold">
|
||||||
{item?.title}
|
{item?.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-[10px] flex flex-row items-center gap-1 text-white mt-1">
|
<p className="text-[10px] flex flex-row items-center gap-1 text-white mt-2">
|
||||||
{formatDateToIndonesian(new Date(item?.createdAt))}{" "}
|
{formatDateToIndonesian(new Date(item?.createdAt))}{" "}
|
||||||
{item?.timezone || "WIB"} |{" "}
|
{item?.timezone || "WIB"} |{" "}
|
||||||
<svg
|
<svg
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,9 @@ import {
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from "@/components/ui/popover";
|
} from "@/components/ui/popover";
|
||||||
import PoldaLogo from "./polda-logo";
|
|
||||||
import { DynamicLogoPolda } from "./dynamic-logo-polda";
|
import { DynamicLogoPolda } from "./dynamic-logo-polda";
|
||||||
import { DynamicLogoSatker } from "./dynamic-logo-satker";
|
import { DynamicLogoSatker } from "./dynamic-logo-satker";
|
||||||
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
||||||
|
|
||||||
type Detail = {
|
type Detail = {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -93,6 +93,8 @@ const Navbar = () => {
|
||||||
const [notificationsUpdate, setNotificationsUpdate] = useState([]);
|
const [notificationsUpdate, setNotificationsUpdate] = useState([]);
|
||||||
const [selectedTab, setSelectedTab] = useState("image");
|
const [selectedTab, setSelectedTab] = useState("image");
|
||||||
|
|
||||||
|
const isHidden = pathname?.includes("polda") || pathname?.includes("satker");
|
||||||
|
|
||||||
let prefixPath = poldaName
|
let prefixPath = poldaName
|
||||||
? `/polda/${poldaName}`
|
? `/polda/${poldaName}`
|
||||||
: satkerName
|
: satkerName
|
||||||
|
|
@ -109,19 +111,18 @@ const Navbar = () => {
|
||||||
window.location.href = "/";
|
window.location.href = "/";
|
||||||
};
|
};
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// if (!roleId) {
|
// if (!roleId) {
|
||||||
// router.replace("/"); // Kalau roleId-nya belum tersedia, redirect juga (opsional)
|
// router.replace("/"); // Kalau roleId-nya belum tersedia, redirect juga (opsional)
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// const token = Cookies.get(roleId);
|
// const token = Cookies.get(roleId);
|
||||||
|
|
||||||
// if (!token) {
|
|
||||||
// router.replace("/"); // Redirect ke halaman home jika tidak ada token
|
|
||||||
// }
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
|
// if (!token) {
|
||||||
|
// router.replace("/"); // Redirect ke halaman home jika tidak ada token
|
||||||
|
// }
|
||||||
|
// }, []);
|
||||||
|
|
||||||
// const profilePicture = Cookies.get("profile_picture");
|
// const profilePicture = Cookies.get("profile_picture");
|
||||||
const fullName = getCookiesDecrypt("ufne");
|
const fullName = getCookiesDecrypt("ufne");
|
||||||
|
|
@ -202,6 +203,8 @@ const Navbar = () => {
|
||||||
return () => clearTimeout(handler);
|
return () => clearTimeout(handler);
|
||||||
}, [onSearch]);
|
}, [onSearch]);
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
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-16 py-2 gap-3">
|
<div className="flex items-center justify-between px-4 lg:px-16 py-2 gap-3">
|
||||||
|
|
@ -218,13 +221,13 @@ const Navbar = () => {
|
||||||
<DynamicLogoPolda /> <DynamicLogoSatker />
|
<DynamicLogoPolda /> <DynamicLogoSatker />
|
||||||
{/* Nav Menu */}
|
{/* Nav Menu */}
|
||||||
<div className="hidden custom-lg-button:flex items-center gap-5">
|
<div className="hidden custom-lg-button:flex items-center gap-5">
|
||||||
<NavigationMenu>
|
<div className="flex gap-4 items-center">
|
||||||
<NavigationMenuList>
|
{/* Popover Utama */}
|
||||||
<NavigationMenuItem>
|
<Popover open={open} onOpenChange={setOpen}>
|
||||||
<NavigationMenuTrigger>
|
<PopoverTrigger asChild>
|
||||||
<a className="dark:text-white text-black flex flex-row justify-center items-center cursor-pointer ">
|
<button className="dark:text-white text-black flex items-center gap-3 cursor-pointer bg-transparent border-none focus:outline-none">
|
||||||
<svg
|
<svg
|
||||||
className="mx-2 dark:"
|
className="mx-1"
|
||||||
width="25"
|
width="25"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 25 24"
|
viewBox="0 0 25 24"
|
||||||
|
|
@ -236,64 +239,50 @@ const Navbar = () => {
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
{t("content")}
|
<span>{t("content")}</span>
|
||||||
</a>
|
{open ? (
|
||||||
</NavigationMenuTrigger>
|
<ChevronUp className="w-4 h-4 transition-all" />
|
||||||
<NavigationMenuContent className="flex flex-col place-content-start rounded-md overflow-hidden ">
|
) : (
|
||||||
<NavigationMenuLink
|
<ChevronDown className="w-4 h-4 transition-all" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
|
||||||
|
<PopoverContent className="flex flex-col gap-2 w-fit px-6 py-4 rounded-md shadow-md bg-white dark:bg-black">
|
||||||
|
<button
|
||||||
onClick={() => router.push(prefixPath + "/image/filter")}
|
onClick={() => router.push(prefixPath + "/image/filter")}
|
||||||
className="flex place-items-start gap-1 px-3 py-1 w-36"
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
>
|
>
|
||||||
<p className="text-slate-600 dark:text-white hover:text-[#bb3523] flex flex-row items-center py-1 cursor-pointer">
|
|
||||||
<FiImage className="mr-2" />
|
<FiImage className="mr-2" />
|
||||||
{t("image")}
|
{t("image")}
|
||||||
</p>
|
</button>
|
||||||
</NavigationMenuLink>
|
<button
|
||||||
<NavigationMenuLink
|
|
||||||
onClick={() => router.push(prefixPath + "/video/filter")}
|
onClick={() => router.push(prefixPath + "/video/filter")}
|
||||||
className="flex items-start gap-1 py-1 px-3 "
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
>
|
>
|
||||||
{pathname?.split("/")[1] == "in" ? (
|
|
||||||
<>
|
|
||||||
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-1 cursor-pointer">
|
|
||||||
<FiYoutube className="mr-2" />
|
<FiYoutube className="mr-2" />
|
||||||
{t("video")}
|
{t("video")}
|
||||||
</p>
|
</button>
|
||||||
</>
|
<button
|
||||||
) : (
|
onClick={() => router.push(prefixPath + "/document/filter")}
|
||||||
<>
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-1 cursor-pointer">
|
|
||||||
<FiYoutube className="mr-2" />
|
|
||||||
{t("video")}
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</NavigationMenuLink>
|
|
||||||
<NavigationMenuLink
|
|
||||||
onClick={() =>
|
|
||||||
router.push(prefixPath + "/document/filter")
|
|
||||||
}
|
|
||||||
className="flex place-items-start gap-1 py-1 px-3"
|
|
||||||
>
|
>
|
||||||
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-1 cursor-pointer">
|
|
||||||
<FiFile className="mr-2" />
|
<FiFile className="mr-2" />
|
||||||
{t("text")}
|
{t("text")}
|
||||||
</p>
|
</button>
|
||||||
</NavigationMenuLink>
|
<button
|
||||||
<NavigationMenuLink
|
|
||||||
onClick={() => router.push(prefixPath + "/audio/filter")}
|
onClick={() => router.push(prefixPath + "/audio/filter")}
|
||||||
className="flex place-items-start gap-1 py-1 px-3 "
|
className="flex items-center text-slate-600 dark:text-white hover:text-[#bb3523]"
|
||||||
>
|
>
|
||||||
<p className="text-slate-600 text-left dark:text-white hover:text-[#bb3523] flex flex-row justify-center items-center py-1 cursor-pointer">
|
|
||||||
<FiMusic className="mr-2" />
|
<FiMusic className="mr-2" />
|
||||||
{t("audio")}{" "}
|
{t("audio")}
|
||||||
</p>
|
</button>
|
||||||
</NavigationMenuLink>
|
</PopoverContent>
|
||||||
</NavigationMenuContent>
|
</Popover>
|
||||||
</NavigationMenuItem>
|
|
||||||
<NavigationMenuItem>
|
{/* Link Schedule */}
|
||||||
<Link href={prefixPath + "/schedule"} legacyBehavior passHref>
|
<Link href={prefixPath + "/schedule"} passHref legacyBehavior>
|
||||||
<NavigationMenuLink className="group inline-flex h-10 w-max items-center justify-center rounded-md bg-[#f7f7f7] dark:bg-black xl:px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50">
|
<a className="group inline-flex h-10 items-center text-center justify-center rounded-md bg-[#f7f7f7] dark:bg-black xl:px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:outline-none">
|
||||||
<span>
|
<span>
|
||||||
<svg
|
<svg
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
|
|
@ -310,12 +299,12 @@ const Navbar = () => {
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
{t("schedule")}
|
{t("schedule")}
|
||||||
</NavigationMenuLink>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</NavigationMenuItem>
|
|
||||||
<NavigationMenuItem>
|
{/* Link Index */}
|
||||||
<Link href={prefixPath + "/indeks"} legacyBehavior passHref>
|
<Link href={prefixPath + "/indeks"} passHref legacyBehavior>
|
||||||
<NavigationMenuLink className="group inline-flex h-10 w-max items-center justify-center rounded-md bg-[#f7f7f7] dark:bg-black xl:px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50">
|
<a className="group inline-flex h-10 items-center justify-center text-center rounded-md bg-[#f7f7f7] dark:bg-black xl:px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:outline-none">
|
||||||
<span>
|
<span>
|
||||||
<svg
|
<svg
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
|
|
@ -334,15 +323,11 @@ const Navbar = () => {
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
{t("index")}
|
{t("index")}
|
||||||
</NavigationMenuLink>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</NavigationMenuItem>
|
|
||||||
</NavigationMenuList>
|
|
||||||
</NavigationMenu>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{/* Mobile Menu Toggle */}
|
|
||||||
|
|
||||||
{/* Desktop Navigation */}
|
{/* Desktop Navigation */}
|
||||||
<div className="hidden custom-lg-button:flex lg:flex items-center xl:gap-5">
|
<div className="hidden custom-lg-button:flex lg:flex items-center xl:gap-5">
|
||||||
|
|
@ -399,7 +384,7 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Languange */}
|
{/* Languange */}
|
||||||
<div className="hidden custom-lg-button:flex relative text-left">
|
<div className={`${isHidden ? "hidden" : "custom-lg-button:flex"} relative text-left`}>
|
||||||
<LocalSwitcher />
|
<LocalSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1030,7 +1015,7 @@ const Navbar = () => {
|
||||||
{/* Mobile Menu */}
|
{/* Mobile Menu */}
|
||||||
{menuOpen && (
|
{menuOpen && (
|
||||||
<div className="custom-lg-button:hidden absolute bg-[#f7f7f7] dark:bg-slate-600 px-4 py-3 w-full space-y-3 z-50 ">
|
<div className="custom-lg-button:hidden absolute bg-[#f7f7f7] dark:bg-slate-600 px-4 py-3 w-full space-y-3 z-50 ">
|
||||||
<div className="flex flex-row pl-5 ">
|
<div className="flex flex-col gap-2">
|
||||||
<NavigationMenu>
|
<NavigationMenu>
|
||||||
<NavigationMenuList>
|
<NavigationMenuList>
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
|
|
@ -1242,13 +1227,13 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className=" py-1 flex items-center mx-3">
|
<div className="py-1 flex items-center mx-3">
|
||||||
<input
|
<input
|
||||||
value={onSearch}
|
value={onSearch}
|
||||||
onChange={(e) => setOnSearch(e.target.value)}
|
onChange={(e) => setOnSearch(e.target.value)}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
className="pl-8 pr-4 py-1 w-28 text-[13px] border rounded-full focus:outline-none dark:text-white"
|
className="pl-8 pr-4 py-1 text-[13px] border rounded-full focus:outline-none dark:text-white w-full "
|
||||||
/>{" "}
|
/>{" "}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1793,7 +1778,7 @@ const Navbar = () => {
|
||||||
<div className="flex justify-center items-center mx-3 gap-1 lg:gap-1 xl:gap-5">
|
<div className="flex justify-center items-center mx-3 gap-1 lg:gap-1 xl:gap-5">
|
||||||
<Link
|
<Link
|
||||||
href="/auth"
|
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"
|
className="w-[50%] px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 text-center"
|
||||||
>
|
>
|
||||||
{t("logIn")}
|
{t("logIn")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
@ -1801,7 +1786,7 @@ const Navbar = () => {
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
className="w-full lg:w-fit px-4 h-8 border bg-white border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-[#bb3523] hover:text-white"
|
className="w-[50%] px-4 h-8 border bg-white border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-[#bb3523] hover:text-white"
|
||||||
>
|
>
|
||||||
{t("register")}
|
{t("register")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -243,20 +243,29 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Caption section */}
|
{/* Caption section */}
|
||||||
<div className="p-4">
|
<div className="p-4 h-full flex flex-col justify-between">
|
||||||
<p className="text-[12px] font-bold text-[#bb3523] uppercase mb-1">
|
<div className="flex flex-col gap-1 flex-grow">
|
||||||
|
<p className="text-[10px] font-bold text-[#bb3523] uppercase">
|
||||||
{image?.categoryName?.toUpperCase() ??
|
{image?.categoryName?.toUpperCase() ??
|
||||||
"Giat Pimpinan"}
|
"Giat Pimpinan"}
|
||||||
</p>
|
</p>
|
||||||
|
<p
|
||||||
<p className="text-lg font-semibold text-black truncate">
|
className="
|
||||||
|
text-sm lg:text-base font-semibold text-black
|
||||||
|
line-clamp-4 /* LIMIT to 2 lines if plugin available */
|
||||||
|
/* or use min-h-[3rem] as fallback */
|
||||||
|
"
|
||||||
|
>
|
||||||
{image?.title}
|
{image?.title}
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
{/* <p className="flex flex-row items-center text-[10px] gap-1 mt-2 text-gray-600">
|
{/* Optional metadata area (uncomment if needed) */}
|
||||||
|
{/*
|
||||||
|
<p className="flex flex-row items-center text-[10px] gap-1 mt-2 text-gray-600">
|
||||||
{formatDateToIndonesian(new Date(image?.createdAt))} {image?.timezone ?? "WIB"} |
|
{formatDateToIndonesian(new Date(image?.createdAt))} {image?.timezone ?? "WIB"} |
|
||||||
<Icon icon="formkit:eye" width="15" height="15" /> {image.clickCount}
|
<Icon icon="formkit:eye" width="15" height="15" /> {image.clickCount}
|
||||||
</p> */}
|
</p>
|
||||||
|
*/}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
|
|
@ -329,7 +338,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
"GIAT PIMPINAN"}
|
"GIAT PIMPINAN"}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-xl font-semibold text-black truncate">
|
<p className="text-xl font-semibold text-black line-clamp-4">
|
||||||
{audio?.title}
|
{audio?.title}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -427,19 +436,24 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Caption section */}
|
{/* Caption section */}
|
||||||
<div className="p-4">
|
<div className="p-4 h-full flex flex-col justify-between">
|
||||||
<p className="text-[12px] font-bold text-[#bb3523] uppercase mb-1">
|
<div className="flex flex-col gap-1 flex-grow">
|
||||||
{video?.categoryName?.toUpperCase() ?? "Video"}
|
<p className="text-[10px] font-bold text-[#bb3523] uppercase">
|
||||||
|
{video?.categoryName?.toUpperCase() ??
|
||||||
|
"Giat Pimpinan"}
|
||||||
</p>
|
</p>
|
||||||
|
<p
|
||||||
<p className="text-lg font-semibold text-black truncate">
|
className="text-sm lg:text-base font-semibold text-black line-clamp-5">
|
||||||
{video?.title}
|
{video?.title}
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
{/* <p className="flex flex-row items-center text-[10px] gap-1 mt-2 text-gray-600">
|
{/* Optional metadata area (uncomment if needed) */}
|
||||||
{formatDateToIndonesian(new Date(video?.createdAt))} {video?.timezone ?? "WIB"} |
|
{/*
|
||||||
<Icon icon="formkit:eye" width="15" height="15" /> {video?.clickCount}
|
<p className="flex flex-row items-center text-[10px] gap-1 mt-2 text-gray-600">
|
||||||
</p> */}
|
{formatDateToIndonesian(new Date(image?.createdAt))} {image?.timezone ?? "WIB"} |
|
||||||
|
<Icon icon="formkit:eye" width="15" height="15" /> {image.clickCount}
|
||||||
|
</p>
|
||||||
|
*/}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
|
|
@ -513,7 +527,7 @@ const NewContent = (props: { group: string; type: string }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Judul */}
|
{/* Judul */}
|
||||||
<div className="font-semibold text-gray-900 text-xl leading-snug line-clamp-2">
|
<div className="font-semibold text-gray-900 text-xl leading-snug line-clamp-4">
|
||||||
{text?.title}
|
{text?.title}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ const ScrollableContent = () => {
|
||||||
|
|
||||||
setContentPolda(data);
|
setContentPolda(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const initFetchSatker = async () => {
|
const initFetchSatker = async () => {
|
||||||
const response = await getHeroData(locale == "en", "satker");
|
const response = await getHeroData(locale == "en", "satker");
|
||||||
console.log(response);
|
console.log(response);
|
||||||
|
|
@ -79,8 +80,8 @@ const ScrollableContent = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="">
|
<div className="w-full">
|
||||||
<h1 className="text-2xl md:text-3xl font-bold text-gray-800 dark:text-white">
|
<h1 className="text-[18px] md:text-3xl font-bold text-gray-800 dark:text-white">
|
||||||
<span className="text-[#c03724] dark:text-white">
|
<span className="text-[#c03724] dark:text-white">
|
||||||
{t("exploration")} {t("and")}
|
{t("exploration")} {t("and")}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -151,7 +152,7 @@ const ScrollableContent = () => {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(`/${contentType}/filter?title=${search}`)
|
router.push(`/${contentType}/filter?title=${search}`)
|
||||||
}
|
}
|
||||||
className="flex justify-center items-center px-6 w-full lg:w-[20%] py-4 bg-[#bb3523] gap-2 text-white rounded-lg hover:bg-red-700"
|
className="flex justify-center items-center px-6 w-full lg:w-[20%] py-4 bg-[#bb3523] gap-2 text-white rounded-lg hover:bg-red-700 text-[14px]"
|
||||||
>
|
>
|
||||||
{t("searchCoverage")}
|
{t("searchCoverage")}
|
||||||
<Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
<Icon icon="ri:arrow-right-s-line" fontSize={20} />
|
||||||
|
|
@ -160,15 +161,18 @@ const ScrollableContent = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col md:flex-row gap-6 py-8">
|
<div className="flex flex-col md:flex-row gap-6 py-8">
|
||||||
{/* Berita Polda */}
|
{/* Berita Polda */}
|
||||||
<div className="w-full md:w-1/2 px-4">
|
{locale === "in" && (
|
||||||
|
<div className="w-full md:w-1/2 px-0 lg:px-4">
|
||||||
<h2 className="text-lg md:text-xl font-bold text-[#bb3523] mb-2 uppercase">
|
<h2 className="text-lg md:text-xl font-bold text-[#bb3523] mb-2 uppercase">
|
||||||
{t("regionNews")}
|
{t("regionNews")}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="w-[10%] h-1 bg-[#bb3523]"></div>
|
<div className="w-[10%] h-1 bg-[#bb3523]"></div>
|
||||||
<div className="w-full h-1 bg-[#bb3523] mx-auto mb-4"></div>
|
<div className="w-full h-1 bg-[#bb3523] mx-auto mb-4"></div>
|
||||||
<div className="grid gap-4">
|
<div className="grid gap-4">
|
||||||
{(seeAllValuePolda ? contentPolda : contentPolda?.slice(0, 3))?.map(
|
{(seeAllValuePolda
|
||||||
(item: any, index: number) => (
|
? contentPolda
|
||||||
|
: contentPolda?.slice(0, 3)
|
||||||
|
)?.map((item: any, index: number) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={`bg-white rounded-lg shadow-md overflow-hidden ${
|
className={`bg-white rounded-lg shadow-md overflow-hidden ${
|
||||||
|
|
@ -215,17 +219,6 @@ const ScrollableContent = () => {
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{/* <Link
|
|
||||||
href={
|
|
||||||
Number(item?.fileTypeId) == 1
|
|
||||||
? `${prefixPath}/image/detail/${item?.slug}`
|
|
||||||
: Number(item?.fileTypeId) == 2
|
|
||||||
? `${prefixPath}/video/detail/${item?.slug}`
|
|
||||||
: Number(item?.fileTypeId) == 3
|
|
||||||
? `${prefixPath}/document/detail/${item?.slug}`
|
|
||||||
: `${prefixPath}/audio/detail/${item?.slug}`
|
|
||||||
}
|
|
||||||
> */}
|
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
Number(item?.fileTypeId) == 1
|
Number(item?.fileTypeId) == 1
|
||||||
|
|
@ -240,19 +233,18 @@ const ScrollableContent = () => {
|
||||||
index === 0 ? "p-4" : "p-3 w-[50%] cursor-pointer"
|
index === 0 ? "p-4" : "p-3 w-[50%] cursor-pointer"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<p className="text-sm text-[#bb3523] font-bold mb-1">
|
<p className="text-sm text-[#bb3523] font-bold mb-1 px-2">
|
||||||
{item.categoryName}
|
{item.categoryName}
|
||||||
</p>
|
</p>
|
||||||
<h3 className="text-sm font-semibold text-gray-800">
|
<h3 className="text-sm font-semibold text-gray-800 px-2">
|
||||||
{item.title}
|
{item.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-xs text-gray-500 mt-1 truncate">
|
<p className="text-xs text-gray-500 mt-1 truncate px-2">
|
||||||
{htmlToString(item.description)}
|
{htmlToString(item.description)}
|
||||||
</p>
|
</p>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
{contentPolda?.length > 3 && (
|
{contentPolda?.length > 3 && (
|
||||||
<div className="flex items-center flex-row justify-start mt-6">
|
<div className="flex items-center flex-row justify-start mt-6">
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -282,61 +274,17 @@ const ScrollableContent = () => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Berita SATKER */}
|
{/* Berita SATKER */}
|
||||||
<div className="w-full md:w-1/2 px-4">
|
{locale === "in" && (
|
||||||
|
<div className="w-full md:w-1/2 px-0 lg:px-4">
|
||||||
<h2 className="text-lg md:text-xl font-bold mb-2 text-[#bb3523] uppercase">
|
<h2 className="text-lg md:text-xl font-bold mb-2 text-[#bb3523] uppercase">
|
||||||
{t("divisionNews")}
|
{t("divisionNews")}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="w-[10%] h-1 bg-[#bb3523]"></div>
|
<div className="w-[10%] h-1 bg-[#bb3523]"></div>
|
||||||
<div className="w-full h-1 bg-[#bb3523] mx-auto mb-4"></div>
|
<div className="w-full h-1 bg-[#bb3523] mx-auto mb-4"></div>
|
||||||
<div className="grid gap-4">
|
<div className="grid gap-4">
|
||||||
{/* {seeAllValue ? content : content
|
|
||||||
?.filter((item: any) => item.isPublishOnPolda === true)
|
|
||||||
.slice(0, 3)
|
|
||||||
.map((item: any, index: number) => (
|
|
||||||
<div key={index} className={`bg-white rounded-lg shadow-md overflow-hidden ${index === 0 ? "" : "flex"}`}>
|
|
||||||
<div className={`relative ${index === 0 ? "w-full h-48" : " w-1/2 h-[150px]"}`}>
|
|
||||||
<Link
|
|
||||||
href={
|
|
||||||
Number(item?.fileTypeId) == 1
|
|
||||||
? `${prefixPath}/image/detail/${item?.slug}`
|
|
||||||
: Number(item?.fileTypeId) == 2
|
|
||||||
? `${prefixPath}/video/detail/${item?.slug}`
|
|
||||||
: Number(item?.fileTypeId) == 3
|
|
||||||
? `${prefixPath}/document/detail/${item?.slug}`
|
|
||||||
: `${prefixPath}/audio/detail/${item?.slug}`
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Image src={item.thumbnailLink} alt={item.title} layout="fill" objectFit="cover" />
|
|
||||||
<div className="absolute top-2 right-2 bg-[#c03724] rounded-full p-1 shadow">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
||||||
<g fill="none">
|
|
||||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
|
||||||
<path
|
|
||||||
fill="white"
|
|
||||||
d="M20 6a2 2 0 0 1 2 2v11.333a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2zm-8.268 7.944L7.136 18.54l-.066.06l-.07.054v.68h13v-.68l-.07-.053l-.066-.06l-2.24-2.24l-.353.354l.055.055a1 1 0 0 1-1.32 1.497l-.094-.083zM17 3a2 2 0 0 1 1.995 1.85L19 5H5a1 1 0 0 0-.993.883L4 6v12a2 2 0 0 1-1.995-1.85L2 16V6a3 3 0 0 1 2.824-2.995L5 3zm3 5H7v7.848L10.848 12a1.25 1.25 0 0 1 1.768 0l3.241 3.24l.884-.883a1.25 1.25 0 0 1 1.768 0L20 15.848zm-3.5 1.5a1.5 1.5 0 1 1 0 3a1.5 1.5 0 0 1 0-3"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<div className={`${index === 0 ? "p-4" : "p-3 w-[50%]"}`}>
|
|
||||||
<p className="text-sm text-[#bb3523] font-bold mb-1">{item.categoryName}</p>
|
|
||||||
<h3 className="text-sm font-semibold text-gray-800">{item.title}</h3>
|
|
||||||
<p className="text-xs text-gray-500 mt-1 truncate">{htmlToString(item.description)}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))} */}
|
|
||||||
{/* <button className="w-fit px-2 mt-2 py-2 border flex flex-row gap-2 border-[#bb3523] bg-white text-[#bb3523] rounded-lg font-semibold hover:bg-[#bb3523] hover:text-white transition">
|
|
||||||
LEBIH SEDIKIT
|
|
||||||
<span className="text-[#bb3523] hover:text-white">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
||||||
<path fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="m10 17l5-5m0 0l-5-5" />
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</button> */}
|
|
||||||
{(seeAllValueSatker
|
{(seeAllValueSatker
|
||||||
? contentSatker
|
? contentSatker
|
||||||
: contentSatker?.slice(0, 3)
|
: contentSatker?.slice(0, 3)
|
||||||
|
|
@ -387,17 +335,6 @@ const ScrollableContent = () => {
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{/* <Link
|
|
||||||
href={
|
|
||||||
Number(item?.fileTypeId) == 1
|
|
||||||
? `${prefixPath}/image/detail/${item?.slug}`
|
|
||||||
: Number(item?.fileTypeId) == 2
|
|
||||||
? `${prefixPath}/video/detail/${item?.slug}`
|
|
||||||
: Number(item?.fileTypeId) == 3
|
|
||||||
? `${prefixPath}/document/detail/${item?.slug}`
|
|
||||||
: `${prefixPath}/audio/detail/${item?.slug}`
|
|
||||||
}
|
|
||||||
> */}
|
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
Number(item?.fileTypeId) == 1
|
Number(item?.fileTypeId) == 1
|
||||||
|
|
@ -410,13 +347,13 @@ const ScrollableContent = () => {
|
||||||
}
|
}
|
||||||
className={`${index === 0 ? "p-4" : "p-3 w-[50%]"}`}
|
className={`${index === 0 ? "p-4" : "p-3 w-[50%]"}`}
|
||||||
>
|
>
|
||||||
<p className="text-sm text-[#bb3523] font-bold mb-1">
|
<p className="text-sm text-[#bb3523] font-bold mb-1 px-2">
|
||||||
{item.categoryName}
|
{item.categoryName}
|
||||||
</p>
|
</p>
|
||||||
<h3 className="text-sm font-semibold text-gray-800">
|
<h3 className="text-sm font-semibold text-gray-800 px-2">
|
||||||
{item.title}
|
{item.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-xs text-gray-500 mt-1 truncate">
|
<p className="text-xs text-gray-500 mt-1 truncate px-2">
|
||||||
{htmlToString(item.description)}
|
{htmlToString(item.description)}
|
||||||
</p>
|
</p>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
@ -452,6 +389,7 @@ const ScrollableContent = () => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -281,17 +281,17 @@ const LoginForm = () => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const msg = response?.data?.message;
|
const msg = response?.data?.message;
|
||||||
// onSubmit(data);
|
|
||||||
|
|
||||||
if (msg == "Continue to setup email") {
|
|
||||||
setStep(2);
|
|
||||||
} else if (msg == "Email is valid and OTP has been sent") {
|
|
||||||
setStep(3);
|
|
||||||
} else if (msg == "Username & password valid") {
|
|
||||||
onSubmit(data);
|
onSubmit(data);
|
||||||
} else {
|
|
||||||
error("Username / password incorrect");
|
// if (msg == "Continue to setup email") {
|
||||||
}
|
// setStep(2);
|
||||||
|
// } else if (msg == "Email is valid and OTP has been sent") {
|
||||||
|
// setStep(3);
|
||||||
|
// } else if (msg == "Username & password valid") {
|
||||||
|
// onSubmit(data);
|
||||||
|
// } else {
|
||||||
|
// error("Username / password incorrect");
|
||||||
|
// }
|
||||||
// else {
|
// else {
|
||||||
// setStep(1);
|
// setStep(1);
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -71,22 +71,22 @@ export default function DashboardVisualization() {
|
||||||
setIsInternational(updatedIsInternational);
|
setIsInternational(updatedIsInternational);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
async function fetchUrl() {
|
// async function fetchUrl() {
|
||||||
console.log("Fetch tableau");
|
// console.log("Fetch tableau");
|
||||||
const urlView = `${url + ticket1}/${view1}${param}`;
|
// const urlView = `${url + ticket1}/${view1}${param}`;
|
||||||
console.log("Fetch tableau ", urlView);
|
// console.log("Fetch tableau ", urlView);
|
||||||
const urlRender = await fetch(urlView)
|
// const urlRender = await fetch(urlView)
|
||||||
.then((response) => {
|
// .then((response) => {
|
||||||
console.log("Tableau res : ", response);
|
// console.log("Tableau res : ", response);
|
||||||
})
|
// })
|
||||||
.catch((error) => {
|
// .catch((error) => {
|
||||||
console.log("Tableau error: ", error);
|
// console.log("Tableau error: ", error);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
fetchUrl();
|
// fetchUrl();
|
||||||
}, [ticket1]);
|
// }, [ticket1]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2 bg-white rounded-lg p-3">
|
<div className="flex flex-col gap-2 bg-white rounded-lg p-3">
|
||||||
|
|
|
||||||
|
|
@ -173,10 +173,10 @@ export async function createMedia(data: any) {
|
||||||
|
|
||||||
export async function uploadThumbnail(id: any, data: any) {
|
export async function uploadThumbnail(id: any, data: any) {
|
||||||
const url = `media/upload?id=${id}&operation=thumbnail`;
|
const url = `media/upload?id=${id}&operation=thumbnail`;
|
||||||
// const headers = {
|
const headers = {
|
||||||
// "Content-Type": "multipart/form-data",
|
"Content-Type": "multipart/form-data",
|
||||||
// };
|
};
|
||||||
return httpPostInterceptor(url, data);
|
return httpPostInterceptor(url, data, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function detailSPIT(id: any) {
|
export async function detailSPIT(id: any) {
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,15 @@ export async function getCsrfToken() {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getHeroData(isInt: Boolean = false, unitType= "") {
|
export async function getHeroData(isInt: Boolean = false, unitType = "") {
|
||||||
return await httpGetInterceptor(
|
return await httpGetInterceptor(
|
||||||
`media/public/list?enablePage=1&sort=desc&sortBy=createdAt&size=5&page=0&typeId=1&title=&categoryId=&fileFormats=&tags=&group=&startDate=&endDate=&month=&year=&isInt=${isInt}${unitType==""?"":unitType=='polda'?'&isAllPolda=true':'&isAllSatker=true'}`
|
`media/public/list?enablePage=1&sort=desc&sortBy=createdAt&size=5&page=0&typeId=1&title=&categoryId=&fileFormats=&tags=&group=&startDate=&endDate=&month=&year=&isInt=${isInt}${
|
||||||
|
unitType == ""
|
||||||
|
? ""
|
||||||
|
: unitType == "polda"
|
||||||
|
? "&isAllPolda=true"
|
||||||
|
: "&isAllSatker=true"
|
||||||
|
}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,7 +47,7 @@ export async function listStaticBanner(
|
||||||
group: any = "",
|
group: any = "",
|
||||||
isInt: Boolean = false
|
isInt: Boolean = false
|
||||||
) {
|
) {
|
||||||
const url = `media/static-banner?group=${group}&isInt=${isInt}`;
|
const url = `media/public/banner?group=${group}&isInt=${isInt}`;
|
||||||
return httpGetInterceptor(url);
|
return httpGetInterceptor(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,10 +59,13 @@ export async function listPopUp(group: any = "", isInt: Boolean = false) {
|
||||||
export async function getPublicCategoryData(
|
export async function getPublicCategoryData(
|
||||||
group: any = "",
|
group: any = "",
|
||||||
type: string = "",
|
type: string = "",
|
||||||
isInt: Boolean = false
|
isInt: boolean = false,
|
||||||
|
page: number = 1
|
||||||
) {
|
) {
|
||||||
return await httpGetInterceptor(
|
return await httpGetInterceptor(
|
||||||
`media/categories/list/publish?enablePage=0&group=${group}&type=${type}&isInt=${isInt}`
|
`media/categories/list/publish?enablePage=1&size=12&sort=desc&sortBy=createdAt&page=${
|
||||||
|
page - 1
|
||||||
|
}&group=${group}&type=${type}&isInt=${isInt}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,3 +23,8 @@ export async function deleteKnowledgeBase(id: any) {
|
||||||
const url = `knowledge-base?id=${id}`;
|
const url = `knowledge-base?id=${id}`;
|
||||||
return httpDeleteInterceptor(url);
|
return httpDeleteInterceptor(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function saveKnowledgeBase(data: any) {
|
||||||
|
const url = "knowledge-base";
|
||||||
|
return httpPostInterceptor(url, data);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,11 @@ export const generateLocalizedPath = (href: string, locale: string): string => {
|
||||||
return `/${locale}${href}`;
|
return `/${locale}${href}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function textEllipsis(str: string, maxLength: number, { side = "end", ellipsis = "..." } = {}) {
|
export function textEllipsis(
|
||||||
|
str: string,
|
||||||
|
maxLength: number,
|
||||||
|
{ side = "end", ellipsis = "..." } = {}
|
||||||
|
) {
|
||||||
if (str !== undefined && str?.length > maxLength) {
|
if (str !== undefined && str?.length > maxLength) {
|
||||||
switch (side) {
|
switch (side) {
|
||||||
case "start":
|
case "start":
|
||||||
|
|
@ -78,7 +82,10 @@ export function getOnlyMonthAndYear(d: Date) {
|
||||||
|
|
||||||
export function getPublicLocaleTimestamp(d: any) {
|
export function getPublicLocaleTimestamp(d: any) {
|
||||||
const pad = (n: any, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
const pad = (n: any, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
||||||
return `${pad(d.getDate())}/${pad(d.getMonth() + 1)}/${pad(d.getFullYear(), 4)} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
return `${pad(d.getDate())}/${pad(d.getMonth() + 1)}/${pad(
|
||||||
|
d.getFullYear(),
|
||||||
|
4
|
||||||
|
)} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function capitalize(s: any) {
|
export function capitalize(s: any) {
|
||||||
|
|
@ -91,9 +98,13 @@ export function capitalize(s: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLocaleTimestamp(d: Date): string {
|
export function getLocaleTimestamp(d: Date): string {
|
||||||
const pad = (n: number, s: number = 2): string => `${new Array(s).fill(0)}${n}`.slice(-s);
|
const pad = (n: number, s: number = 2): string =>
|
||||||
|
`${new Array(s).fill(0)}${n}`.slice(-s);
|
||||||
|
|
||||||
return `${pad(d.getDate())}-${pad(d.getMonth() + 1)}-${pad(d.getFullYear(), 4)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
return `${pad(d.getDate())}-${pad(d.getMonth() + 1)}-${pad(
|
||||||
|
d.getFullYear(),
|
||||||
|
4
|
||||||
|
)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLocaleTime(d: Date) {
|
export function getLocaleTime(d: Date) {
|
||||||
|
|
@ -102,7 +113,9 @@ export function getLocaleTime(d: Date) {
|
||||||
}
|
}
|
||||||
export function getTimestamp(d: Date) {
|
export function getTimestamp(d: Date) {
|
||||||
const pad = (n: any, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
const pad = (n: any, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
||||||
return `${pad(d.getFullYear(), 4)}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
return `${pad(d.getFullYear(), 4)}-${pad(d.getMonth() + 1)}-${pad(
|
||||||
|
d.getDate()
|
||||||
|
)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function secondToTimes(sec: number) {
|
export function secondToTimes(sec: number) {
|
||||||
|
|
@ -116,7 +129,10 @@ export function secondToTimes(sec: number) {
|
||||||
|
|
||||||
export function checkMaliciousText(str: any) {
|
export function checkMaliciousText(str: any) {
|
||||||
try {
|
try {
|
||||||
const urlPattern = new RegExp("(https?:\\/\\/(?:www\\.|(?!www))[^\\s\\.]+\\.[^\\s]{2,}|www\\.[^\\s]+\\.[^\\s]{2,}|https?:\\/\\/[^\\s]+|\\b(?:https?|ftp):\\/\\/[^\\s/$.?#].[^\\s]*)", "gi");
|
const urlPattern = new RegExp(
|
||||||
|
"(https?:\\/\\/(?:www\\.|(?!www))[^\\s\\.]+\\.[^\\s]{2,}|www\\.[^\\s]+\\.[^\\s]{2,}|https?:\\/\\/[^\\s]+|\\b(?:https?|ftp):\\/\\/[^\\s/$.?#].[^\\s]*)",
|
||||||
|
"gi"
|
||||||
|
);
|
||||||
const isContainUrl = urlPattern.test(str);
|
const isContainUrl = urlPattern.test(str);
|
||||||
if (isContainUrl) {
|
if (isContainUrl) {
|
||||||
return "Message mengandung URL yang tidak diizinkan";
|
return "Message mengandung URL yang tidak diizinkan";
|
||||||
|
|
@ -155,20 +171,26 @@ export const shimmer = (w: number, h: number) => `
|
||||||
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
|
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
|
||||||
export const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str));
|
export const toBase64 = (str: string) =>
|
||||||
|
typeof window === "undefined"
|
||||||
|
? Buffer.from(str).toString("base64")
|
||||||
|
: window.btoa(str);
|
||||||
|
|
||||||
const LoadScript = () => {
|
const LoadScript = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const script = document.createElement("script");
|
const script = document.createElement("script");
|
||||||
script.src = "https://cdn.userway.org/widget.js";
|
script.src = "https://cdn.userway.org/widget.js";
|
||||||
script.setAttribute("data-account", "X36s1DpjqB");
|
script.setAttribute("data-account", "X36s1DpjqB");
|
||||||
|
script.setAttribute("data-position", "5");
|
||||||
script.async = true;
|
script.async = true;
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// Cleanup if needed
|
|
||||||
document.head.removeChild(script);
|
document.head.removeChild(script);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
return null; // Tidak perlu merender apa-apa
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoadScript;
|
export default LoadScript;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue