This commit is contained in:
Sabda Yagra 2025-12-02 09:17:40 +07:00
commit 5fa74cc716
28 changed files with 197 additions and 175 deletions

View File

@ -19,7 +19,7 @@ build-prod:
- echo "Username:$DEPLOY_USERNAME" - echo "Username:$DEPLOY_USERNAME"
- echo "Token:$DEPLOY_TOKEN" - echo "Token:$DEPLOY_TOKEN"
- echo "$DEPLOY_TOKEN" | docker login 103.82.242.92:8900 --username "$DEPLOY_USERNAME" --password-stdin - echo "$DEPLOY_TOKEN" | docker login 103.82.242.92:8900 --username "$DEPLOY_USERNAME" --password-stdin
- docker build -t 103.82.242.92:8900/mediahub/new-mediahub-fe:prod . - docker build --no-cache -t 103.82.242.92:8900/mediahub/new-mediahub-fe:prod .
- docker push 103.82.242.92:8900/mediahub/new-mediahub-fe:prod - docker push 103.82.242.92:8900/mediahub/new-mediahub-fe:prod
auto-deploy: auto-deploy:

View File

@ -25,7 +25,8 @@ RUN pnpm install
COPY . . COPY . .
# Build aplikasi # Build aplikasi
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm run build # RUN NODE_OPTIONS="--max-old-space-size=4096"
RUN pnpm run build
# Expose port untuk server # Expose port untuk server
EXPOSE 3000 EXPOSE 3000

View File

@ -171,11 +171,11 @@ export default function CreateAccountForBroadcast() {
{/* WA */} {/* WA */}
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes("wa")} checked={field.value?.includes("wa") ?? false}
onCheckedChange={(checked) => onCheckedChange={(checked) =>
checked checked
? field.onChange([...field.value, "wa"]) ? field.onChange([...(field.value ?? []), "wa"])
: field.onChange(field.value.filter((v) => v !== "wa")) : field.onChange((field.value ?? []).filter((v) => v !== "wa"))
} }
/> />
<label>Whatsapp</label> <label>Whatsapp</label>
@ -184,12 +184,12 @@ export default function CreateAccountForBroadcast() {
{/* EMAIL */} {/* EMAIL */}
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes("email")} checked={field.value?.includes("email") ?? false}
onCheckedChange={(checked) => onCheckedChange={(checked) =>
checked checked
? field.onChange([...field.value, "email"]) ? field.onChange([...(field.value ?? []), "email"])
: field.onChange( : field.onChange(
field.value.filter((v) => v !== "email") (field.value ?? []).filter((v) => v !== "email")
) )
} }
/> />
@ -202,7 +202,7 @@ export default function CreateAccountForBroadcast() {
/> />
{/* FORM WHATSAPP */} {/* FORM WHATSAPP */}
{selectedTypes.includes("wa") && ( {selectedTypes?.includes("wa") && (
<FormField <FormField
control={form.control} control={form.control}
name="whatsapp" name="whatsapp"
@ -221,7 +221,7 @@ export default function CreateAccountForBroadcast() {
)} )}
{/* FORM EMAIL */} {/* FORM EMAIL */}
{selectedTypes.includes("email") && ( {selectedTypes?.includes("email") && (
<FormField <FormField
control={form.control} control={form.control}
name="email" name="email"

View File

@ -5,7 +5,7 @@ export default function PerformancePolda() {
return ( return (
<div> <div>
<SiteBreadcrumb /> <SiteBreadcrumb />
<p className="font-semibold">PERFORMANCE KUMULATIF PER POLRES</p> {/* <p className="font-semibold">PERFORMANCE KUMULATIF PER POLRES</p> */}
<PerformancePolresViz /> <PerformancePolresViz />
</div> </div>
); );

View File

@ -6,7 +6,6 @@ export default function PerformanceSatker() {
return ( return (
<div> <div>
<SiteBreadcrumb /> <SiteBreadcrumb />
<p className="font-semibold">PERFORMANCE KUMULATIF PER SATKER</p>
<PerformanceSatkerViz /> <PerformanceSatkerViz />
</div> </div>
); );

View File

@ -300,11 +300,11 @@ export default function CreateCategoryModal() {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
item.id, item.id,
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== item.id (value) => value !== item.id
) )
); );
@ -371,11 +371,11 @@ export default function CreateCategoryModal() {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
item.id, item.id,
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== item.id (value) => value !== item.id
) )
); );
@ -443,11 +443,11 @@ export default function CreateCategoryModal() {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
item.id, item.id,
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== item.id (value) => value !== item.id
) )
); );

View File

@ -326,11 +326,11 @@ export default function EditCategoryModal(props: {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
item.id, item.id,
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== item.id (value) => value !== item.id
) )
); );
@ -398,11 +398,11 @@ export default function EditCategoryModal(props: {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
item.id, item.id,
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== item.id (value) => value !== item.id
) )
); );
@ -473,11 +473,11 @@ export default function EditCategoryModal(props: {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
item.id, item.id,
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== item.id (value) => value !== item.id
) )
); );

View File

@ -150,11 +150,11 @@ export function UnitMapping(props: {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
String(item.id), String(item.id),
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== String(item.id) (value) => value !== String(item.id)
) )
); );
@ -223,11 +223,11 @@ export function UnitMapping(props: {
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
return checked return checked
? field.onChange([ ? field.onChange([
...field.value, ...(field.value ?? []),
String(item.id), String(item.id),
]) ])
: field.onChange( : field.onChange(
field.value?.filter( (field.value ?? []).filter(
(value) => value !== String(item.id) (value) => value !== String(item.id)
) )
); );

View File

@ -98,11 +98,11 @@ export default function DetailSettingTracking(props: {
{wilayahList.map((item) => ( {wilayahList.map((item) => (
<div key={item.id} className="flex items-center gap-2"> <div key={item.id} className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes(item.id)} checked={field.value?.includes(item.id) ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const updated = checked const updated = checked
? [...field.value, item.id] ? [...(field.value ?? []), item.id]
: field.value.filter((val) => val !== item.id); : (field.value ?? []).filter((val) => val !== item.id);
field.onChange(updated); field.onChange(updated);
}} }}
/> />
@ -124,11 +124,11 @@ export default function DetailSettingTracking(props: {
{jumlahList.map((num) => ( {jumlahList.map((num) => (
<div key={num} className="flex items-center gap-2"> <div key={num} className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes(num)} checked={field.value?.includes(num) ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const updated = checked const updated = checked
? [...field.value, num] ? [...(field.value ?? []), num]
: field.value.filter((val) => val !== num); : (field.value ?? []).filter((val) => val !== num);
field.onChange(updated); field.onChange(updated);
}} }}
/> />

View File

@ -98,11 +98,11 @@ export default function UpdateSettingTracking(props: {
{wilayahList.map((item) => ( {wilayahList.map((item) => (
<div key={item.id} className="flex items-center gap-2"> <div key={item.id} className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes(item.id)} checked={field.value?.includes(item.id) ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const updated = checked const updated = checked
? [...field.value, item.id] ? [...(field.value ?? []), item.id]
: field.value.filter((val) => val !== item.id); : (field.value ?? []).filter((val) => val !== item.id);
field.onChange(updated); field.onChange(updated);
}} }}
/> />
@ -124,11 +124,11 @@ export default function UpdateSettingTracking(props: {
{jumlahList.map((num) => ( {jumlahList.map((num) => (
<div key={num} className="flex items-center gap-2"> <div key={num} className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes(num)} checked={field.value?.includes(num) ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const updated = checked const updated = checked
? [...field.value, num] ? [...(field.value ?? []), num]
: field.value.filter((val) => val !== num); : (field.value ?? []).filter((val) => val !== num);
field.onChange(updated); field.onChange(updated);
}} }}
/> />

View File

@ -73,7 +73,22 @@ const useTableColumns = ({
{ {
accessorKey: "status", accessorKey: "status",
header: t("status", { defaultValue: "Status" }), header: t("status", { defaultValue: "Status" }),
cell: ({ row }) => <span className="">{row.getValue("status")}</span>, cell: ({ row }) => {
const version = Number(row.original.version); // pastikan number
const isProcess = version === 0;
const status = isProcess ? "Proses" : "Selesai";
return (
<span
className={`px-2 py-1 rounded-full text-white text-xs font-semibold ${
isProcess ? "bg-yellow-500" : "bg-green-600"
}`}
>
{status}
</span>
);
},
}, },
{ {
@ -131,7 +146,9 @@ const useTableColumns = ({
const response = await downloadReport(id); const response = await downloadReport(id);
console.log(response?.data); console.log(response?.data);
const url = window.URL.createObjectURL(new Blob([response?.data], { type : "application/pdf"})); const url = window.URL.createObjectURL(
new Blob([response?.data], { type: "application/pdf" })
);
const link = document.createElement("a"); const link = document.createElement("a");
link.href = url; link.href = url;
link.setAttribute("download", `report-${id}.pdf`); link.setAttribute("download", `report-${id}.pdf`);

View File

@ -32,7 +32,7 @@ export default function ExecutiveDataDashboard() {
const baseUrl = "https://db-mediahub.polri.go.id/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://db-mediahub.polri.go.id/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const safeLevelName = levelNumber ?? ""; const safeLevelName = levelName ?? "";
// const view1 = // const view1 =
// levelName == "MABES POLRI" // levelName == "MABES POLRI"
@ -53,7 +53,7 @@ export default function ExecutiveDataDashboard() {
: levelNumber === "2" : levelNumber === "2"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-by-polda-publish-konten?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-by-polda-publish-konten?provinsi-polda=${provState}&`
: levelNumber === "3" : levelNumber === "3"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-satker?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-satker?satker-selected=${state}&`
: ""; : "";
const view2 = const view2 =
@ -83,7 +83,7 @@ export default function ExecutiveDataDashboard() {
: levelNumber === "2" : levelNumber === "2"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-by-polda-cat?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-by-polda-cat?provinsi-polda=${provState}&`
: levelNumber === "3" : levelNumber === "3"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-satker-kategori?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-satker-kategori?satker-selected=${state}&`
: ""; : "";
const view4 = const view4 =
@ -110,7 +110,7 @@ export default function ExecutiveDataDashboard() {
: levelNumber === "2" : levelNumber === "2"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-executive?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-executive?provinsi-polda=${provState}&`
: levelNumber === "3" : levelNumber === "3"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-top-satker?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-top-satker?satker-selected=${state}&`
: ""; : "";
// const view6 = // const view6 =
@ -128,7 +128,7 @@ export default function ExecutiveDataDashboard() {
: levelNumber === "2" : levelNumber === "2"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-heatmap-polda?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-heatmap-polda?provinsi-polda=${provState}&`
: levelNumber === "3" : levelNumber === "3"
? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-hm-satker?provinsi-polda=${provState}&` ? `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-hm-satker?satker-selected=${state}&`
: ""; : "";
// const view7 = // const view7 =

View File

@ -40,7 +40,7 @@ export default function ExecutiveDashboard() {
const baseUrl = "https://db-mediahub.polri.go.id/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://db-mediahub.polri.go.id/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const safeLevelName = levelNumber ?? ""; const safeLevelName = levelName ?? "";
const view1 = const view1 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -62,7 +62,7 @@ export default function ExecutiveDashboard() {
? // `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/2025_10_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-executive?provinsi-polda=${provState}&` `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-executive?provinsi-polda=${provState}&`
: // `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/2025_10_MediaHUB-Viz-POLDA_Rev200/db-published-produksi-executive?provinsi-polda=${provState}&`; `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-top-satker?satker-selected=${state}&`;
const view3 = const view3 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -75,7 +75,7 @@ export default function ExecutiveDashboard() {
? // `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/2025_10_MediaHUB-Viz-POLDA_Rev200/db-waktu-akses-pengguna-executive?provinsi-polda=${provState}` `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-waktu-akses-pengguna-executive?provinsi-polda=${provState}`
: // `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/2025_10_MediaHUB-Viz-POLDA_Rev200/db-waktu-akses-pengguna-executive?provinsi-polda=${provState}`; `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-hm-satker?satker-selected=${state}`;
const view4 = const view4 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -86,9 +86,9 @@ export default function ExecutiveDashboard() {
"views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-konten-header?" "views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-konten-header?"
: safeLevelName.includes("POLDA") : safeLevelName.includes("POLDA")
? // `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda?polda-selected=${state}&` ? // `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda?polda-selected=${state}&`
`/views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-konten-header?provinsi-polda=${provState}&` `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-konten-header?provinsi-polda=${provState}&`
: // `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda?polda-selected=${state}&`; : // `views/2023_04_MediaHUB-Viz-POLDA_Rev200/db-content-interaction-polda?polda-selected=${state}&`;
`/views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-konten-header?provinsi-polda=${provState}&`; `views/2025_10_MediaHUB-Viz-POLDA_Rev200/db-satker?satker-selected=${state}&`;
const view5 = const view5 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -160,10 +160,10 @@ export default function ExecutiveDashboard() {
<Card className="rounded-sm p-5 w-full"> <Card className="rounded-sm p-5 w-full">
<div className="flex flex-row flex-wrap gap-5 justify-between"> <div className="flex flex-row flex-wrap gap-5 justify-between">
{/* ===================== POLDA ===================== */} {/* ===================== POLDA ===================== */}
{(levelNumber === "1" || levelNumber === "2") && ( {(levelNumber === "1" || levelNumber === "2" || levelNumber === "3") && (
<div className="flex-1 min-w-[350px]"> <div className="flex-1 min-w-[350px]">
<p className="text-base font-semibold mb-3"> <p className="text-base font-semibold mb-3">
Publish Konten Polda Publish Konten
</p> </p>
{ticket1 == "" ? ( {ticket1 == "" ? (

View File

@ -288,11 +288,11 @@ export default function ContentBlast() {
<div className="flex gap-6"> <div className="flex gap-6">
<label className="flex items-center gap-2"> <label className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes("wa")} checked={field.value?.includes("wa") ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
checked checked
? field.onChange([...field.value, "wa"]) ? field.onChange([...(field.value ?? []), "wa"])
: field.onChange(field.value.filter((v) => v !== "wa")); : field.onChange((field.value ?? []).filter((v) => v !== "wa"));
}} }}
/> />
WhatsApp WhatsApp
@ -300,12 +300,12 @@ export default function ContentBlast() {
<label className="flex items-center gap-2"> <label className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes("email")} checked={field.value?.includes("email") ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
checked checked
? field.onChange([...field.value, "email"]) ? field.onChange([...(field.value ?? []), "email"])
: field.onChange( : field.onChange(
field.value.filter((v) => v !== "email") (field.value ?? []).filter((v) => v !== "email")
); );
}} }}
/> />

View File

@ -1748,13 +1748,13 @@ export default function FormAudio() {
{options.map((option) => { {options.map((option) => {
const isAllChecked = const isAllChecked =
field.value.length === (field.value?.length ?? 0) ===
options.filter((opt: any) => opt.id !== "all").length; options.filter((opt: any) => opt.id !== "all").length;
const isChecked = const isChecked =
option.id === "all" option.id === "all"
? isAllChecked ? isAllChecked
: field.value.includes(option.id); : field.value?.includes(option.id) ?? false;
const handleChange = () => { const handleChange = () => {
let updated: string[] = []; let updated: string[] = [];
@ -1767,8 +1767,8 @@ export default function FormAudio() {
.map((opt: any) => opt.id); .map((opt: any) => opt.id);
} else { } else {
updated = isChecked updated = isChecked
? field.value.filter((val) => val !== option.id) ? (field.value ?? []).filter((val) => val !== option.id)
: [...field.value, option.id]; : [...(field.value ?? []), option.id];
if (isAllChecked && option.id !== "all") { if (isAllChecked && option.id !== "all") {
updated = updated.filter((val) => val !== "all"); updated = updated.filter((val) => val !== "all");

View File

@ -1673,13 +1673,13 @@ export default function FormImage() {
{options.map((option) => { {options.map((option) => {
const isAllChecked = const isAllChecked =
field.value.length === (field.value?.length ?? 0) ===
options.filter((opt: any) => opt.id !== "all").length; options.filter((opt: any) => opt.id !== "all").length;
const isChecked = const isChecked =
option.id === "all" option.id === "all"
? isAllChecked ? isAllChecked
: field.value.includes(option.id); : field.value?.includes(option.id) ?? false;
const handleChange = () => { const handleChange = () => {
let updated: string[] = []; let updated: string[] = [];
@ -1692,8 +1692,8 @@ export default function FormImage() {
.map((opt: any) => opt.id); .map((opt: any) => opt.id);
} else { } else {
updated = isChecked updated = isChecked
? field.value.filter((val) => val !== option.id) ? (field.value ?? []).filter((val) => val !== option.id)
: [...field.value, option.id]; : [...(field.value ?? []), option.id];
if (isAllChecked && option.id !== "all") { if (isAllChecked && option.id !== "all") {
updated = updated.filter((val) => val !== "all"); updated = updated.filter((val) => val !== "all");

View File

@ -1715,13 +1715,13 @@ export default function FormTeks() {
{options.map((option) => { {options.map((option) => {
const isAllChecked = const isAllChecked =
field.value.length === (field.value?.length ?? 0) ===
options.filter((opt: any) => opt.id !== "all").length; options.filter((opt: any) => opt.id !== "all").length;
const isChecked = const isChecked =
option.id === "all" option.id === "all"
? isAllChecked ? isAllChecked
: field.value.includes(option.id); : field.value?.includes(option.id) ?? false;
const handleChange = () => { const handleChange = () => {
let updated: string[] = []; let updated: string[] = [];
@ -1734,8 +1734,8 @@ export default function FormTeks() {
.map((opt: any) => opt.id); .map((opt: any) => opt.id);
} else { } else {
updated = isChecked updated = isChecked
? field.value.filter((val) => val !== option.id) ? (field.value ?? []).filter((val) => val !== option.id)
: [...field.value, option.id]; : [...(field.value ?? []), option.id];
if (isAllChecked && option.id !== "all") { if (isAllChecked && option.id !== "all") {
updated = updated.filter((val) => val !== "all"); updated = updated.filter((val) => val !== "all");

View File

@ -1713,7 +1713,7 @@ export default function FormVideo() {
if (e.key === "Enter" && e.currentTarget.value.trim()) { if (e.key === "Enter" && e.currentTarget.value.trim()) {
e.preventDefault(); e.preventDefault();
field.onChange([ field.onChange([
...field.value, ...(field.value ?? []),
e.currentTarget.value.trim(), e.currentTarget.value.trim(),
]); ]);
e.currentTarget.value = ""; e.currentTarget.value = "";
@ -1722,7 +1722,7 @@ export default function FormVideo() {
/> />
<div className="mt-3"> <div className="mt-3">
{field.value.map((tag: string, index: number) => ( {(field.value ?? []).map((tag: string, index: number) => (
<span <span
key={index} key={index}
className="px-1 py-1 rounded-lg bg-black text-white mr-2 text-sm font-sans" className="px-1 py-1 rounded-lg bg-black text-white mr-2 text-sm font-sans"
@ -1731,7 +1731,7 @@ export default function FormVideo() {
<button <button
type="button" type="button"
onClick={() => { onClick={() => {
const updatedTags = field.value.filter( const updatedTags = (field.value ?? []).filter(
(_, i) => i !== index (_, i) => i !== index
); );
field.onChange(updatedTags); field.onChange(updatedTags);
@ -1764,13 +1764,13 @@ export default function FormVideo() {
{options.map((option) => { {options.map((option) => {
const isAllChecked = const isAllChecked =
field.value.length === (field.value?.length ?? 0) ===
options.filter((opt: any) => opt.id !== "all").length; options.filter((opt: any) => opt.id !== "all").length;
const isChecked = const isChecked =
option.id === "all" option.id === "all"
? isAllChecked ? isAllChecked
: field.value.includes(option.id); : field.value?.includes(option.id) ?? false;
const handleChange = () => { const handleChange = () => {
let updated: string[] = []; let updated: string[] = [];
@ -1783,8 +1783,8 @@ export default function FormVideo() {
.map((opt: any) => opt.id); .map((opt: any) => opt.id);
} else { } else {
updated = isChecked updated = isChecked
? field.value.filter((val) => val !== option.id) ? (field.value ?? []).filter((val) => val !== option.id)
: [...field.value, option.id]; : [...(field.value ?? []), option.id];
if (isAllChecked && option.id !== "all") { if (isAllChecked && option.id !== "all") {
updated = updated.filter((val) => val !== "all"); updated = updated.filter((val) => val !== "all");

View File

@ -67,11 +67,11 @@ export default function DetailSettingTracking() {
{wilayahList.map((item) => ( {wilayahList.map((item) => (
<div key={item.id} className="flex items-center gap-2"> <div key={item.id} className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes(item.id)} checked={field.value?.includes(item.id) ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const updated = checked const updated = checked
? [...field.value, item.id] ? [...(field.value ?? []), item.id]
: field.value.filter((val) => val !== item.id); : (field.value ?? []).filter((val) => val !== item.id);
field.onChange(updated); field.onChange(updated);
}} }}
/> />

View File

@ -67,11 +67,11 @@ export default function CreateSettingTracking() {
{wilayahList.map((item) => ( {wilayahList.map((item) => (
<div key={item.id} className="flex items-center gap-2"> <div key={item.id} className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes(item.id)} checked={field.value?.includes(item.id) ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const updated = checked const updated = checked
? [...field.value, item.id] ? [...(field.value ?? []), item.id]
: field.value.filter((val) => val !== item.id); : (field.value ?? []).filter((val) => val !== item.id);
field.onChange(updated); field.onChange(updated);
}} }}
/> />

View File

@ -67,11 +67,11 @@ export default function UpdateSettingTracking() {
{wilayahList.map((item) => ( {wilayahList.map((item) => (
<div key={item.id} className="flex items-center gap-2"> <div key={item.id} className="flex items-center gap-2">
<Checkbox <Checkbox
checked={field.value.includes(item.id)} checked={field.value?.includes(item.id) ?? false}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const updated = checked const updated = checked
? [...field.value, item.id] ? [...(field.value ?? []), item.id]
: field.value.filter((val) => val !== item.id); : (field.value ?? []).filter((val) => val !== item.id);
field.onChange(updated); field.onChange(updated);
}} }}
/> />

View File

@ -202,7 +202,7 @@ export function FormDatePicker<
<Calendar <Calendar
initialFocus initialFocus
mode={mode} mode={mode}
defaultMonth={mode === 'range' && 'from' in selectedDate ? selectedDate.from : selectedDate} defaultMonth={mode === 'range' && selectedDate && 'from' in selectedDate ? selectedDate.from : selectedDate}
selected={selectedDate} selected={selectedDate}
onSelect={field.onChange} onSelect={field.onChange}
numberOfMonths={numberOfMonths} numberOfMonths={numberOfMonths}

View File

@ -81,7 +81,7 @@ export default function PerformancePoldaViz() {
<p className="text-lg"> <p className="text-lg">
<b> <b>
{levelName == "MABES POLRI" {levelName == "MABES POLRI"
? "PERFORMANCE PER POLDA" ? "PERFORMANCE PER POLDA/SATKER"
: "PERFORMANCE POLRES"} : "PERFORMANCE POLRES"}
</b> </b>
</p> </p>
@ -105,8 +105,8 @@ export default function PerformancePoldaViz() {
<p className="text-lg"> <p className="text-lg">
<b> <b>
{isInternational[0] {isInternational[0]
? "PUBLISH CONTENT PER POLDA" ? "PUBLISH CONTENT PER POLDA/SATKER"
: "PUBLISH KONTEN PER POLDA"} : "PUBLISH KONTEN PER POLDA/SATKER"}
</b> </b>
</p> </p>
<div className="my-5"> <div className="my-5">

View File

@ -22,19 +22,17 @@ export default function PerformancePolresViz() {
const baseUrl = "https://db-mediahub.polri.go.id/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://db-mediahub.polri.go.id/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const view1 = const view1 = `views/2025_10_MediaHUB-Viz-POLDA_Rev203/db-ranking-polda-satker?polda-selected=${poldaState}&`;
levelName == "MABES POLRI" const view2 = `views/2023_09_db-ranking-polres-by-polda_rev100/db-ranking-by-polda?polda-selected=${poldaState}&`;
? isInternational[0]
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-konten-top10?"
: "views/2023_09_db-ranking-polda_rev100/db-ranking-13-polda?"
: `/views/2023_09_db-ranking-polres-by-polda_rev100/db-ranking-by-polda?polda-selected=${poldaState}&`;
const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true"; const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true";
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {
const response1 = await generateTicket(); const response1 = await generateTicket();
setTicket1(response1?.data?.data); setTicket1(response1?.data?.data);
const response2 = await generateTicket();
setTicket2(response2?.data?.data);
} }
initState(); initState();
@ -48,19 +46,10 @@ export default function PerformancePolresViz() {
// Render // Render
if (!hasMounted) return null; if (!hasMounted) return null;
const handleInternational = (index: number, val: boolean) => {
const updatedIsInternational = [...isInternational];
updatedIsInternational[index] = val;
setIsInternational(updatedIsInternational);
};
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">
<p className="text-lg"> <p className="text-lg">
<b> <b>PERFORMANCE POLRES</b>
{isInternational[0] ? "POLRES PERFORMANCE" : "POLFORMANCE POLRES"}
</b>
</p> </p>
<div className="my-5"> <div className="my-5">
{ticket1 == "" ? ( {ticket1 == "" ? (
@ -79,6 +68,31 @@ export default function PerformancePolresViz() {
/> />
)} )}
</div> </div>
<p className="text-lg">
<b>
{isInternational[0]
? "PUBLISH CONTENT PER POLICE REGENCY"
: "PUBLISH KONTEN PER POLRES"}
</b>
</p>
<div className="my-5">
{ticket2 == "" ? (
<iframe
src={`${baseUrl + view2 + param}`}
width="100%"
height="750"
frameBorder="0"
/>
) : (
<iframe
src={`${`${url + ticket2}/${view2}${param}`}`}
width="100%"
height="750"
frameBorder="0"
/>
)}
</div>
</div> </div>
); );
} }

View File

@ -10,24 +10,16 @@ export default function PerformanceSatkerViz() {
const [hasMounted, setHasMounted] = useState(false); const [hasMounted, setHasMounted] = useState(false);
const t = useTranslations("AnalyticsDashboard"); const t = useTranslations("AnalyticsDashboard");
const levelName = getCookiesDecrypt("ulnae"); const levelName = getCookiesDecrypt("ulnae");
const poldaState = Cookies.get("state"); const state = Cookies.get("state");
const provState = Cookies.get("state-prov"); const provState = Cookies.get("state-prov");
const [ticket1, setTicket1] = useState(""); const [ticket1, setTicket1] = useState("");
const [ticket2, setTicket2] = useState("");
const [ticket3, setTicket3] = useState("");
const [ticket4, setTicket4] = useState("");
const [isInternational, setIsInternational] = useState([false, false, false]); const [isInternational, setIsInternational] = useState([false, false, false]);
const baseUrl = "https://db-mediahub.polri.go.id/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://db-mediahub.polri.go.id/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const view1 = const view1 = `views/2025_10_MediaHUB-Viz-POLDA_Rev203/db-ranking-polda-satker?polda-selected=${state}&unit-work-level-1=SATKER`;
levelName == "MABES POLRI"
? isInternational[0]
? "views/2023_04_MediaHUB-Viz_INTL_Rev202/db-konten-top10?"
: "views/2023_04_MediaHUB-Viz-POLDA_Rev201/db-konten-top10?"
: `/views/2023_09_db-ranking-polres-by-polda_rev100/db-ranking-by-polda?polda-selected=${provState}&`;
const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true"; const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true";
@ -59,7 +51,7 @@ export default function PerformanceSatkerViz() {
<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">
<p className="text-lg"> <p className="text-lg">
<b> <b>
{isInternational[0] ? "SATKER PERFORMANCE" : "POLFORMANCE SATKER"} {isInternational[0] ? "SATKER PERFORMANCE" : "PERFORMANCE SATKER"}
</b> </b>
</p> </p>
<div className="my-5"> <div className="my-5">

View File

@ -2649,8 +2649,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
(Number(roleId) == 3 || Number(roleId) == 14 || Number(roleId) == 15) && (Number(roleId) == 3 || Number(roleId) == 14 || Number(roleId) == 15) &&
Number(levelNumber) == 3 Number(levelNumber) == 3
) { ) {
if (Number(userParentLevelId) != 761) if (Number(userParentLevelId) != 761) {
{
menusSelected = [ menusSelected = [
{ {
groupLabel: t("apps"), groupLabel: t("apps"),
@ -4009,20 +4008,20 @@ export function getMenuList(pathname: string, t: any): Group[] {
}, },
], ],
}, },
{ // {
groupLabel: "", // groupLabel: "",
id: "agenda-setting", // id: "agenda-setting",
menus: [ // menus: [
{ // {
id: "agenda-setting", // id: "agenda-setting",
href: "/contributor/agenda-setting", // href: "/contributor/agenda-setting",
label: t("agenda-setting"), // label: t("agenda-setting"),
active: pathname.includes("/agenda-setting"), // active: pathname.includes("/agenda-setting"),
icon: "iconoir:journal-page", // icon: "iconoir:journal-page",
submenus: [], // submenus: [],
}, // },
], // ],
}, // },
{ {
groupLabel: "", groupLabel: "",
id: "performance-polres", id: "performance-polres",
@ -4050,7 +4049,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
submenus: [ submenus: [
{ {
href: "/admin/media-tracking/tracking-berita", href: "/admin/media-tracking/tracking-berita",
label: "Tracking Beritra", label: "Tracking Berita",
active: pathname === "/admin/media-tracking/tracking-berita", active: pathname === "/admin/media-tracking/tracking-berita",
icon: "heroicons:arrow-trending-up", icon: "heroicons:arrow-trending-up",
children: [], children: [],
@ -4119,41 +4118,41 @@ export function getMenuList(pathname: string, t: any): Group[] {
icon: "heroicons:arrow-trending-up", icon: "heroicons:arrow-trending-up",
children: [], children: [],
}, },
{ // {
href: "/admin/settings/banner", // href: "/admin/settings/banner",
label: "Banner", // label: "Banner",
active: pathname === "/admin/settings/banner", // active: pathname === "/admin/settings/banner",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
{ // {
href: "/admin/settings/feedback", // href: "/admin/settings/feedback",
label: "Feedback", // label: "Feedback",
active: pathname === "/admin/settings/feedback", // active: pathname === "/admin/settings/feedback",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
{ // {
href: "/admin/settings/faq", // href: "/admin/settings/faq",
label: "FAQ", // label: "FAQ",
active: pathname === "/admin/settings/faq", // active: pathname === "/admin/settings/faq",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
{ // {
href: "https://nat-mediahub.polri.go.id/", // href: "https://nat-mediahub.polri.go.id/",
label: "Mediahub 2022", // label: "Mediahub 2022",
active: pathname === "/admin/settings/mediahub-2022", // active: pathname === "/admin/settings/mediahub-2022",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
{ // {
href: "/admin/settings/privacy", // href: "/admin/settings/privacy",
label: t("privacy"), // label: t("privacy"),
active: pathname === "/admin/settings/privacy", // active: pathname === "/admin/settings/privacy",
icon: "heroicons:arrow-trending-up", // icon: "heroicons:arrow-trending-up",
children: [], // children: [],
}, // },
], ],
}, },
], ],
@ -4259,7 +4258,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
submenus: [ submenus: [
{ {
href: "/admin/media-tracking/tracking-berita", href: "/admin/media-tracking/tracking-berita",
label: "Tracking Beritra", label: "Tracking Berita",
active: pathname === "/admin/media-tracking/tracking-berita", active: pathname === "/admin/media-tracking/tracking-berita",
icon: "heroicons:arrow-trending-up", icon: "heroicons:arrow-trending-up",
children: [], children: [],

View File

@ -327,7 +327,7 @@
"sellers": "Sellers", "sellers": "Sellers",
"typography": "Typography", "typography": "Typography",
"colors": "Colors", "colors": "Colors",
"performance-polda": "Performance Polda", "performance-polda": "Performance Polda/Satker",
"performance-polres": "Performance Polres", "performance-polres": "Performance Polres",
"performance-satker": "Performance Satker", "performance-satker": "Performance Satker",
"analysis": "Analysis", "analysis": "Analysis",

View File

@ -328,7 +328,7 @@
"sellers": "Sellers", "sellers": "Sellers",
"typography": "Typography", "typography": "Typography",
"colors": "Colors", "colors": "Colors",
"performance-polda": "Performa Polda", "performance-polda": "Performa Polda/Satker",
"performance-polres": "Performa Polres", "performance-polres": "Performa Polres",
"performance-satker": "Performa Satker", "performance-satker": "Performa Satker",
"analysis": "Analisa", "analysis": "Analisa",