Compare commits

..

119 Commits

Author SHA1 Message Date
hanif salafi b181f6b3dd Edit .gitlab-ci.yml 2025-11-11 17:21:03 +00:00
Sabda Yagra cde575cb5e fix: edit url in all tableau 2025-11-12 00:14:42 +07:00
Sabda Yagra c7b2456a78 fix: conflict in image-update-form 2025-11-11 08:33:35 +07:00
Sabda Yagra 4605ef3aeb fix: input search all content and menu sidebar in polda and satker approver 2025-11-10 22:52:59 +07:00
hanif salafi 8e2fa0425d Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-11-06 01:40:28 +07:00
Sabda Yagra 9d028b54d3 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-11-06 00:16:19 +07:00
Sabda Yagra 978fd4eb6e Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-11-05 11:49:16 +07:00
Sabda Yagra 45a63696f4 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-27 20:22:31 +07:00
Sabda Yagra f3528fb288 fix: dockerfile 2025-10-27 11:38:09 +07:00
Sabda Yagra f2b934db97 fix: conflict 2025-10-27 10:17:57 +07:00
Sabda Yagra 173eb00cd9 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-23 09:52:28 +07:00
Sabda Yagra 0f863281ec Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-21 12:33:04 +07:00
Sabda Yagra b0813350d7 fix: conflict when pull main 2025-10-20 10:02:14 +07:00
Sabda Yagra f0205597b5 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-16 15:29:41 +07:00
Sabda Yagra fdb3080495 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-16 12:41:59 +07:00
Sabda Yagra 07a11d83a7 fix run build 2025-10-16 09:52:55 +07:00
hanif salafi 08d438881c fix: update content form 2025-10-16 09:30:50 +07:00
hanif salafi 7b13a09b76 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-16 08:53:24 +07:00
hanif salafi 4f28de0a12 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-15 15:27:01 +07:00
hanif salafi 6346426468 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-15 11:04:01 +07:00
hanif salafi 27098b5373 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-08 13:20:49 +07:00
hanif salafi fab81ed10b Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-06 09:36:46 +07:00
hanif salafi 6871934fe6 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-10-03 22:37:29 +07:00
hanif salafi fae207dfb0 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-27 12:33:06 +07:00
hanif salafi caa82967b5 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-26 14:52:50 +07:00
hanif salafi a7be72f7f7 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-26 10:17:53 +07:00
hanif salafi f2bfd3f36a Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-25 15:37:10 +07:00
hanif salafi 74acf4d894 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-23 18:00:25 +07:00
hanif salafi 25b0ce301b Merge branch 'main' into 'prod'
Main

See merge request hanifsalafi/mediahub_redesign!2
2025-09-19 11:31:33 +00:00
hanif salafi f30a6475a4 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-19 14:38:45 +07:00
hanif salafi cf6feec304 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-19 10:25:30 +07:00
hanif salafi f90ea2cc9a Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-19 02:54:05 +07:00
hanif salafi 4ee30e8bf9 feat: update regional filter fixing error 2025-09-18 21:08:06 +07:00
hanif salafi a0ca095d5b Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-18 20:54:41 +07:00
hanif salafi e03bd4a878 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-17 11:11:37 +07:00
hanif salafi 390fb27001 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-16 09:20:03 +07:00
hanif salafi 5d4ea85934 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-13 13:34:11 +07:00
hanif salafi 3d53652765 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-12 14:57:36 +07:00
hanif salafi 48a18c172f Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-11 08:27:58 +07:00
hanif salafi 0ba8138779 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-10 23:51:03 +07:00
hanif salafi ed5adaced3 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-10 12:05:43 +07:00
hanif salafi 45de7405d2 Merge branches 'main' and 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-10 08:55:44 +07:00
hanif salafi 49678e91c3 feat: fixing custom editor 2025-09-10 07:14:49 +07:00
hanif salafi 893ac68240 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-10 07:02:22 +07:00
hanif salafi d6a419e9b5 feat: update fixing 2025-09-10 06:25:25 +07:00
hanif salafi 01003616ab Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-10 06:00:41 +07:00
hanif salafi 76ab479e2d Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-09-09 08:19:13 +07:00
hanif salafi 8a404b21ed feat: change dise domain 2025-09-03 07:45:47 +07:00
hanif salafi 82d2c19e02 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-29 14:23:36 +07:00
hanif salafi 14e21a3193 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-27 09:06:15 +07:00
hanif salafi ca5a150015 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-27 08:52:09 +07:00
Sabda Yagra f4888db103 fixing conflict 2025-08-22 19:02:28 +07:00
Sabda Yagra 134a2532ee fixing conflict 2025-08-22 18:43:35 +07:00
hanif salafi 2099cd1e1c Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-18 09:38:02 +07:00
hanif salafi 0ec1ca9297 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-15 15:36:23 +07:00
hanif salafi a01d77c82a Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-14 09:37:37 +07:00
hanif salafi ae42305e0e Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-13 18:49:18 +07:00
hanif salafi 88bbe147e4 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-13 07:44:05 +07:00
Sabda Yagra 4ec966c9eb fix: disable all console.log 2025-08-12 13:31:20 +07:00
hanif salafi 4c74c191cc Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-11 17:22:26 +07:00
hanif salafi 15697a30f7 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-11 11:08:23 +07:00
hanif salafi 37ebe1ad12 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-08 12:41:55 +07:00
hanif salafi c792f5b4b1 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-08 09:10:16 +07:00
hanif salafi 090006fa30 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-07 10:40:19 +07:00
hanif salafi 166c3c8143 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-07 10:28:42 +07:00
hanif salafi 97612d6a71 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-05 12:32:13 +07:00
hanif salafi f10db99437 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-05 11:59:47 +07:00
hanif salafi a4bf80482a featL update id of satker 2025-08-05 11:19:33 +07:00
hanif salafi 12c904d49a Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-04 13:53:11 +07:00
hanif salafi 541f9b6004 Merge branches 'main' and 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-04 11:00:09 +07:00
hanif salafi fd61c5311b Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-04 08:47:58 +07:00
hanif salafi a8c6087437 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-08-01 12:44:24 +07:00
hanif salafi 3f2d66c426 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-31 20:47:12 +07:00
hanif salafi f854cb7385 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-31 12:46:10 +07:00
hanif salafi d8aad6da43 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-29 10:20:14 +07:00
hanif salafi ed71982b6c Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-28 15:48:36 +07:00
hanif salafi 2fae4027ee Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-28 14:10:01 +07:00
hanif salafi 4e1d98d168 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-25 18:04:16 +07:00
hanif salafi ad4aa1f81e Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-24 21:15:43 +07:00
hanif salafi 7d9f23896e Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-24 16:31:25 +07:00
hanif salafi 459425a309 fixing error 2025-07-24 13:45:12 +07:00
hanif salafi 6ac02ba0a9 feat: update Dockerfile 2025-07-24 13:14:45 +07:00
hanif salafi 3445a932eb Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-24 12:52:12 +07:00
hanif salafi 9ae0c9269d update fixing 2025-07-24 12:32:31 +07:00
hanif salafi 59834d95e7 feat: update conflict 2025-07-23 17:39:33 +07:00
hanif salafi dd1479000e Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-23 09:42:59 +07:00
hanif salafi 8e3090d6eb update: fixing vendors 2025-07-23 08:58:26 +07:00
hanif salafi a80585326a update fixing 2025-07-23 08:45:49 +07:00
hanif salafi 96f16d2b77 fixing ckeditor 2025-07-22 20:32:08 +07:00
hanif salafi 16cbdcff45 Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-22 14:35:47 +07:00
hanif salafi ddd31a46fd Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-21 20:07:54 +07:00
hanif salafi ad13a58ac8 feat: update custom editor 2025-07-21 16:53:10 +07:00
hanif salafi e0d9b43892 feat: update Dockerfile 2025-07-21 15:45:09 +07:00
hanif salafi 72b16e21ba feat: update dockerfile 2025-07-21 15:41:49 +07:00
hanif salafi 09a27f3807 fixing error 2025-07-21 15:36:50 +07:00
hanif salafi 47c2fc55df update: merge from DEV : change ckeditor, detail media, etc 2025-07-21 15:28:41 +07:00
hanif salafi c44ae46633 Merge branch 'prod' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-21 10:07:16 +07:00
hanif salafi d00956503f feat: update detail media 2025-07-21 10:07:04 +07:00
Sabda Yagra e9fa8f8e93 feat: change background landing in dark mode 2025-07-21 09:27:09 +07:00
hanif salafi 5467edc3a7 feat: remove unused file 2025-07-21 00:06:56 +07:00
hanif salafi 1a6919ea5d Merge branch 'main' of https://gitlab.com/hanifsalafi/mediahub_redesign into prod 2025-07-20 23:56:38 +07:00
hanif salafi 471adf85f0 feat: update viz performance polda 2025-07-20 23:00:16 +07:00
hanif salafi e2450d4b56 feat: update performance polda 2025-07-20 22:28:05 +07:00
hanif salafi be9f8649f4 feat: update param tableau 2025-07-20 22:00:55 +07:00
hanif salafi 5e849572a3 feat: update dashboard viz 2025-07-20 20:44:44 +07:00
Sabda Yagra 07c7a93b18 fix: button cancel in all form 2025-07-20 18:10:49 +07:00
hanif salafi 0b420bdef4 feat : update approval show detail media 2025-07-20 17:06:42 +07:00
hanif salafi f639a827d4 fixing spit convert 2025-07-20 16:10:19 +07:00
hanif salafi 007a6d9eec fixing custom editor and spit convert 2025-07-20 16:07:22 +07:00
hanif salafi f3757bcfac update viz tableau 2025-07-20 15:50:01 +07:00
hanif salafi a0b658bbfc feat: update tableau viz url 2025-07-20 03:46:48 +07:00
hanif salafi fb1d0fde82 feat: update auth services 2025-07-20 03:02:15 +07:00
hanif salafi 04a04cfe74 feat: update next config 2025-07-20 02:44:27 +07:00
hanif salafi ac332b7099 feat: update http service 2025-07-20 02:00:02 +07:00
Sabda Yagra 3ed1327707 change endpoint api 2025-07-19 22:37:18 +07:00
Sabda Yagra b3ab21700a add in script docker 2025-07-19 21:02:02 +07:00
Sabda Yagra 026eae5cd3 change docker login 2025-07-19 20:54:01 +07:00
Sabda Yagra 00aeded4ea change script docker login 2025-07-19 20:50:03 +07:00
Sabda Yagra 72099c35a6 change domain to mediahub.polri.go.id 2025-07-19 20:37:18 +07:00
302 changed files with 13602 additions and 11393 deletions

View File

@ -1,46 +0,0 @@
kind: pipeline
type: ssh
name: mediahub-fe-build-deploy
server:
host:
from_secret: ssh_host
user:
from_secret: ssh_user
ssh_key:
from_secret: ssh_key
steps:
- name: prepare repo
when:
branch:
- dev-sabda-v2
- main
- prod
commands:
- rm -rf /opt/build/mediahub-fe
- mkdir -p /opt/build
- cd /opt/build
- git clone http://38.47.180.165:3000/mediahub/mediahub-fe.git
- name: build image
when:
branch:
- dev-sabda-v2
- main
- prod
commands:
- docker login 38.47.180.165:3000 -u administrator -p HarborDockerImageRep0
- cd /opt/build/mediahub-fe
- docker build -t 38.47.180.165:3000/mediahub/mediahub-fe:$DRONE_BRANCH .
- docker push 38.47.180.165:3000/mediahub/mediahub-fe:$DRONE_BRANCH
- name: deploy
when:
branch:
- main
commands:
- docker pull 38.47.180.165:3000/mediahub/mediahub-fe:$DRONE_BRANCH
- docker stop new-mediahub-fe || true
- docker rm new-mediahub-fe || true
- docker run -dt -p 4200:3000 --restart always --name new-mediahub-fe 38.47.180.165:3000/mediahub/mediahub-fe:$DRONE_BRANCH

4
.env
View File

@ -1,3 +1,3 @@
NEXT_PUBLIC_API=https://new.netidhub.com/api NEXT_PUBLIC_API=https://mediahub.polri.go.id/api/v2
NEXT_PUBLIC=https://new.netidhub.com NEXT_PUBLIC=https://mediahub.polri.go.id
NEXT_PUBLIC_TINYMCE_API_KEY=bhteuja26yz5p0aubxry9b95hs33amgn65kjv5km0fd5iuev NEXT_PUBLIC_TINYMCE_API_KEY=bhteuja26yz5p0aubxry9b95hs33amgn65kjv5km0fd5iuev

View File

@ -1,23 +1,26 @@
stages: stages:
- build - build
- deploy - deploy
build-dev: build-prod:
stage: build stage: build
when: on_success when: on_success
only: only:
- main - main
- dev-landing-v2 - dev-landing-v2
image: - prod
image:
name: docker:25.0.3-cli name: docker:25.0.3-cli
services: services:
- name: docker:25.0.3-dind - name: docker:25.0.3-dind
command: ["--insecure-registry=38.47.185.86:8900"] command: ["--insecure-registry=103.82.242.92:8900"]
script: script:
- docker logout - docker logout
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN 38.47.185.86:8900 - echo "Username:$DEPLOY_USERNAME"
- docker build -t 38.47.185.86:8900/mediahub/new-mediahub-fe:dev . - echo "Token:$DEPLOY_TOKEN"
- docker push 38.47.185.86:8900/mediahub/new-mediahub-fe:dev - 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 push 103.82.242.92:8900/mediahub/new-mediahub-fe:prod
auto-deploy: auto-deploy:
stage: deploy stage: deploy
@ -26,5 +29,7 @@ auto-deploy:
- main - main
- dev-landing-v2 - dev-landing-v2
image: curlimages/curl:latest image: curlimages/curl:latest
services:
- docker:dind
script: script:
- curl --user admin:$JENKINS_PWD http://38.47.185.86:8080/job/auto-deploy-new-mediahub-fe/build?token=autodeploynewmediahub - curl --user admin:$JENKINS_PWD http://38.47.180.165:8080/job/auto-deploy-new-mediahub-fe/build?token=autodeploynewmediahub

View File

@ -18,7 +18,7 @@ import { useRouter } from "next/navigation";
import { deleteUser } from "@/service/management-user/management-user"; import { deleteUser } from "@/service/management-user/management-user";
import { stringify } from "querystring"; import { stringify } from "querystring";
const getColumns = ({ onRefresh }: { onRefresh: () => void }): ColumnDef<any>[] => [ const columns: ColumnDef<any>[] = [
{ {
accessorKey: "no", accessorKey: "no",
header: "No", header: "No",
@ -30,13 +30,11 @@ const getColumns = ({ onRefresh }: { onRefresh: () => void }): ColumnDef<any>[]
header: "Nama", header: "Nama",
cell: ({ row }) => <span>{row.getValue("fullname")}</span>, cell: ({ row }) => <span>{row.getValue("fullname")}</span>,
}, },
{ {
accessorKey: "address", accessorKey: "address",
header: "Wilayah", header: "Wilayah",
cell: () => <span>MABES</span>, cell: ({ row }) => <span>MABES</span>,
}, },
{ {
accessorKey: "userRolePlacements", accessorKey: "userRolePlacements",
header: "Posisi", header: "Posisi",
@ -54,7 +52,6 @@ const getColumns = ({ onRefresh }: { onRefresh: () => void }): ColumnDef<any>[]
return <span>{posisi}</span>; return <span>{posisi}</span>;
}, },
}, },
{ {
accessorKey: "role.name", accessorKey: "role.name",
header: "Bidang Keahlian", header: "Bidang Keahlian",
@ -84,77 +81,72 @@ const getColumns = ({ onRefresh }: { onRefresh: () => void }): ColumnDef<any>[]
{ {
id: "actions", id: "actions",
accessorKey: "action",
header: "Actions", header: "Actions",
enableHiding: false,
cell: ({ row }) => { cell: ({ row }) => {
const { toast } = useToast(); const { toast } = useToast();
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter();
const doDelete = async (id: number) => { const doDelete = async (id: number) => {
Swal.fire({
title: "Menghapus user...",
text: "Mohon tunggu",
allowOutsideClick: false,
didOpen: () => Swal.showLoading(),
});
const response = await deleteUser(id); const response = await deleteUser(id);
Swal.close();
if (response?.error) { if (response?.error) {
toast({ toast({
title: stringify(response?.message), title: stringify(response?.message),
variant: "destructive", variant: "destructive",
}); });
return;
} }
toast({
title: "Success delete",
});
toast({ title: "Berhasil menghapus user" }); router.push("?dataChange=true");
// ⬅️ INI YANG PENTING → REFRESH TABLE TANPA RELOAD
onRefresh();
}; };
const handleDelete = (id: number) => { const handleDelete = (id: number) => {
MySwal.fire({ MySwal.fire({
title: "Hapus user ini?", title: "Apakah anda ingin menghapus data user?",
showCancelButton: true, showCancelButton: true,
confirmButtonColor: "#dc3545", confirmButtonColor: "#dc3545",
confirmButtonText: "Iya", confirmButtonText: "Iya",
cancelButtonText: "Tidak", cancelButtonText: "Tidak",
}).then((res) => { }).then((result) => {
if (res.isConfirmed) doDelete(id); if (result.isConfirmed) {
doDelete(id);
}
}); });
}; };
return ( return (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button size="icon" variant="ghost"> <Button
<MoreVertical className="h-4 w-4" /> size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="end"> <DropdownMenuContent className="p-0" align="end">
<Link href={`/admin/add-experts/detail/${row?.original?.id}`}>
<Link href={`/admin/add-experts/detail/${row.original.id}`}> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer"> <Eye className="w-4 h-4 me-1.5" />
<Eye className="w-4 h-4 me-1.5" /> View View
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
<Link href={`/admin/add-experts/update/${row.original.id}`}> <Link href={`/admin/add-experts/update/${row?.original?.id}`}>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer"> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" /> Edit <SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
<DropdownMenuItem <DropdownMenuItem
onClick={() => handleDelete(row.original.userKeycloakId)} onClick={() => handleDelete(row.original.userKeycloakId)}
className="text-red-600 cursor-pointer hover:bg-red-300" className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
> >
<Trash2 className="w-4 h-4 me-1.5" /> Delete <Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
); );
@ -162,4 +154,4 @@ const getColumns = ({ onRefresh }: { onRefresh: () => void }): ColumnDef<any>[]
}, },
]; ];
export default getColumns; export default columns;

View File

@ -2,6 +2,7 @@
import * as React from "react"; import * as React from "react";
import { import {
ColumnDef,
ColumnFiltersState, ColumnFiltersState,
PaginationState, PaginationState,
SortingState, SortingState,
@ -14,6 +15,7 @@ import {
useReactTable, useReactTable,
} from "@tanstack/react-table"; } from "@tanstack/react-table";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import {
Table, Table,
TableBody, TableBody,
@ -23,6 +25,7 @@ import {
TableRow, TableRow,
} from "@/components/ui/table"; } from "@/components/ui/table";
import { UserIcon } from "lucide-react"; import { UserIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -32,14 +35,43 @@ import {
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
import { ticketingPagination } from "@/service/ticketing/ticketing";
import { Badge } from "@/components/ui/badge";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import TablePagination from "@/components/table/table-pagination"; import TablePagination from "@/components/table/table-pagination";
// import columns from "./column"; import columns from "./column";
import getColumns from "./column"; import { getPlanningPagination } from "@/service/agenda-setting/agenda-setting";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { listDataMedia } from "@/service/broadcast/broadcast";
import { listEnableCategory } from "@/service/content/content"; import { listEnableCategory } from "@/service/content/content";
import { Checkbox } from "@/components/ui/checkbox";
import { close, loading } from "@/config/swal";
import { Link } from "@/i18n/routing"; import { Link } from "@/i18n/routing";
import { listDataExperts } from "@/service/experts/experts"; import { listDataExperts } from "@/service/experts/experts";
const dummyData = [
{
id: 1,
name: "Prof. Dr. Ravi",
region: "Nasional",
skills: "Komunikasi",
experience: "Akademisi",
},
{
id: 2,
name: "Prof. Dr. Novan",
region: "DKI Jakarta",
skills: "Hukum",
experience: "Akademisi + Praktisi",
},
];
const AddExpertTable = () => { const AddExpertTable = () => {
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
@ -65,8 +97,7 @@ const AddExpertTable = () => {
const [limit, setLimit] = React.useState(10); const [limit, setLimit] = React.useState(10);
const table = useReactTable({ const table = useReactTable({
data: dataTable, data: dataTable,
// columns, columns,
columns: getColumns({ onRefresh: fetchData }),
onSortingChange: setSorting, onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters, onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(), getCoreRowModel: getCoreRowModel(),
@ -252,11 +283,7 @@ const AddExpertTable = () => {
)) ))
) : ( ) : (
<TableRow> <TableRow>
<TableCell <TableCell colSpan={columns.length} className="h-24 text-center">
// colSpan={columns.length}
colSpan={table.getAllLeafColumns().length}
className="h-24 text-center"
>
No results. No results.
</TableCell> </TableCell>
</TableRow> </TableRow>

View File

@ -35,61 +35,32 @@ import {
import { error, loading } from "@/config/swal"; import { error, loading } from "@/config/swal";
import { Eye, EyeOff } from "lucide-react"; import { Eye, EyeOff } from "lucide-react";
// const FormSchema = z.object({
// name: z.string({
// required_error: "Required",
// }),
// username: z.string({
// required_error: "Required",
// }),
// password: z.string({
// required_error: "Required",
// }),
// phoneNumber: z.string({
// required_error: "Required",
// }),
// email: z.string({
// required_error: "Required",
// }),
// skills: z.string({
// required_error: "Required",
// }),
// experiences: z.string({
// required_error: "Required",
// }),
// company: z.string({
// required_error: "Required",
// }),
// });
const FormSchema = z.object({ const FormSchema = z.object({
name: z.string({ required_error: "Required" }), name: z.string({
username: z required_error: "Required",
.string({ required_error: "Required" }) }),
.refine((val) => !/\s/.test(val), { username: z.string({
message: "Username tidak boleh mengandung spasi", required_error: "Required",
}), }),
// .transform((val) => val.toLowerCase()), password: z.string({
required_error: "Required",
password: z }),
.string({ required_error: "Required" }) phoneNumber: z.string({
.min(8, "Minimal 8 karakter") required_error: "Required",
.regex(/[A-Z]/, "Harus mengandung huruf besar (A-Z)") }),
.regex(/[0-9]/, "Harus mengandung angka (0-9)") email: z.string({
.regex(/[^A-Za-z0-9]/, "Harus mengandung karakter spesial (!@#$%^&*)"), required_error: "Required",
}),
// confirmPassword: z.string({ required_error: "Required" }), skills: z.string({
required_error: "Required",
phoneNumber: z.string({ required_error: "Required" }), }),
email: z.string({ required_error: "Required" }), experiences: z.string({
skills: z.string({ required_error: "Required" }), required_error: "Required",
experiences: z.string({ required_error: "Required" }), }),
company: z.string({ required_error: "Required" }), company: z.string({
required_error: "Required",
}),
}); });
// .refine((data) => data.password === data.confirmPassword, {
// path: ["confirmPassword"],
// message: "Konfirmasi password tidak sama",
// });
export type Placements = { export type Placements = {
index: number; index: number;
@ -103,7 +74,6 @@ export default function AddExpertForm() {
const form = useForm<z.infer<typeof FormSchema>>({ const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema), resolver: zodResolver(FormSchema),
}); });
const [passwordStrength, setPasswordStrength] = useState("");
const [incrementId, setIncrementId] = useState(1); const [incrementId, setIncrementId] = useState(1);
const [placementRows, setPlacementRows] = useState<Placements[]>([ const [placementRows, setPlacementRows] = useState<Placements[]>([
{ index: 0, roleId: "", userLevelId: 0 }, { index: 0, roleId: "", userLevelId: 0 },
@ -148,7 +118,7 @@ export default function AddExpertForm() {
}; };
const save = async (data: z.infer<typeof FormSchema>) => { const save = async (data: z.infer<typeof FormSchema>) => {
console.log("data", data); // console.log("data", data);
const dataReq = { const dataReq = {
firstName: data.name, firstName: data.name,
@ -165,7 +135,7 @@ export default function AddExpertForm() {
}; };
loading(); loading();
// check availability first // check availability first
var placementArr: any[] = []; var placementArr: any[] = [];
placementRows.forEach((row: any) => { placementRows.forEach((row: any) => {
@ -274,10 +244,10 @@ export default function AddExpertForm() {
}; };
const handleRemoveRow = (index: number) => { const handleRemoveRow = (index: number) => {
console.log(index); // console.log(index);
console.log(placementRows); // console.log(placementRows);
const newPlacements = placementRows.filter((row) => row.index != index); const newPlacements = placementRows.filter((row) => row.index != index);
console.log(newPlacements); // console.log(newPlacements);
setPlacementRows(newPlacements); setPlacementRows(newPlacements);
}; };
@ -291,19 +261,6 @@ export default function AddExpertForm() {
} }
}; };
const computeStrength = (password: string) => {
let score = 0;
if (password.length >= 8) score++;
if (/[A-Z]/.test(password)) score++;
if (/[0-9]/.test(password)) score++;
if (/[^A-Za-z0-9]/.test(password)) score++;
if (score <= 1) return "weak";
if (score === 2 || score === 3) return "medium";
if (score === 4) return "strong";
return "";
};
return ( return (
<div> <div>
<SiteBreadcrumb /> <SiteBreadcrumb />
@ -331,39 +288,6 @@ export default function AddExpertForm() {
)} )}
/> />
<FormField <FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username (huruf kecil, tanpa spasi)</FormLabel>
<Input
type="text"
value={field.value}
placeholder="masukkan username"
onChange={(e) => {
let value = e.target.value;
// Hapus spasi otomatis
value = value.replace(/\s+/g, "");
// Jadikan lowercase otomatis
value = value.toLowerCase();
field.onChange(value);
}}
/>
{/* Info tambahan */}
<p className="text-xs text-gray-500 mt-1">
Username otomatis menjadi huruf kecil tanpa spasi.
</p>
<FormMessage />
</FormItem>
)}
/>
{/* <FormField
control={form.control} control={form.control}
name="username" name="username"
render={({ field }) => ( render={({ field }) => (
@ -379,7 +303,7 @@ export default function AddExpertForm() {
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> */} />
<FormField <FormField
control={form.control} control={form.control}
name="phoneNumber" name="phoneNumber"
@ -425,69 +349,6 @@ export default function AddExpertForm() {
)} )}
/> />
<FormField <FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<div className="relative">
<Input
type={showPassword ? "text" : "password"}
value={field.value}
placeholder="Masukkan Password"
onChange={(e) => {
field.onChange(e.target.value);
setPasswordStrength(computeStrength(e.target.value));
}}
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-default-500"
>
{showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
</button>
</div>
<FormLabel className="text-gray-400 text-[12px]">
Password harus memiliki minimal 8 karakter, special karakter,
angka dan huruf kapital
</FormLabel>
{/* Strength meter */}
{field.value && (
<div className="mt-2">
<div
className={`h-2 rounded transition-all ${
passwordStrength === "weak"
? "bg-red-500 w-1/4"
: passwordStrength === "medium"
? "bg-yellow-500 w-2/4"
: "bg-green-500 w-full"
}`}
/>
<p
className={`text-xs mt-1 ${
passwordStrength === "weak"
? "text-red-500"
: passwordStrength === "medium"
? "text-yellow-600"
: "text-green-600"
}`}
>
{passwordStrength === "weak" && "Weak Password"}
{passwordStrength === "medium" && "Medium Password"}
{passwordStrength === "strong" && "Strong Password"}
</p>
</div>
)}
<FormMessage />
</FormItem>
)}
/>
{/* <FormField
control={form.control} control={form.control}
name="password" name="password"
render={({ field }) => ( render={({ field }) => (
@ -512,7 +373,7 @@ export default function AddExpertForm() {
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> */} />
<FormField <FormField
control={form.control} control={form.control}
name="skills" name="skills"

View File

@ -37,43 +37,32 @@ import { Eye, EyeOff } from "lucide-react";
import { useParams } from "next/navigation"; import { useParams } from "next/navigation";
const FormSchema = z.object({ const FormSchema = z.object({
name: z.string().optional(), name: z.string({
username: z.string().optional(), required_error: "Required",
password: z.string().optional(), }),
phoneNumber: z.string().optional(), username: z.string({
email: z.string().optional(), required_error: "Required",
skills: z.string().optional(), }),
experiences: z.string().optional(), password: z.string({
company: z.string().optional(), required_error: "Required",
}),
phoneNumber: z.string({
required_error: "Required",
}),
email: z.string({
required_error: "Required",
}),
skills: z.string({
required_error: "Required",
}),
experiences: z.string({
required_error: "Required",
}),
company: z.string({
required_error: "Required",
}),
}); });
// const FormSchema = z.object({
// name: z.string({
// required_error: "Required",
// }),
// username: z.string({
// required_error: "Required",
// }),
// password: z.string({
// required_error: "Required",
// }),
// phoneNumber: z.string({
// required_error: "Required",
// }),
// email: z.string({
// required_error: "Required",
// }),
// skills: z.string({
// required_error: "Required",
// }),
// experiences: z.string({
// required_error: "Required",
// }),
// company: z.string({
// required_error: "Required",
// }),
// });
export type Placements = { export type Placements = {
index: number; index: number;
roleId?: string; roleId?: string;
@ -107,10 +96,6 @@ interface Detail {
createdAt: string; createdAt: string;
}; };
}; };
userRolePlacements?: {
roleId: number;
userLevelId: number;
}[];
} }
export default function UpdateExpertForm() { export default function UpdateExpertForm() {
@ -164,39 +149,6 @@ export default function UpdateExpertForm() {
initState(); initState();
}, [id]); }, [id]);
useEffect(() => {
if (!detail) return;
// Isi semua form field
form.reset({
name: detail.fullname || "",
username: detail.username || "",
phoneNumber: detail.phoneNumber || "",
email: detail.email || "",
password: "",
skills: detail?.userProfilesAdditional?.userCompetency?.id
? String(detail.userProfilesAdditional.userCompetency.id)
: "",
experiences: detail?.userProfilesAdditional?.userExperienceId
? String(detail.userProfilesAdditional.userExperienceId)
: "",
company: detail?.userProfilesAdditional?.companyName || "",
});
// 🔥 Masukkan posisi existing
if (detail.userRolePlacements && detail.userRolePlacements.length > 0) {
const mapped = detail.userRolePlacements.map(
(item: any, idx: number) => ({
index: idx,
roleId: String(item.roleId),
userLevelId: Number(item.userLevelId),
})
);
setPlacementRows(mapped);
}
}, [detail]);
if (!detail) return <div>Loading...</div>; if (!detail) return <div>Loading...</div>;
const togglePasswordType = () => { const togglePasswordType = () => {
@ -233,39 +185,22 @@ export default function UpdateExpertForm() {
}; };
const save = async (data: z.infer<typeof FormSchema>) => { const save = async (data: z.infer<typeof FormSchema>) => {
console.log("data", data); // console.log("data", data);
const dataReq = { const dataReq = {
id: detail?.id, id: detail?.id,
firstName: data.name || detail.fullname, firstName: data.name,
username: data.username || detail.username, username: data.username,
email: data.email || detail.email, email: data.email,
password: data.password || undefined, password: data.password,
address: "", address: "",
roleId: "EXP-ID", roleId: "EXP-ID",
phoneNumber: data.phoneNumber || detail.phoneNumber, phoneNumber: data.phoneNumber,
userCompetencyId: userCompetencyId: data.skills,
data.skills || detail.userProfilesAdditional?.userCompetency?.id, userExperienceId: data.experiences,
userExperienceId: companyName: data.company,
data.experiences || detail.userProfilesAdditional?.userExperienceId,
companyName: data.company || detail.userProfilesAdditional?.companyName,
isAdmin: true,
}; };
// const dataReq = {
// id: detail?.id,
// firstName: data.name,
// username: data.username,
// email: data.email,
// password: data.password,
// address: "",
// roleId: "EXP-ID",
// phoneNumber: data.phoneNumber,
// userCompetencyId: data.skills,
// userExperienceId: data.experiences,
// companyName: data.company,
// };
loading(); loading();
const res = await saveUserInternal(dataReq); const res = await saveUserInternal(dataReq);
const resData = res?.data?.data; const resData = res?.data?.data;
@ -310,7 +245,7 @@ export default function UpdateExpertForm() {
const resExperiences = await getListExperiences(); const resExperiences = await getListExperiences();
setUserExperiences(resExperiences?.data?.data); setUserExperiences(resExperiences?.data?.data);
console.log("experience", resExperiences?.data?.data); // console.log("experience", resExperiences?.data?.data);
const resUserLevels = await AdministrationLevelList(); const resUserLevels = await AdministrationLevelList();
const data = resUserLevels?.data?.data; const data = resUserLevels?.data?.data;
@ -353,10 +288,10 @@ export default function UpdateExpertForm() {
}; };
const handleRemoveRow = (index: number) => { const handleRemoveRow = (index: number) => {
console.log(index); // console.log(index);
console.log(placementRows); // console.log(placementRows);
const newPlacements = placementRows.filter((row) => row.index != index); const newPlacements = placementRows.filter((row) => row.index != index);
console.log(newPlacements); // console.log(newPlacements);
setPlacementRows(newPlacements); setPlacementRows(newPlacements);
}; };
@ -387,15 +322,10 @@ export default function UpdateExpertForm() {
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Nama Lengkap</FormLabel> <FormLabel>Nama Lengkap</FormLabel>
{/* <Input <Input
defaultValue={detail?.fullname} defaultValue={detail?.fullname}
placeholder="Masukkan Nama Lengkap" placeholder="Masukkan Nama Lengkap"
onChange={field.onChange} onChange={field.onChange}
/> */}
<Input
{...field}
defaultValue={detail?.fullname}
placeholder="Masukkan Nama Lengkap"
/> />
<FormMessage /> <FormMessage />
@ -403,24 +333,18 @@ export default function UpdateExpertForm() {
)} )}
/> />
<FormField <FormField
disabled
control={form.control} control={form.control}
name="username" name="username"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Username</FormLabel> <FormLabel>Username</FormLabel>
{/* <Input <Input
type="text" type="text"
defaultValue={detail?.username} defaultValue={detail?.username}
placeholder="Masukkan" placeholder="Masukkan"
onChange={field.onChange} onChange={field.onChange}
/> */}
<Input
{...field}
type="text"
defaultValue={detail?.username}
placeholder="Masukkan"
/> />
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
@ -431,17 +355,11 @@ export default function UpdateExpertForm() {
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>No. HP</FormLabel> <FormLabel>No. HP</FormLabel>
{/* <Input <Input
type="number" type="number"
defaultValue={detail?.phoneNumber} defaultValue={detail?.phoneNumber}
placeholder="Masukkan No.Hp" placeholder="Masukkan No.Hp"
onChange={field.onChange} onChange={field.onChange}
/> */}
<Input
{...field}
type="number"
defaultValue={detail?.phoneNumber}
placeholder="Masukkan"
/> />
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -453,46 +371,17 @@ export default function UpdateExpertForm() {
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Email</FormLabel> <FormLabel>Email</FormLabel>
{/* <Input <Input
type="email" type="email"
defaultValue={detail?.email} defaultValue={detail?.email}
placeholder="Masukkan email" placeholder="Masukkan email"
onChange={field.onChange} onChange={field.onChange}
/> */}
<Input
{...field}
type="email"
defaultValue={detail?.email}
placeholder="Masukkan email"
/> />
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> />
{/* <FormField <FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password (Opsional)</FormLabel>
<div className="relative">
<Input
{...field}
type={showPassword ? "text" : "password"}
placeholder="Kosongkan jika tidak ingin mengubah password"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2"
>
{showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
</button>
</div>
</FormItem>
)}
/> */}
{/* <FormField
control={form.control} control={form.control}
name="password" name="password"
render={({ field }) => ( render={({ field }) => (
@ -517,7 +406,7 @@ export default function UpdateExpertForm() {
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> */} />
<FormField <FormField
control={form.control} control={form.control}
name="skills" name="skills"
@ -592,21 +481,12 @@ export default function UpdateExpertForm() {
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Nama Institusi/Perusahaan</FormLabel> <FormLabel>Nama Institusi/Perusahaan</FormLabel>
{/* <Input <Input
type="text" type="text"
value={detail?.userProfilesAdditional?.companyName || ""} value={detail?.userProfilesAdditional?.companyName || ""}
placeholder="Nama Institusi/Perusahaan" placeholder="Nama Institusi/Perusahaan"
onChange={field.onChange} onChange={field.onChange}
/> */}
<Input
{...field}
type="text"
defaultValue={
detail?.userProfilesAdditional?.companyName || ""
}
placeholder="Nama Institusi/Perusahaan"
/> />
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
@ -617,7 +497,6 @@ export default function UpdateExpertForm() {
{placementRows?.map((row: any) => ( {placementRows?.map((row: any) => (
<div key={row.index} className="flex items-center gap-2 my-2"> <div key={row.index} className="flex items-center gap-2 my-2">
<Select <Select
value={row.roleId}
onValueChange={(e) => onValueChange={(e) =>
handleSelectionChange(row.index, "roleId", e) handleSelectionChange(row.index, "roleId", e)
} }
@ -654,7 +533,6 @@ export default function UpdateExpertForm() {
</SelectContent> </SelectContent>
</Select> */} </Select> */}
<Select <Select
value={row.userLevelId}
onValueChange={(e) => onValueChange={(e) =>
handleSelectionChange(row.index, "userLevelId", e) handleSelectionChange(row.index, "userLevelId", e)
} }
@ -684,7 +562,7 @@ export default function UpdateExpertForm() {
type="button" type="button"
size="md" size="md"
onClick={handleAddRow} onClick={handleAddRow}
disabled={placementRows.length >= 2} disabled={placementRows.length >= 2} // optional: disable button if already 1 row added
> >
Tambah Tambah
</Button> </Button>

View File

@ -43,8 +43,8 @@ export default function ContentManagement() {
const [ticket6, setTicket6] = useState(""); const [ticket6, setTicket6] = useState("");
const [isInternational, setIsInternational] = useState([false, false, false]); const [isInternational, setIsInternational] = useState([false, false, false]);
const baseUrl = "https://analytic.sitani.info/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://analytic.sitani.info/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const view1 = const view1 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -87,7 +87,7 @@ export default function ContentManagement() {
? "views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-intl?" ? "views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-intl?"
: "views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-intl?" : "views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-intl?"
: `views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-intl?provinsi-polda=${poldaState}&`; : `views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-intl?provinsi-polda=${poldaState}&`;
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true"; const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true";
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {

View File

@ -43,8 +43,8 @@ export default function EmergencyIssue() {
const [ticket6, setTicket6] = useState(""); const [ticket6, setTicket6] = useState("");
const [isInternational, setIsInternational] = useState([false, false, false]); const [isInternational, setIsInternational] = useState([false, false, false]);
const baseUrl = "https://analytic.sitani.info/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://analytic.sitani.info/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const view1 = const view1 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -53,7 +53,7 @@ export default function EmergencyIssue() {
: "views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue?" : "views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue?"
: `views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue?provinsi-polda=${provState}&`; : `views/2023_08_MediaHUB-KtnMgt_Rev100/db-emg-issue?provinsi-polda=${provState}&`;
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true"; const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true";
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {

View File

@ -43,8 +43,8 @@ export default function FeedbackCenter() {
const [ticket6, setTicket6] = useState(""); const [ticket6, setTicket6] = useState("");
const [isInternational, setIsInternational] = useState([false, false, false]); const [isInternational, setIsInternational] = useState([false, false, false]);
const baseUrl = "https://analytic.sitani.info/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://analytic.sitani.info/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const view1 = const view1 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -53,7 +53,7 @@ export default function FeedbackCenter() {
: "views/2023_08_MediaHUB-KtnMgt_Rev100/db-tickets?" : "views/2023_08_MediaHUB-KtnMgt_Rev100/db-tickets?"
: `views/2023_08_MediaHUB-KtnMgt_Rev100/db-tickets?provinsi-polda=${provState}&`; : `views/2023_08_MediaHUB-KtnMgt_Rev100/db-tickets?provinsi-polda=${provState}&`;
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true"; const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true";
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {

View File

@ -38,8 +38,8 @@ export default function ContentManagement() {
const [ticket6, setTicket6] = useState(""); const [ticket6, setTicket6] = useState("");
const [isInternational, setIsInternational] = useState([false, false, false]); const [isInternational, setIsInternational] = useState([false, false, false]);
const baseUrl = "https://analytic.sitani.info/"; const baseUrl = "https://db-mediahub.polri.go.id/";
const url = "https://analytic.sitani.info/trusted/"; const url = "https://db-mediahub.polri.go.id/trusted/";
const view1 = const view1 =
levelName == "MABES POLRI" levelName == "MABES POLRI"
@ -69,7 +69,7 @@ export default function ContentManagement() {
: "views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-act-jnl?" : "views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-act-jnl?"
: `views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-act-jnl?provinsi-polda=${poldaState}&`; : `views/2023_08_MediaHUB-KtnMgt_Rev100/db-ktn-act-jnl?provinsi-polda=${poldaState}&`;
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true"; const param = ":embed=yes&:toolbar=yes&:iframeSizedToWindow=true";
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {

View File

@ -59,12 +59,8 @@ import {
deleteMediaBlastCampaignAccount, deleteMediaBlastCampaignAccount,
saveMediaBlastCampaignAccountBulk, saveMediaBlastCampaignAccountBulk,
} from "@/service/broadcast/broadcast"; } from "@/service/broadcast/broadcast";
import { import { AdministrationUserList, getUserListAll } from "@/service/management-user/management-user";
AdministrationUserList,
getUserListAll,
} from "@/service/management-user/management-user";
import { close, loading, error, success, successCallback } from "@/config/swal"; import { close, loading, error, success, successCallback } from "@/config/swal";
import { Link } from "@/i18n/routing";
// Mock data for available accounts - replace with actual API call // Mock data for available accounts - replace with actual API call
const availableAccounts = [ const availableAccounts = [
@ -102,8 +98,7 @@ const AccountListTable = () => {
const [accountCategory, setAccountCategory] = React.useState<string>(""); const [accountCategory, setAccountCategory] = React.useState<string>("");
const [selectedAccount, setSelectedAccount] = React.useState<any[]>([]); const [selectedAccount, setSelectedAccount] = React.useState<any[]>([]);
const [selectedCategory, setSelectedCategory] = React.useState<string>(""); const [selectedCategory, setSelectedCategory] = React.useState<string>("");
const [availableAccountsList, setAvailableAccountsList] = const [availableAccountsList, setAvailableAccountsList] = React.useState<any[]>(availableAccounts);
React.useState<any[]>(availableAccounts);
const [usersList, setUsersList] = React.useState<any[]>([]); const [usersList, setUsersList] = React.useState<any[]>([]);
const table = useReactTable({ const table = useReactTable({
@ -176,7 +171,7 @@ const AccountListTable = () => {
async function saveCampaignAccount() { async function saveCampaignAccount() {
try { try {
loading(); loading();
if (accountCategory === "all-account") { if (accountCategory === "all-account") {
// Handle all accounts - send only campaignId and category "all" // Handle all accounts - send only campaignId and category "all"
const request = { const request = {
@ -207,7 +202,7 @@ const AccountListTable = () => {
default: default:
roleId = "5"; roleId = "5";
} }
const request = { const request = {
mediaBlastCampaignId: campaignId, mediaBlastCampaignId: campaignId,
mediaBlastAccountCategory: `role-${roleId}`, mediaBlastAccountCategory: `role-${roleId}`,
@ -221,7 +216,7 @@ const AccountListTable = () => {
// Handle custom selection - send campaignId and selected user IDs // Handle custom selection - send campaignId and selected user IDs
const request = { const request = {
mediaBlastCampaignId: campaignId, mediaBlastCampaignId: campaignId,
mediaBlastAccountIds: selectedAccount.map((acc) => acc.id), mediaBlastAccountIds: selectedAccount.map(acc => acc.id),
}; };
const response = await saveMediaBlastCampaignAccountBulk(request); const response = await saveMediaBlastCampaignAccountBulk(request);
if (response?.error) { if (response?.error) {
@ -229,7 +224,7 @@ const AccountListTable = () => {
return; return;
} }
} }
close(); close();
successCallback("Akun berhasil ditambahkan ke campaign!"); successCallback("Akun berhasil ditambahkan ke campaign!");
resetDialogState(); resetDialogState();
@ -252,7 +247,7 @@ const AccountListTable = () => {
try { try {
loading(); loading();
const response = await getUserListAll(); const response = await getUserListAll();
if (response?.data?.data?.content) { if (response?.data?.data?.content) {
setUsersList(response.data.data.content); setUsersList(response.data.data.content);
} }
@ -270,15 +265,15 @@ const AccountListTable = () => {
setFiltered(temp); setFiltered(temp);
}; };
const removeSelectedAccount = (accountId: string) => { const removeSelectedAccount = (accountId: string) => {
setSelectedAccount(selectedAccount.filter((acc) => acc.id !== accountId)); setSelectedAccount(selectedAccount.filter(acc => acc.id !== accountId));
}; };
const getFilteredAccounts = () => { const getFilteredAccounts = () => {
if (accountCategory === "kategori" && selectedCategory) { if (accountCategory === "kategori" && selectedCategory) {
return availableAccountsList.filter( return availableAccountsList.filter(acc => acc.category === selectedCategory);
(acc) => acc.category === selectedCategory
);
} }
return availableAccountsList; return availableAccountsList;
}; };
@ -296,10 +291,7 @@ const AccountListTable = () => {
Pilih Akun Pilih Akun
</Button> </Button>
</DialogTrigger> </DialogTrigger>
<DialogContent <DialogContent size="md" className="max-w-xl max-h-[80vh] overflow-y-auto">
size="md"
className="max-w-xl max-h-[80vh] overflow-y-auto"
>
<DialogHeader> <DialogHeader>
<DialogTitle>Pilih Akun Untuk Campaign Ini</DialogTitle> <DialogTitle>Pilih Akun Untuk Campaign Ini</DialogTitle>
</DialogHeader> </DialogHeader>
@ -358,17 +350,15 @@ const AccountListTable = () => {
options={usersList.map((user: any) => ({ options={usersList.map((user: any) => ({
value: user.id, value: user.id,
label: `${user.fullname} (${user.role?.name})`, label: `${user.fullname} (${user.role?.name})`,
user: user, user: user
}))} }))}
value={selectedAccount.map((acc: any) => ({ value={selectedAccount.map((acc: any) => ({
value: acc.id, value: acc.id,
label: `${acc.fullname} (${acc.role?.name})`, label: `${acc.fullname} (${acc.role?.name})`,
user: acc, user: acc
}))} }))}
onChange={(selectedOptions: any) => { onChange={(selectedOptions: any) => {
const selectedUsers = selectedOptions const selectedUsers = selectedOptions ? selectedOptions.map((option: any) => option.user) : [];
? selectedOptions.map((option: any) => option.user)
: [];
setSelectedAccount(selectedUsers); setSelectedAccount(selectedUsers);
}} }}
placeholder="Cari dan pilih user..." placeholder="Cari dan pilih user..."
@ -379,17 +369,14 @@ const AccountListTable = () => {
className="react-select" className="react-select"
classNamePrefix="select" classNamePrefix="select"
/> />
{/* Selected Accounts Display */} {/* Selected Accounts Display */}
{selectedAccount.length > 0 && ( {selectedAccount.length > 0 && (
<div className="space-y-2"> <div className="space-y-2">
<Label>User Terpilih ({selectedAccount.length}):</Label> <Label>User Terpilih ({selectedAccount.length}):</Label>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{selectedAccount.map((acc) => ( {selectedAccount.map((acc) => (
<Badge <Badge key={acc.id} className="flex items-center gap-1">
key={acc.id}
className="flex items-center gap-1"
>
{acc.fullname} {acc.fullname}
<X <X
className="h-3 w-3 cursor-pointer" className="h-3 w-3 cursor-pointer"
@ -416,8 +403,7 @@ const AccountListTable = () => {
{accountCategory === "kategori" && selectedCategory && ( {accountCategory === "kategori" && selectedCategory && (
<div className="p-3 bg-green-50 rounded-md"> <div className="p-3 bg-green-50 rounded-md">
<p className="text-sm text-green-700"> <p className="text-sm text-green-700">
Semua akun dengan role "{selectedCategory.toUpperCase()}" Semua akun dengan role "{selectedCategory.toUpperCase()}" akan ditambahkan.
akan ditambahkan.
</p> </p>
</div> </div>
)} )}
@ -426,8 +412,7 @@ const AccountListTable = () => {
{accountCategory === "custom" && ( {accountCategory === "custom" && (
<div className="p-3 bg-purple-50 rounded-md"> <div className="p-3 bg-purple-50 rounded-md">
<p className="text-sm text-purple-700"> <p className="text-sm text-purple-700">
{selectedAccount.length} user terpilih akan ditambahkan ke {selectedAccount.length} user terpilih akan ditambahkan ke campaign ini.
campaign ini.
</p> </p>
</div> </div>
)} )}
@ -438,8 +423,7 @@ const AccountListTable = () => {
onClick={saveCampaignAccount} onClick={saveCampaignAccount}
disabled={ disabled={
!accountCategory || !accountCategory ||
(accountCategory === "custom" && (accountCategory === "custom" && selectedAccount.length < 1) ||
selectedAccount.length < 1) ||
(accountCategory === "kategori" && !selectedCategory) (accountCategory === "kategori" && !selectedCategory)
} }
> >
@ -457,47 +441,7 @@ const AccountListTable = () => {
</div> </div>
{/* === Filter Akun === */} {/* === Filter Akun === */}
<div className="flex flex-row justify-end"> <div className="flex justify-end">
{/* <div className="flex flex-row gap-4">
<Link href="/admin/broadcast/campaign-list/account-list/create">
<Button variant="default" className="bg-[#3f37c9] gap-2">
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="22"
height="22"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 13h-4v4h-2v-4H7v-2h4V7h2v4h4m2-8H5c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2"
/>
</svg>
</span>
Tambahkan Akun
</Button>
</Link>
<Button variant="default" className="bg-[#3f37c9] gap-2">
<span>
<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="currentColor"
d="M12 2v6.5a1.5 1.5 0 0 0 1.5 1.5H20v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1h3.414l-1.121 1.121a1 1 0 1 0 1.414 1.415l2.829-2.829a1 1 0 0 0 0-1.414l-2.829-2.828a1 1 0 1 0-1.414 1.414L7.414 17H4V4a2 2 0 0 1 2-2zM4 17v2H3a1 1 0 1 1 0-2zM14 2.043a2 2 0 0 1 1 .543L19.414 7a2 2 0 0 1 .543 1H14z"
/>
</g>
</svg>
</span>
Import Akun
</Button>
</div> */}
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button size="md" variant="outline"> <Button size="md" variant="outline">

View File

@ -6,6 +6,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { import {
Form, Form,
FormControl, FormControl,
FormDescription,
FormField, FormField,
FormItem, FormItem,
FormLabel, FormLabel,
@ -13,80 +14,55 @@ import {
} from "@/components/ui/form"; } from "@/components/ui/form";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { format } from "date-fns";
import { CalendarIcon } from "lucide-react";
import { Calendar } from "@/components/ui/calendar";
import { getOnlyDate } from "@/utils/globals";
import { import {
getMediaBlastCampaignPage,
saveMediaBlastAccount, saveMediaBlastAccount,
saveMediaBlastCampaign,
} from "@/service/broadcast/broadcast"; } from "@/service/broadcast/broadcast";
import { error } from "@/config/swal"; import { error } from "@/config/swal";
import { useRouter } from "@/i18n/routing"; import { useRouter } from "@/i18n/routing";
import { Checkbox } from "@/components/ui/checkbox"; import { Checkbox } from "@/components/ui/checkbox";
import { useEffect, useState } from "react"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
// ----------------------------
// ZOD SCHEMA (dinamis)
// ----------------------------
const FormSchema = z.object({ const FormSchema = z.object({
name: z.string({ required_error: "Required" }), name: z.string({
required_error: "Required",
}),
accountType: z accountType: z
.array(z.string()) .array(z.string())
.min(1, "Pilih minimal satu tipe akun"), .refine((value) => value.some((item) => item), {
message: "Required",
email: z.string().optional(), }),
whatsapp: z.string().optional(), accountCategory: z.enum(["polri", "jurnalis", "umum", "ksp"], {
required_error: "Required",
campaignId: z.string({ required_error: "Required" }), }),
}).refine( email: z.string({
(data) => { required_error: "Required",
if (data.accountType.includes("email") && !data.email) return false; }),
return true; whatsapp: z.string({
}, required_error: "Required",
{ message: "Email wajib diisi", path: ["email"] } }),
).refine( });
(data) => {
if (data.accountType.includes("wa") && !data.whatsapp) return false;
return true;
},
{ message: "Whatsapp wajib diisi", path: ["whatsapp"] }
);
// ----------------------------
// COMPONENT
// ----------------------------
export default function CreateAccountForBroadcast() { export default function CreateAccountForBroadcast() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const router = useRouter(); const router = useRouter();
const form = useForm<z.infer<typeof FormSchema>>({ const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema), resolver: zodResolver(FormSchema),
defaultValues: { defaultValues: { accountType: [] },
accountType: [],
email: "",
whatsapp: "",
},
}); });
const selectedTypes = form.watch("accountType");
const [campaigns, setCampaigns] = useState<any[]>([]);
useEffect(() => {
fetchCampaignList();
}, []);
async function fetchCampaignList() {
try {
const res = await getMediaBlastCampaignPage(0);
setCampaigns(res?.data?.data?.content ?? []);
} catch (e) {
console.log("Error fetch campaign:", e);
}
}
const onSubmit = async (data: z.infer<typeof FormSchema>) => { const onSubmit = async (data: z.infer<typeof FormSchema>) => {
MySwal.fire({ MySwal.fire({
title: "Simpan Data", title: "Simpan Data",
@ -109,8 +85,10 @@ export default function CreateAccountForBroadcast() {
icon: "success", icon: "success",
confirmButtonColor: "#3085d6", confirmButtonColor: "#3085d6",
confirmButtonText: "OK", confirmButtonText: "OK",
}).then(() => { }).then((result) => {
router.push("/admin/broadcast/campaign-list/account-list"); if (result.isConfirmed) {
router.push("/admin/broadcast/campaign-list/account-list");
}
}); });
} }
@ -118,21 +96,20 @@ export default function CreateAccountForBroadcast() {
const reqData = { const reqData = {
accountName: data.name, accountName: data.name,
accountType: data.accountType.join(","), accountType: data.accountType.join(","),
emailAddress: data.email ?? "", accountCategory: data.accountCategory,
whatsappNumber: data.whatsapp ?? "", emailAddress: data.email,
campaignId: data.campaignId, whatsappNumber: data.whatsapp,
}; };
// console.log("data", data);
console.log("REQ:", reqData);
const response = await saveMediaBlastAccount(reqData); const response = await saveMediaBlastAccount(reqData);
if (response?.error) { if (response?.error) {
error(response.message); error(response.message);
return; return false;
} }
successSubmit(); successSubmit();
}; };
return ( return (
<div> <div>
<SiteBreadcrumb /> <SiteBreadcrumb />
@ -141,9 +118,7 @@ export default function CreateAccountForBroadcast() {
onSubmit={form.handleSubmit(onSubmit)} onSubmit={form.handleSubmit(onSubmit)}
className="space-y-3 bg-white rounded-sm p-4" className="space-y-3 bg-white rounded-sm p-4"
> >
<p className="font-semibold">Account</p> <p className="fonnt-semibold">Account</p>
{/* NAMA */}
<FormField <FormField
control={form.control} control={form.control}
name="name" name="name"
@ -155,125 +130,172 @@ export default function CreateAccountForBroadcast() {
placeholder="Masukkan nama" placeholder="Masukkan nama"
onChange={field.onChange} onChange={field.onChange}
/> />
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> />
{/* CHECKBOX TIPE AKUN */}
<FormField <FormField
control={form.control} control={form.control}
name="accountType" name="accountType"
render={({ field }) => ( render={() => (
<FormItem> <FormItem>
<FormLabel>Tipe Akun</FormLabel> <FormLabel>Tipe Akun</FormLabel>
<div className="flex flex-row gap-4"> <div className="flex flex-row gap-2">
{/* WA */} {" "}
<div className="flex items-center gap-2"> <FormField
<Checkbox key="wa"
checked={field.value.includes("wa")} control={form.control}
onCheckedChange={(checked) => name="accountType"
checked render={({ field }) => {
? field.onChange([...field.value, "wa"]) return (
: field.onChange(field.value.filter((v) => v !== "wa")) <FormItem
} key="wa"
/> className="flex flex-row items-start space-x-3 space-y-0"
<label>Whatsapp</label> >
</div> <FormControl>
<Checkbox
{/* EMAIL */} checked={field.value?.includes("wa")}
<div className="flex items-center gap-2"> onCheckedChange={(checked) => {
<Checkbox return checked
checked={field.value.includes("email")} ? field.onChange([...field.value, "wa"])
onCheckedChange={(checked) => : field.onChange(
checked field.value?.filter(
? field.onChange([...field.value, "email"]) (value) => value !== "wa"
: field.onChange( )
field.value.filter((v) => v !== "email") );
) }}
} />
/> </FormControl>
<label>Email</label> <FormLabel className="font-normal">
</div> Whatsapp
</FormLabel>
</FormItem>
);
}}
/>
<FormField
key="email"
control={form.control}
name="accountType"
render={({ field }) => {
return (
<FormItem
key="email"
className="flex flex-row items-start space-x-3 space-y-0"
>
<FormControl>
<Checkbox
checked={field.value?.includes("email")}
onCheckedChange={(checked) => {
return checked
? field.onChange([...field.value, "email"])
: field.onChange(
field.value?.filter(
(value) => value !== "email"
)
);
}}
/>
</FormControl>
<FormLabel className="font-normal">Email</FormLabel>
</FormItem>
);
}}
/>
</div> </div>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> />
{/* FORM WHATSAPP */}
{selectedTypes.includes("wa") && (
<FormField
control={form.control}
name="whatsapp"
render={({ field }) => (
<FormItem>
<FormLabel>Whatsapp</FormLabel>
<Input
type="number"
placeholder="Masukkan nomor Whatsapp"
{...field}
/>
<FormMessage />
</FormItem>
)}
/>
)}
{/* FORM EMAIL */}
{selectedTypes.includes("email") && (
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<Input
type="email"
placeholder="Masukkan email"
{...field}
/>
<FormMessage />
</FormItem>
)}
/>
)}
{/* CAMPAIGN */}
<FormField <FormField
control={form.control} control={form.control}
name="campaignId" name="accountCategory"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem className="space-y-3">
<FormLabel>Campaign</FormLabel> <FormLabel>Kategori</FormLabel>
<FormControl> <FormControl>
<select <RadioGroup
className="w-full border rounded-md p-2 text-sm" onValueChange={field.onChange}
value={field.value} defaultValue={field.value}
onChange={field.onChange} className="flex flex-row gap-2"
> >
<option value="" className="text-slate-400"> <FormItem className="flex items-center space-x-3 space-y-0">
Pilih campaign <FormControl>
</option> <RadioGroupItem value="polri" />
</FormControl>
{campaigns.map((c: any) => ( <FormLabel className="font-normal">POLRI</FormLabel>
<option key={c.id} value={c.id}> </FormItem>
{c.title || `Campaign ${c.id}`} <FormItem className="flex items-center space-x-3 space-y-0">
</option> <FormControl>
))} <RadioGroupItem value="jurnalis" />
</select> </FormControl>
<FormLabel className="font-normal">JURNALIS</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="umum" />
</FormControl>
<FormLabel className="font-normal">UMUM</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="ksp" />
</FormControl>
<FormLabel className="font-normal">KSP</FormLabel>
</FormItem>
</RadioGroup>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> />
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Nama</FormLabel>
<Input
type="email"
value={field.value}
placeholder="Masukkan email"
onChange={field.onChange}
/>
{/* BUTTON */} <FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="whatsapp"
render={({ field }) => (
<FormItem>
<FormLabel>Nama</FormLabel>
<Input
type="number"
value={field.value}
placeholder="Masukkan whatsapp"
onChange={field.onChange}
/>
<FormMessage />
</FormItem>
)}
/>
<div className="flex flex-row gap-2 mt-4 pt-4"> <div className="flex flex-row gap-2 mt-4 pt-4">
<Button type="button" variant="outline" color="destructive"> <Button
size="md"
type="button"
variant="outline"
color="destructive"
className="text-xs"
>
Cancel Cancel
</Button> </Button>
<Button type="submit" color="primary"> <Button size="md" type="submit" color="primary" className="text-xs">
Submit Submit
</Button> </Button>
</div> </div>
@ -282,380 +304,3 @@ export default function CreateAccountForBroadcast() {
</div> </div>
); );
} }
// "use client";
// import SiteBreadcrumb from "@/components/site-breadcrumb";
// import { z } from "zod";
// import { useForm } from "react-hook-form";
// import { zodResolver } from "@hookform/resolvers/zod";
// import {
// Form,
// FormControl,
// FormField,
// FormItem,
// FormLabel,
// FormMessage,
// } from "@/components/ui/form";
// import withReactContent from "sweetalert2-react-content";
// import Swal from "sweetalert2";
// import { Input } from "@/components/ui/input";
// import { Button } from "@/components/ui/button";
// import {
// getMediaBlastCampaignPage,
// saveMediaBlastAccount,
// } from "@/service/broadcast/broadcast";
// import { error } from "@/config/swal";
// import { useRouter } from "@/i18n/routing";
// import { Checkbox } from "@/components/ui/checkbox";
// import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
// import { useEffect, useState } from "react";
// // const FormSchema = z.object({
// // name: z.string({
// // required_error: "Required",
// // }),
// // accountType: z
// // .array(z.string())
// // .refine((value) => value.some((item) => item), {
// // message: "Required",
// // }),
// // accountCategory: z.enum(["polri", "jurnalis", "umum", "ksp"], {
// // required_error: "Required",
// // }),
// // email: z.string({
// // required_error: "Required",
// // }),
// // whatsapp: z.string({
// // required_error: "Required",
// // }),
// // campaignId: z.string({ required_error: "Required" }),
// // });
// const FormSchema = z
// .object({
// name: z.string().min(1, "Required"),
// accountType: z.array(z.string()).refine((value) => value.length > 0, {
// message: "Pilih minimal satu tipe akun",
// }),
// accountCategory: z.enum(["polri", "jurnalis", "umum", "ksp"], {
// required_error: "Required",
// }),
// email: z.string().optional(),
// whatsapp: z.string().optional(),
// campaignId: z.string().min(1, "Required"),
// })
// .refine(
// (data) => {
// if (data.accountType.includes("email")) {
// return !!data.email && data.email.trim() !== "";
// }
// return true;
// },
// { path: ["email"], message: "Email wajib diisi" }
// )
// .refine(
// (data) => {
// if (data.accountType.includes("wa")) {
// return !!data.whatsapp && data.whatsapp.trim() !== "";
// }
// return true;
// },
// { path: ["whatsapp"], message: "Whatsapp wajib diisi" }
// );
// export default function CreateAccountForBroadcast() {
// const MySwal = withReactContent(Swal);
// const router = useRouter();
// const form = useForm<z.infer<typeof FormSchema>>({
// resolver: zodResolver(FormSchema),
// defaultValues: { accountType: [] },
// });
// const selectedTypes = form.watch("accountType");
// const [campaigns, setCampaigns] = useState<any[]>([]);
// useEffect(() => {
// fetchCampaignList();
// }, []);
// async function fetchCampaignList() {
// try {
// const res = await getMediaBlastCampaignPage(0);
// setCampaigns(res?.data?.data?.content ?? []);
// } catch (e) {
// console.log("Error fetch campaign:", e);
// }
// }
// const onSubmit = async (data: z.infer<typeof FormSchema>) => {
// MySwal.fire({
// title: "Simpan Data",
// text: "Apakah Anda yakin ingin menyimpan data ini?",
// icon: "warning",
// showCancelButton: true,
// cancelButtonColor: "#d33",
// confirmButtonColor: "#3085d6",
// confirmButtonText: "Simpan",
// }).then((result) => {
// if (result.isConfirmed) {
// save(data);
// }
// });
// };
// function successSubmit() {
// MySwal.fire({
// title: "Sukses",
// icon: "success",
// confirmButtonColor: "#3085d6",
// confirmButtonText: "OK",
// }).then((result) => {
// if (result.isConfirmed) {
// router.push("/admin/broadcast/campaign-list/account-list");
// }
// });
// }
// const save = async (data: z.infer<typeof FormSchema>) => {
// const reqData = {
// accountName: data.name,
// accountType: data.accountType.join(","),
// accountCategory: data.accountCategory,
// emailAddress: data.email ?? "",
// whatsappNumber: data.whatsapp ?? "",
// campaignId: data.campaignId,
// };
// console.log("data", data);
// const response = await saveMediaBlastAccount(reqData);
// if (response?.error) {
// error(response.message);
// return false;
// }
// successSubmit();
// };
// return (
// <div>
// <SiteBreadcrumb />
// <Form {...form}>
// <form
// onSubmit={form.handleSubmit(onSubmit)}
// className="space-y-3 bg-white rounded-sm p-4"
// >
// <p className="fonnt-semibold">Account</p>
// <FormField
// control={form.control}
// name="name"
// render={({ field }) => (
// <FormItem>
// <FormLabel>Nama</FormLabel>
// <Input
// value={field.value}
// placeholder="Masukkan nama"
// onChange={field.onChange}
// />
// <FormMessage />
// </FormItem>
// )}
// />
// <FormField
// control={form.control}
// name="accountType"
// render={() => (
// <FormItem>
// <FormLabel>Tipe Akun</FormLabel>
// <div className="flex flex-row gap-2">
// {" "}
// <FormField
// key="wa"
// control={form.control}
// name="accountType"
// render={({ field }) => {
// return (
// <FormItem
// key="wa"
// className="flex flex-row items-start space-x-3 space-y-0"
// >
// <FormControl>
// <Checkbox
// checked={field.value?.includes("wa")}
// onCheckedChange={(checked) => {
// return checked
// ? field.onChange([...field.value, "wa"])
// : field.onChange(
// field.value?.filter(
// (value) => value !== "wa"
// )
// );
// }}
// />
// </FormControl>
// <FormLabel className="font-normal">
// Whatsapp
// </FormLabel>
// </FormItem>
// );
// }}
// />
// <FormField
// key="email"
// control={form.control}
// name="accountType"
// render={({ field }) => {
// return (
// <FormItem
// key="email"
// className="flex flex-row items-start space-x-3 space-y-0"
// >
// <FormControl>
// <Checkbox
// checked={field.value?.includes("email")}
// onCheckedChange={(checked) => {
// return checked
// ? field.onChange([...field.value, "email"])
// : field.onChange(
// field.value?.filter(
// (value) => value !== "email"
// )
// );
// }}
// />
// </FormControl>
// <FormLabel className="font-normal">Email</FormLabel>
// </FormItem>
// );
// }}
// />
// </div>
// <FormMessage />
// </FormItem>
// )}
// />
// {/* <FormField
// control={form.control}
// name="accountCategory"
// render={({ field }) => (
// <FormItem className="space-y-3">
// <FormLabel>Kategori</FormLabel>
// <FormControl>
// <RadioGroup
// onValueChange={field.onChange}
// defaultValue={field.value}
// className="flex flex-row gap-2"
// >
// <FormItem className="flex items-center space-x-3 space-y-0">
// <FormControl>
// <RadioGroupItem value="polri" />
// </FormControl>
// <FormLabel className="font-normal">POLRI</FormLabel>
// </FormItem>
// <FormItem className="flex items-center space-x-3 space-y-0">
// <FormControl>
// <RadioGroupItem value="jurnalis" />
// </FormControl>
// <FormLabel className="font-normal">JURNALIS</FormLabel>
// </FormItem>
// <FormItem className="flex items-center space-x-3 space-y-0">
// <FormControl>
// <RadioGroupItem value="umum" />
// </FormControl>
// <FormLabel className="font-normal">UMUM</FormLabel>
// </FormItem>
// <FormItem className="flex items-center space-x-3 space-y-0">
// <FormControl>
// <RadioGroupItem value="ksp" />
// </FormControl>
// <FormLabel className="font-normal">KSP</FormLabel>
// </FormItem>
// </RadioGroup>
// </FormControl>
// <FormMessage />
// </FormItem>
// )}
// /> */}
// <FormField
// control={form.control}
// name="email"
// render={({ field }) => (
// <FormItem>
// <FormLabel>Email</FormLabel>
// <Input
// type="email"
// value={field.value}
// placeholder="Masukkan email"
// onChange={field.onChange}
// />
// <FormMessage />
// </FormItem>
// )}
// />
// <FormField
// control={form.control}
// name="whatsapp"
// render={({ field }) => (
// <FormItem>
// <FormLabel>Nama</FormLabel>
// <Input
// type="number"
// value={field.value}
// placeholder="Masukkan whatsapp"
// onChange={field.onChange}
// />
// <FormMessage />
// </FormItem>
// )}
// />
// <FormField
// control={form.control}
// name="campaignId"
// render={({ field }) => (
// <FormItem>
// <FormLabel>Campaign</FormLabel>
// <FormControl>
// <select
// className="w-full border rounded-md p-2"
// value={field.value}
// onChange={field.onChange}
// >
// <option value="" className="text-slate-400">
// Pilih campaign
// </option>
// {campaigns.map((c: any) => (
// <option key={c.id} value={c.id}>
// {c.title || `Campaign ${c.id}`}
// </option>
// ))}
// </select>
// </FormControl>
// <FormMessage />
// </FormItem>
// )}
// />
// <div className="flex flex-row gap-2 mt-4 pt-4">
// <Button
// size="md"
// type="button"
// variant="outline"
// color="destructive"
// className="text-xs"
// >
// Cancel
// </Button>
// <Button size="md" type="submit" color="primary" className="text-xs">
// Submit
// </Button>
// </div>
// </form>
// </Form>
// </div>
// );
// }

View File

@ -157,7 +157,7 @@ export default function EditAccountForBroadcast() {
isDefault: false, isDefault: false,
isAdmin: true, isAdmin: true,
}; };
console.log("data", data); // console.log("data", data);
const response = await saveUserInternal(reqData); const response = await saveUserInternal(reqData);
if (response?.error) { if (response?.error) {

View File

@ -136,7 +136,7 @@ const CampaignListTable = () => {
item.no = (page - 1) * 10 + index + 1; item.no = (page - 1) * 10 + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);
@ -152,12 +152,12 @@ const CampaignListTable = () => {
<div className="flex justify-between mb-10 items-center"> <div className="flex justify-between mb-10 items-center">
<p className="text-xl font-medium text-default-900">Daftar Campaign</p> <p className="text-xl font-medium text-default-900">Daftar Campaign</p>
<div className="flex flex-row gap-2"> <div className="flex flex-row gap-2">
{/* <Link href="/admin/broadcast/campaign-list/account-list"> <Link href="/admin/broadcast/campaign-list/account-list">
<Button color="primary" size="md" className="text-sm"> <Button color="primary" size="md" className="text-sm">
<UserIcon /> <UserIcon />
Daftar Akun Daftar Akun
</Button> </Button>
</Link> */} </Link>
<Link href="/admin/broadcast/campaign-list/create"> <Link href="/admin/broadcast/campaign-list/create">
<Button color="primary" size="md" className="text-sm"> <Button color="primary" size="md" className="text-sm">
<NewCampaignIcon size={23} /> <NewCampaignIcon size={23} />

View File

@ -117,8 +117,8 @@ export default function BroadcastCampaignDetail({
async function getListPaginationData() { async function getListPaginationData() {
loading(); loading();
console.log("Type : ", typeFilter); // console.log("Type : ", typeFilter);
console.log("Date : ", startDateString, endDateString); // console.log("Date : ", startDateString, endDateString);
try { try {
const res = await getMediaBlastBroadcastList( const res = await getMediaBlastBroadcastList(
@ -152,7 +152,7 @@ export default function BroadcastCampaignDetail({
]); ]);
function setupData(rawData: PaginatedResponse) { function setupData(rawData: PaginatedResponse) {
console.log("raw", rawData); // console.log("raw", rawData);
if (rawData !== undefined) { if (rawData !== undefined) {
const dataContent = rawData?.content; const dataContent = rawData?.content;
const data: CampaignData[] = []; const data: CampaignData[] = [];
@ -251,7 +251,7 @@ export default function BroadcastCampaignDetail({
setEndDateString(getOnlyDate(endDate)); setEndDateString(getOnlyDate(endDate));
} }
} }
console.log("date range", dateRange); // console.log("date range", dateRange);
initState(); initState();
}, [calenderState, startDate, endDate]); }, [calenderState, startDate, endDate]);

View File

@ -5,7 +5,7 @@ export default function CreateEmailBlast() {
return ( return (
<div> <div>
<SiteBreadcrumb /> <SiteBreadcrumb />
<ContentBlast /> <ContentBlast type="email" />
</div> </div>
); );
} }

View File

@ -90,16 +90,16 @@ const columns: ColumnDef<any>[] = [
Detail Detail
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
<Link href={`/admin/broadcast/create/${row.original.id}`}> <Link href={`/admin/broadcast/email/${row.original.id}`}>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer"> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer">
Email & Whatsapp Blast Email Blast
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
{/* <Link href={`/admin/broadcast/whatsapp/${row.original.id}`}> <Link href={`/admin/broadcast/whatsapp/${row.original.id}`}>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer"> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer">
Whatsapp Blast Whatsapp Blast
</DropdownMenuItem> </DropdownMenuItem>
</Link> */} </Link>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
); );

View File

@ -160,7 +160,7 @@ const BroadcastEmailTable = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import SiteBreadcrumb from "@/components/site-breadcrumb"; import SiteBreadcrumb from "@/components/site-breadcrumb";
import BroadcastTable from "./create/component/table"; import BroadcastTable from "./email/component/table";
import { PlusIcon } from "lucide-react"; import { PlusIcon } from "lucide-react";
import EscalationTable from "../../shared/communication/escalation/components/escalation-table"; import EscalationTable from "../../shared/communication/escalation/components/escalation-table";
@ -8,7 +8,7 @@ import InternalTable from "../../shared/communication/internal/components/intern
import { useState } from "react"; import { useState } from "react";
import { Link } from "@/i18n/routing"; import { Link } from "@/i18n/routing";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import BroadcastEmailTable from "./create/component/table"; import BroadcastEmailTable from "./email/component/table";
import BroadcastWhatsAppTable from "./whatsapp/component/table"; import BroadcastWhatsAppTable from "./whatsapp/component/table";
export default function AdminBroadcast() { export default function AdminBroadcast() {

View File

@ -5,7 +5,7 @@ export default function CreateWABlast() {
return ( return (
<div> <div>
<SiteBreadcrumb /> <SiteBreadcrumb />
{/* <ContentBlast /> */} <ContentBlast type="wa" />
</div> </div>
); );
} }

View File

@ -160,7 +160,7 @@ const BroadcastWhatsAppTable = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -85,7 +85,7 @@ export default function EditUserForm() {
const response = await getUserById(String(id)); const response = await getUserById(String(id));
const res = response?.data?.data; const res = response?.data?.data;
close(); close();
console.log("res", res); // console.log("res", res);
form.setValue("fullname", res?.fullname); form.setValue("fullname", res?.fullname);
form.setValue("username", res?.username); form.setValue("username", res?.username);
form.setValue("phoneNumber", res?.phoneNumber); form.setValue("phoneNumber", res?.phoneNumber);

View File

@ -126,7 +126,7 @@ export default function EditUserForm() {
const response = await getUserById(String(id)); const response = await getUserById(String(id));
const res = response?.data?.data; const res = response?.data?.data;
close(); close();
console.log("res", res); // console.log("res", res);
form.setValue("fullname", res?.fullname); form.setValue("fullname", res?.fullname);
form.setValue("username", res?.username); form.setValue("username", res?.username);
form.setValue("phoneNumber", res?.phoneNumber); form.setValue("phoneNumber", res?.phoneNumber);

View File

@ -203,7 +203,7 @@ export default function DetailUserForm() {
const response = await getUserById(String(id)); const response = await getUserById(String(id));
const res = response?.data?.data; const res = response?.data?.data;
close(); close();
console.log("res", res); // console.log("res", res);
if (Number(res.roleId) > 4) { if (Number(res.roleId) > 4) {
form.setValue("fullname", res?.fullname); form.setValue("fullname", res?.fullname);
form.setValue("username", res?.username); form.setValue("username", res?.username);
@ -215,7 +215,7 @@ export default function DetailUserForm() {
form.setValue("level", String(res?.userLevelId)); form.setValue("level", String(res?.userLevelId));
} else { } else {
initFetch(); initFetch();
console.log("sadad", res?.role?.code); // console.log("sadad", res?.role?.code);
form.setValue("fullname", res?.fullname); form.setValue("fullname", res?.fullname);
form.setValue("username", res?.username); form.setValue("username", res?.username);
form.setValue("phoneNumber", res?.phoneNumber); form.setValue("phoneNumber", res?.phoneNumber);

View File

@ -209,7 +209,7 @@ export default function EditUserForm() {
const response = await getUserById(String(id)); const response = await getUserById(String(id));
const res = response?.data?.data; const res = response?.data?.data;
close(); close();
console.log("res", res); // console.log("res", res);
if (Number(res.roleId) > 4) { if (Number(res.roleId) > 4) {
form.setValue("fullname", res?.fullname); form.setValue("fullname", res?.fullname);
form.setValue("username", res?.username); form.setValue("username", res?.username);

View File

@ -43,7 +43,7 @@ export default function TrackingMediaModal(props: { triggerFetch: () => void })
} }
if (/\s/.test(value)) { if (/\s/.test(value)) {
console.log("Terdapat spasi dalam input"); // console.log("Terdapat spasi dalam input");
fecthAll(); fecthAll();
} }

View File

@ -161,11 +161,11 @@ const NewsTable = () => {
setCategoryFilter( setCategoryFilter(
categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]
); );
console.log( // console.log(
"Kategori", // "Kategori",
categorie, // categorie,
categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] // categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]
); // );
} }
}, [categorie]); }, [categorie]);
@ -177,7 +177,7 @@ const NewsTable = () => {
} else { } else {
filter.splice(categoryFilter.indexOf(id), 1); filter.splice(categoryFilter.indexOf(id), 1);
} }
console.log("checkbox filter", filter); // console.log("checkbox filter", filter);
setCategoryFilter(filter); setCategoryFilter(filter);
router.push(`?category=${filter.join("&")}`); router.push(`?category=${filter.join("&")}`);
}; };

View File

@ -31,8 +31,6 @@ import {
DialogTrigger, DialogTrigger,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Collapsible, CollapsibleContent } from "@/components/ui/collapsible"; import { Collapsible, CollapsibleContent } from "@/components/ui/collapsible";
import { validateMediaLink } from "@/service/media-tracking/media-tracking";
import toast from "react-hot-toast";
const columns: ColumnDef<any>[] = [ const columns: ColumnDef<any>[] = [
{ {
@ -54,132 +52,12 @@ const columns: ColumnDef<any>[] = [
<span className="normal-case">{row.getValue("title")}</span> <span className="normal-case">{row.getValue("title")}</span>
), ),
}, },
// {
// accessorKey: "link",
// header: "Link Berita",
// cell: ({ row }) => (
// <span className="normal-case">{row.getValue("link")}</span>
// ),
// },
{ {
accessorKey: "link", accessorKey: "link",
header: "Link Berita", header: "Link Berita",
cell: ({ row }) => { cell: ({ row }) => (
const link = row.getValue<string>("link"); <span className="normal-case">{row.getValue("link")}</span>
),
if (!link) {
return <span className="text-muted-foreground">-</span>;
}
return (
<Link
href={link}
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 underline hover:text-blue-800 break-all"
>
{link}
</Link>
);
},
},
{
id: "validation",
header: "Validasi",
cell: ({ row, table }) => {
const original = row.original;
// const isValid = original.isValid;
const isRelevant = original.isRelevant;
const link = original.link;
const updateRow = (data: Partial<any>) => {
table.options.meta?.updateData(row.index, data);
};
const handleValid = async () => {
try {
await validateMediaLink(original.id, true);
updateRow({
isRelevant: true,
});
table.options.meta?.refetchData?.();
} catch (err: any) {
toast.error(err.message);
}
};
const handleInvalid = async () => {
try {
await validateMediaLink(original.id, false);
updateRow({
isRelevant: false,
});
table.options.meta?.refetchData?.();
} catch (err: any) {
toast.error(err.message);
}
};
if (!link) {
return <span className="text-muted-foreground">-</span>;
}
if (isRelevant === true) {
return (
<Button
size="sm"
className="bg-green-600 hover:bg-green-700"
disabled
>
Relevan
</Button>
);
}
return (
<div className="flex gap-2">
<Button
size="sm"
variant="outline"
onClick={handleValid}
className="flex items-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M18.7 7.2c-.4-.4-1-.4-1.4 0l-7.5 7.5l-3.1-3.1c-.4-.4-1-.4-1.4 0s-.4 1 0 1.4l3.8 3.8c.2.2.4.3.7.3s.5-.1.7-.3l8.2-8.2c.4-.4.4-1 0-1.4"
/>
</svg>
Relevan
</Button>
<Button size="sm" variant="outline" onClick={handleInvalid} className="flex text-center items-center justify-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M6.758 17.243L12.001 12m5.243-5.243L12 12m0 0L6.758 6.757M12.001 12l5.243 5.243"
/>
</svg>
Tidak Relevan
</Button>
</div>
);
},
}, },
]; ];

View File

@ -116,18 +116,6 @@ const NewsDetailTable = () => {
onColumnVisibilityChange: setColumnVisibility, onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection, onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination, onPaginationChange: setPagination,
meta: {
updateData: (rowIndex: number, value: Partial<any>) => {
setDataTable((old) =>
old.map((row, index) =>
index === rowIndex ? { ...row, ...value } : row
)
);
},
refetchData: () => {
fetchData();
},
},
state: { state: {
sorting, sorting,
columnFilters, columnFilters,
@ -166,7 +154,7 @@ const NewsDetailTable = () => {
pageIndex: 0, pageIndex: 0,
pageSize: Number(showData), pageSize: Number(showData),
}); });
}, [page, showData, id]); }, [page, showData]);
async function fetchData() { async function fetchData() {
try { try {

View File

@ -1,15 +1,7 @@
import * as React from "react"; import * as React from "react";
import { ColumnDef } from "@tanstack/react-table"; import { ColumnDef } from "@tanstack/react-table";
import { exportMediaTrackingToExcel } from "@/utils/export-media-tracking";
import { loading, close } from "@/config/swal"; import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
import { error } from "@/lib/swal";
import {
DownloadIcon,
Eye,
MoreVertical,
SquarePen,
Trash2,
} from "lucide-react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { import {
DropdownMenu, DropdownMenu,
@ -53,101 +45,19 @@ const columns: ColumnDef<any>[] = [
cell: ({ row }) => <span>{row.getValue("title")}</span>, cell: ({ row }) => <span>{row.getValue("title")}</span>,
}, },
{ {
accessorKey: "resultTotal", accessorKey: "link",
header: () => <div className="text-center w-full">Total Artikel</div>, header: "Jumlah Amplifikasi",
cell: ({ row }) => { cell: ({ row }) => <span>{row.getValue("link")}</span>,
const value = row.getValue("resultTotal") as number | string | null;
const finalValue =
value === null || value === undefined || value === ""
? 0
: Number(value);
return <div className="text-center w-full">{finalValue}</div>;
},
}, },
{ {
accessorKey: "amplification", accessorKey: "status",
header: () => <div className="text-center w-full">Jumlah Amplifikasi</div>, header: "Status",
cell: ({ row }) => { cell: ({ row }) => <span>{row.getValue("status")}</span>,
const raw = row.getValue("amplification") as string | null;
let total = 0;
let invalidTotal = 0;
if (raw && typeof raw === "string") {
const parts = raw.split("/").map((v) => v.trim());
total = Number(parts[0]) || 0;
invalidTotal = Number(parts[1]) || 0;
}
return (
<div className="text-center w-full font-medium">
{total}
<span className="text-muted-foreground">/{invalidTotal}</span>
</div>
);
},
}, },
// {
// accessorKey: "status",
// header: "Status",
// cell: ({ row }) => <span>{row.getValue("status")}</span>,
// },
// {
// accessorKey: "isProcessing",
// header: () => <div className="text-center">Status</div>,
// cell: ({ row }) => {
// const raw = row.getValue("isProcessing");
// var status = "Sedang Diproses"
// if (Boolean(raw) == true) {
// status = "Selesai Diproses";
// }
// return <div className="text-center">{status}</div>;
// },
// },
{ {
accessorKey: "isProcessing", accessorKey: "date",
header: () => <div className="text-center">Status</div>, header: "Tanggal Penarikan",
cell: ({ row }) => { cell: ({ row }) => <span>{row.getValue("date")}</span>,
const raw = Boolean(row.getValue("isProcessing"));
const statusText = raw ? "Sedang Diproses" : "Sudah Selesai";
const colorClass = raw
? "bg-yellow-100 text-yellow-700 border border-yellow-300"
: "bg-green-100 text-green-700 border border-green-300";
return (
<div className="text-center">
<span
className={`px-2 py-1 rounded text-xs font-medium inline-block ${colorClass}`}
>
{statusText}
</span>
</div>
);
},
},
{
accessorKey: "createdAt",
header: () => <div className="text-center">Tanggal Penarikan</div>,
cell: ({ row }) => {
const raw = row.getValue("createdAt");
if (!raw || typeof raw !== "string")
return <div className="text-center">-</div>;
const date = new Date(raw);
if (isNaN(date.getTime())) return <div className="text-center">-</div>;
const formatted = date.toLocaleDateString("id-ID", {
day: "2-digit",
month: "short",
year: "numeric",
});
return <div className="text-center">{formatted}</div>;
},
}, },
{ {
id: "actions", id: "actions",
@ -168,31 +78,13 @@ const columns: ColumnDef<any>[] = [
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end"> <DropdownMenuContent className="p-0" align="end">
<Link href={`/admin/media-tracking/detail/${row.original.id}`}> <Link href={`/admin/media-tracking/detail/${row.original.id}`}>
<DropdownMenuItem className="p-2 border-b cursor-pointer text-default-700 group focus:bg-default focus:text-primary-foreground items-center rounded-none"> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" /> <Eye className="w-4 h-4 me-1.5" />
View&nbsp; View
{row.original.mediaUpload.fileType.secondaryName && {row.original.mediaUpload.fileType.secondaryName &&
row.original.mediaUpload.fileType.secondaryName.toLowerCase()} row.original.mediaUpload.fileType.secondaryName.toLowerCase()}
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
<DropdownMenuItem
className="p-2 border-b cursor-pointer text-default-700 group rounded-none focus:bg-default focus:text-primary-foreground "
onClick={async () => {
try {
loading();
await exportMediaTrackingToExcel({
mediaTrackingId: row.original.id,
});
close();
} catch (e: any) {
close();
error(e.message || "Gagal export data");
}
}}
>
<DownloadIcon className="w-4 h-4 me-1.5" />
<p>Download</p>
</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
); );

View File

@ -179,11 +179,11 @@ const ResultTable = () => {
setCategoryFilter( setCategoryFilter(
categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]
); );
console.log( // console.log(
"Kategori", // "Kategori",
categorie, // categorie,
categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] // categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]
); // );
} }
}, [categorie]); }, [categorie]);
@ -195,7 +195,7 @@ const ResultTable = () => {
} else { } else {
filter.splice(categoryFilter.indexOf(id), 1); filter.splice(categoryFilter.indexOf(id), 1);
} }
console.log("checkbox filter", filter); // console.log("checkbox filter", filter);
setCategoryFilter(filter); setCategoryFilter(filter);
router.push(`?category=${filter.join("&")}`); router.push(`?category=${filter.join("&")}`);
}; };

View File

@ -151,11 +151,11 @@ const NewsTable = () => {
setCategoryFilter( setCategoryFilter(
categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]
); );
console.log( // console.log(
"Kategori", // "Kategori",
categorie, // categorie,
categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie] // categorie?.split("&")?.length > 1 ? categorie?.split("&") : [categorie]
); // );
} }
}, [categorie]); }, [categorie]);
@ -167,7 +167,7 @@ const NewsTable = () => {
} else { } else {
filter.splice(categoryFilter.indexOf(id), 1); filter.splice(categoryFilter.indexOf(id), 1);
} }
console.log("checkbox filter", filter); // console.log("checkbox filter", filter);
setCategoryFilter(filter); setCategoryFilter(filter);
router.push(`?category=${filter.join("&")}`); router.push(`?category=${filter.join("&")}`);
}; };

View File

@ -32,7 +32,7 @@ export default function TrackingBeritaCard() {
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1); const [totalPage, setTotalPage] = useState(1);
const [showData, setShowData] = useState("6"); const [showData, setShowData] = useState("6");
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
useEffect(() => { useEffect(() => {
initFecth(); initFecth();
@ -40,7 +40,7 @@ export default function TrackingBeritaCard() {
const initFecth = async () => { const initFecth = async () => {
loading(); loading();
const response = await listDataTracking(Number(showData), page - 1, search); const response = await listDataTracking(showData, page - 1);
const data = response?.data?.data; const data = response?.data?.data;
const newData = data?.content; const newData = data?.content;
setTotalPage(data?.totalPages || 1); setTotalPage(data?.totalPages || 1);
@ -56,85 +56,23 @@ export default function TrackingBeritaCard() {
setContent(response?.data?.data?.content || []); setContent(response?.data?.data?.content || []);
}; };
const handleInputChange = async (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value; const value = e.target.value;
setSearch(value); setSearch(value);
const response = await listDataTracking(Number(showData), 0, value); if (value.trim() === "") {
setContent(response?.data?.data?.content || []); initFecth();
} else {
fecthAll(value);
}
}; };
// const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// const value = e.target.value;
// setSearch(value);
// if (value.trim() === "") {
// initFecth();
// } else {
// fecthAll(value);
// }
// };
const handleSelect = (id: number) => { const handleSelect = (id: number) => {
setSelectedItems((prev) => setSelectedItems((prev) =>
prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id] prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
); );
}; };
const doSave = async () => {
if (selectedItems.length === 0) {
MySwal.fire(
"Peringatan",
"Pilih minimal 1 berita untuk disimpan.",
"warning"
);
return;
}
try {
loading();
const promises = selectedItems.map(async (id) => {
const res = await mediaTrackingSave({
mediaUploadId: id,
duration: 24,
scrapingPeriod: 3,
});
// cek pesan API
if (!res?.data?.success) {
throw new Error(
res?.data?.message ||
"Limit media tracking per hari sudah tercapai. Maksimal 5 tracking per hari."
);
}
return res;
});
await Promise.all(promises);
close();
await MySwal.fire({
icon: "success",
title: "Berhasil!",
text: "Tracking berita berhasil ditambahkan.",
confirmButtonColor: "#2563eb",
});
setSelectedItems([]);
initFecth();
} catch (err: any) {
close();
MySwal.fire({
icon: "error",
title: "Gagal!",
text: err?.message || "Terjadi kesalahan saat menyimpan data.",
confirmButtonColor: "#dc2626",
});
}
};
// const doSave = async () => { // const doSave = async () => {
// if (selectedItems.length === 0) { // if (selectedItems.length === 0) {
// toast("Pilih minimal 1 berita untuk disimpan."); // toast("Pilih minimal 1 berita untuk disimpan.");
@ -161,63 +99,48 @@ export default function TrackingBeritaCard() {
// } // }
// }; // };
// const doSave = async () => { const doSave = async () => {
// if (selectedItems.length === 0) { if (selectedItems.length === 0) {
// MySwal.fire( MySwal.fire(
// "Peringatan", "Peringatan",
// "Pilih minimal 1 berita untuk disimpan.", "Pilih minimal 1 berita untuk disimpan.",
// "warning" "warning"
// ); );
// return; return;
// } }
// try { try {
// loading(); loading();
// const promises = selectedItems.map((id) => const promises = selectedItems.map((id) =>
// mediaTrackingSave({ mediaTrackingSave({
// mediaUploadId: id, mediaUploadId: id,
// duration: 24, duration: 24,
// scrapingPeriod: 3, scrapingPeriod: 3,
// }) })
// ); );
// await Promise.all(promises); await Promise.all(promises);
// close(); close();
// await MySwal.fire({ await MySwal.fire({
// icon: "success", icon: "success",
// title: "Berhasil!", title: "Berhasil!",
// text: "Tracking berita berhasil ditambahkan.", text: "Tracking berita berhasil ditambahkan.",
// confirmButtonColor: "#2563eb", confirmButtonColor: "#2563eb",
// }); });
// setSelectedItems([]); setSelectedItems([]);
// initFecth(); initFecth();
// } catch (err: any) { } catch (err: any) {
// close(); close();
// MySwal.fire({ MySwal.fire({
// icon: "error", icon: "error",
// title: "Gagal!", title: "Gagal!",
// text: err?.message || "Terjadi kesalahan saat menyimpan data.", text: err?.message || "Terjadi kesalahan saat menyimpan data.",
// confirmButtonColor: "#dc2626", confirmButtonColor: "#dc2626",
// }); });
// } }
// };
const slugify = (text: string) => {
return text
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/(^-|-$)+/g, "");
};
const goToDetail = (item: any) => {
const type = item.type || "image";
const slug = slugify(item.title || "");
const url = `/in/${type}/detail/${item.id}-${slug}`;
window.location.href = url;
}; };
return ( return (
@ -265,7 +188,7 @@ export default function TrackingBeritaCard() {
<div className="text-sm text-blue-600 font-medium"> <div className="text-sm text-blue-600 font-medium">
{selectedItems.length} Item Terpilih{" "} {selectedItems.length} Item Terpilih{" "}
<span className="text-black"> <span className="text-black">
/ Tracking Berita tersisa {5 - selectedItems.length} / Tracking Berita tersisa {29 - selectedItems.length}
</span> </span>
</div> </div>
<Button className="bg-blue-600 text-white" onClick={doSave}> <Button className="bg-blue-600 text-white" onClick={doSave}>
@ -275,48 +198,6 @@ export default function TrackingBeritaCard() {
)} )}
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
{content?.length > 0 &&
content.map((item: any) => (
<Card
key={item.id}
className="relative overflow-hidden shadow-sm border rounded-lg"
>
{/* KLIK GAMBAR = CHECKLIST */}
<div
className="cursor-pointer"
onClick={() => handleSelect(item.id)}
>
<img
src={item.thumbnailLink}
alt={item.title}
className="w-full h-[300px] object-cover"
/>
{/* CHECKBOX */}
<div className="absolute top-2 left-2">
<div className="w-5 h-5 border-2 border-white bg-white rounded-sm flex items-center justify-center">
{selectedItems.includes(item.id) && (
<div className="w-3 h-3 bg-blue-600 rounded-sm" />
)}
</div>
</div>
</div>
{/* KLIK JUDUL = DETAIL */}
<p
className="p-2 text-sm font-medium hover:underline cursor-pointer"
onClick={(e) => {
e.stopPropagation();
goToDetail(item);
}}
>
{item.title}
</p>
</Card>
))}
</div>
{/* <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
{content?.length > 1 && {content?.length > 1 &&
content.map((item: any) => ( content.map((item: any) => (
<Card <Card
@ -341,7 +222,7 @@ export default function TrackingBeritaCard() {
</p> </p>
</Card> </Card>
))} ))}
</div> */} </div>
<div className="mt-3"> <div className="mt-3">
{content && content?.length > 0 ? ( {content && content?.length > 0 ? (
<CustomPagination <CustomPagination

View File

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

View File

@ -97,7 +97,7 @@ const BannerListTable = () => {
const response = await listBanner(); 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);
close(); close();

View File

@ -176,7 +176,7 @@ const ContentListBanner = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setData(contentData); setData(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -88,7 +88,7 @@ const columns: ColumnDef<any>[] = [
const categoryDelete = async (id: number) => { const categoryDelete = async (id: number) => {
const response = await deleteCategory(id); const response = await deleteCategory(id);
console.log(response); // console.log(response);
if (response?.error) { if (response?.error) {
error(response.message); error(response.message);
return false; return false;

View File

@ -68,7 +68,7 @@ const columns: ColumnDef<any>[] = [
const faqDelete = async (id: string) => { const faqDelete = async (id: string) => {
const response = await deleteDataFAQ(id); const response = await deleteDataFAQ(id);
console.log(response); // console.log(response);
if (response?.error) { if (response?.error) {
error(response.message); error(response.message);
return false; return false;

View File

@ -110,7 +110,7 @@ const AdminFAQTable = () => {
loading(); loading();
const response = await getListFAQ(); const response = await getListFAQ();
const data = response?.data?.data; const data = response?.data?.data;
console.log("respone", response); // console.log("respone", response);
data.forEach((item: any, index: number) => { data.forEach((item: any, index: number) => {
item.no = (page - 1) * 10 + index + 1; item.no = (page - 1) * 10 + index + 1;
}); });

View File

@ -69,7 +69,7 @@ const columns: ColumnDef<any>[] = [
const faqDelete = async (id: string) => { const faqDelete = async (id: string) => {
const response = await deleteDataFAQ(id); const response = await deleteDataFAQ(id);
console.log(response); // console.log(response);
if (response?.error) { if (response?.error) {
error(response.message); error(response.message);
return false; return false;

View File

@ -109,7 +109,7 @@ const AdminFeedbackTable = () => {
loading(); loading();
const response = await getListFeedback(); const response = await getListFeedback();
const data = response?.data?.data; const data = response?.data?.data;
console.log("respone", response); // console.log("respone", response);
data.forEach((item: any, index: number) => { data.forEach((item: any, index: number) => {
item.no = (page - 1) * 10 + index + 1; item.no = (page - 1) * 10 + index + 1;
}); });

View File

@ -97,7 +97,7 @@ const IklanListTable = () => {
const response = await listBanner(); 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);
close(); close();

View File

@ -160,7 +160,7 @@ const AdvertisementsList = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -100,7 +100,7 @@ const PopUpListTable = () => {
const response = await getListPopUp(); const response = await getListPopUp();
const data = response?.data?.data?.content; const data = response?.data?.data?.content;
console.log("banner", data); // console.log("banner", data);
setGetData(data); setGetData(data);
close(); close();

View File

@ -178,7 +178,7 @@ const ContentListPopUp = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setData(contentData); setData(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -64,7 +64,7 @@ export default function DetailSettingTracking(props: {
}); });
const onSubmit = (values: any) => { const onSubmit = (values: any) => {
console.log("Submitted values:", values); // console.log("Submitted values:", values);
setIsOpen(false); setIsOpen(false);
}; };

View File

@ -64,7 +64,7 @@ export default function UpdateSettingTracking(props: {
}); });
const onSubmit = (values: any) => { const onSubmit = (values: any) => {
console.log("Submitted values:", values); // console.log("Submitted values:", values);
setIsOpen(false); setIsOpen(false);
}; };

View File

@ -72,7 +72,7 @@ export default function CreateTagModal() {
categoryId: Number(data.category), categoryId: Number(data.category),
isActive: true, isActive: true,
}; };
console.log("reqqq", request); // console.log("reqqq", request);
// const response = await postDataFeedback(request); // const response = await postDataFeedback(request);
// close(); // close();
// if (response?.error) { // if (response?.error) {
@ -93,7 +93,7 @@ export default function CreateTagModal() {
async function getCategoryParent() { async function getCategoryParent() {
const response = await getCategoriesAll(); const response = await getCategoriesAll();
const res = response?.data?.data.content; const res = response?.data?.data.content;
console.log("res", res); // console.log("res", res);
var levelsArr: { id: number; label: string; value: string }[] = []; var levelsArr: { id: number; label: string; value: string }[] = [];
res.forEach((levels: { id: number; name: string }) => { res.forEach((levels: { id: number; name: string }) => {
levelsArr.push({ levelsArr.push({

View File

@ -145,7 +145,7 @@ export default function EditTagModal(props: {
async function getCategoryParent() { async function getCategoryParent() {
const response = await getCategoriesAll(); const response = await getCategoriesAll();
const res = response?.data?.data.content; const res = response?.data?.data.content;
console.log("res", res); // console.log("res", res);
var levelsArr: { id: number; label: string; value: string }[] = []; var levelsArr: { id: number; label: string; value: string }[] = [];
res.forEach((levels: { id: number; name: string }) => { res.forEach((levels: { id: number; name: string }) => {
levelsArr.push({ levelsArr.push({

View File

@ -173,7 +173,7 @@ const SurveyListTable = () => {
item.no = (page - 1) * 10 + index + 1; item.no = (page - 1) * 10 + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -178,7 +178,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => {
}, },
})); }));
console.log("Event Data : ", events); // console.log("Event Data : ", events);
setCalendarEvents(events); setCalendarEvents(events);
} }
} catch (err) { } catch (err) {
@ -217,7 +217,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => {
const filteredEvents = calendarEvents.filter((event) => { const filteredEvents = calendarEvents.filter((event) => {
if (!selectedCategory.length) return false; if (!selectedCategory.length) return false;
console.log("Event category : ", selectedCategory); // console.log("Event category : ", selectedCategory);
const eventCategories = event.extendedProps.calendar const eventCategories = event.extendedProps.calendar
?.split(",") ?.split(",")

View File

@ -109,9 +109,7 @@ const EventModal = ({
const pathname = usePathname(); const pathname = usePathname();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [checkedLevels, setCheckedLevels] = useState<Set<number>>(new Set()); const [checkedLevels, setCheckedLevels] = useState<Set<number>>(new Set());
const [expandedPolda, setExpandedPolda] = useState<Record<number, boolean>>( const [expandedPolda, setExpandedPolda] = useState<Record<number, boolean>>({});
{}
);
const [audioFile, setAudioFile] = useState<File | null>(null); const [audioFile, setAudioFile] = useState<File | null>(null);
const [isRecording, setIsRecording] = useState(false); const [isRecording, setIsRecording] = useState(false);
const [timer, setTimer] = useState<number>(120); const [timer, setTimer] = useState<number>(120);
@ -155,11 +153,9 @@ const EventModal = ({
}); });
// State untuk melacak apakah perubahan berasal dari checkbox Jenis Agenda // State untuk melacak apakah perubahan berasal dari checkbox Jenis Agenda
const [isUpdatingFromJenisAgenda, setIsUpdatingFromJenisAgenda] = const [isUpdatingFromJenisAgenda, setIsUpdatingFromJenisAgenda] = useState(false);
useState(false);
// State untuk melacak jenis perubahan spesifik // State untuk melacak jenis perubahan spesifik
const [jenisAgendaChangeType, setJenisAgendaChangeType] = const [jenisAgendaChangeType, setJenisAgendaChangeType] = useState<string>("");
useState<string>("");
const levelNumber = Number(getCookiesDecrypt("ulne")) || 0; const levelNumber = Number(getCookiesDecrypt("ulne")) || 0;
const userLevelId = getCookiesDecrypt("ulie"); const userLevelId = getCookiesDecrypt("ulie");
@ -265,11 +261,7 @@ const EventModal = ({
// useEffect untuk sinkronisasi checkbox modal dengan Jenis Agenda // useEffect untuk sinkronisasi checkbox modal dengan Jenis Agenda
useEffect(() => { useEffect(() => {
if ( if (listDest.length > 0 && isUpdatingFromJenisAgenda && jenisAgendaChangeType) {
listDest.length > 0 &&
isUpdatingFromJenisAgenda &&
jenisAgendaChangeType
) {
syncModalWithJenisAgenda(); syncModalWithJenisAgenda();
} }
}, [isUpdatingFromJenisAgenda, jenisAgendaChangeType]); }, [isUpdatingFromJenisAgenda, jenisAgendaChangeType]);
@ -281,55 +273,44 @@ const EventModal = ({
} }
}, [checkedLevels, isUpdatingFromJenisAgenda]); }, [checkedLevels, isUpdatingFromJenisAgenda]);
// Fungsi untuk update wilayahPublish berdasarkan checkbox modal // Fungsi untuk update wilayahPublish berdasarkan checkbox modal
const updateWilayahPublishFromModal = () => { const updateWilayahPublishFromModal = () => {
// Hanya update jika tidak sedang dalam proses update dari Jenis Agenda // Hanya update jika tidak sedang dalam proses update dari Jenis Agenda
if (!isUpdatingFromJenisAgenda && listDest.length > 0) { if (!isUpdatingFromJenisAgenda && listDest.length > 0) {
// Hitung item yang dipilih berdasarkan checkedLevels // Hitung item yang dipilih berdasarkan checkedLevels
const checkedPoldaCount = listDest.filter( const checkedPoldaCount = listDest.filter((item: any) =>
(item: any) => item.levelNumber === 2 &&
item.levelNumber === 2 && item.name !== "SATKER POLRI" &&
item.name !== "SATKER POLRI" && checkedLevels.has(Number(item.id))
checkedLevels.has(Number(item.id))
).length; ).length;
const checkedPolresCount = listDest.reduce((total: number, item: any) => { const checkedPolresCount = listDest.reduce((total: number, item: any) => {
if (item.subDestination) { if (item.subDestination) {
return ( return total + item.subDestination.filter((sub: any) => checkedLevels.has(Number(sub.id))).length;
total +
item.subDestination.filter((sub: any) =>
checkedLevels.has(Number(sub.id))
).length
);
} }
return total; return total;
}, 0); }, 0);
const satkerItem: any = listDest.find( const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
(item: any) => item.name === "SATKER POLRI" const checkedSatkerCount = satkerItem ? (
); (checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) +
const checkedSatkerCount = satkerItem (satkerItem.subDestination?.filter((sub: any) => checkedLevels.has(Number(sub.id))).length || 0)
? (checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) + ) : 0;
(satkerItem.subDestination?.filter((sub: any) =>
checkedLevels.has(Number(sub.id))
).length || 0)
: 0;
// Checkbox aktif jika ADA item yang dipilih dalam kategori tersebut // Checkbox aktif jika ADA item yang dipilih dalam kategori tersebut
const hasSelectedPolda = checkedPoldaCount > 0; const hasSelectedPolda = checkedPoldaCount > 0;
const hasSelectedPolres = checkedPolresCount > 0; const hasSelectedPolres = checkedPolresCount > 0;
const hasSelectedSatker = checkedSatkerCount > 0; const hasSelectedSatker = checkedSatkerCount > 0;
// Update arrays untuk backend // Update arrays untuk backend
const newSelectedPolda = listDest const newSelectedPolda = listDest
.filter( .filter((item: any) =>
(item: any) => item.levelNumber === 2 &&
item.levelNumber === 2 && item.name !== "SATKER POLRI" &&
item.name !== "SATKER POLRI" && checkedLevels.has(Number(item.id))
checkedLevels.has(Number(item.id))
) )
.map((item: any) => String(item.id)); .map((item: any) => String(item.id));
const newSelectedPolres: string[] = []; const newSelectedPolres: string[] = [];
listDest.forEach((item: any) => { listDest.forEach((item: any) => {
if (item.subDestination) { if (item.subDestination) {
@ -340,7 +321,7 @@ const EventModal = ({
}); });
} }
}); });
const newSelectedSatker: string[] = []; const newSelectedSatker: string[] = [];
if (satkerItem) { if (satkerItem) {
if (checkedLevels.has(Number(satkerItem.id))) { if (checkedLevels.has(Number(satkerItem.id))) {
@ -354,56 +335,51 @@ const EventModal = ({
}); });
} }
} }
// Update state arrays // Update state arrays
setSelectedPolda(newSelectedPolda); setSelectedPolda(newSelectedPolda);
setSelectedPolres(newSelectedPolres); setSelectedPolres(newSelectedPolres);
setSelectedSatker(newSelectedSatker); setSelectedSatker(newSelectedSatker);
// Update wilayahPublish berdasarkan yang dipilih di modal // Update wilayahPublish berdasarkan yang dipilih di modal
setWilayahPublish((prev) => { setWilayahPublish(prev => {
const newState = { ...prev }; const newState = { ...prev };
// Update individual checkboxes // Update individual checkboxes
newState.polda = hasSelectedPolda; newState.polda = hasSelectedPolda;
newState.polres = hasSelectedPolres; newState.polres = hasSelectedPolres;
newState.satker = hasSelectedSatker; newState.satker = hasSelectedSatker;
// Update checkbox "semua" berdasarkan level user // Update checkbox "semua" berdasarkan level user
if (levelNumber === 1) { if (levelNumber === 1) {
// Level 1: semua checkbox harus aktif (nasional, polda, polres, satker, international) // Level 1: semua checkbox harus aktif (nasional, polda, polres, satker, international)
newState.semua = newState.semua = newState.nasional && hasSelectedPolda && hasSelectedPolres && hasSelectedSatker && newState.international;
newState.nasional &&
hasSelectedPolda &&
hasSelectedPolres &&
hasSelectedSatker &&
newState.international;
} else if (levelNumber === 2) { } else if (levelNumber === 2) {
// Level 2: hanya polres yang perlu aktif // Level 2: hanya polres yang perlu aktif
newState.semua = hasSelectedPolres; newState.semua = hasSelectedPolres;
} else { } else {
newState.semua = false; newState.semua = false;
} }
return newState; return newState;
}); });
// Update agendaType berdasarkan checkbox yang aktif // Update agendaType berdasarkan checkbox yang aktif
const selectedKeys = []; const selectedKeys = [];
if (hasSelectedPolda) selectedKeys.push(wilayahValueMap.polda); if (hasSelectedPolda) selectedKeys.push(wilayahValueMap.polda);
if (hasSelectedPolres) selectedKeys.push(wilayahValueMap.polres); if (hasSelectedPolres) selectedKeys.push(wilayahValueMap.polres);
if (hasSelectedSatker) selectedKeys.push(wilayahValueMap.satker); if (hasSelectedSatker) selectedKeys.push(wilayahValueMap.satker);
setAgendaType(selectedKeys.join(",")); setAgendaType(selectedKeys.join(","));
} }
}; };
// Fungsi untuk sinkronisasi checkbox modal dengan Jenis Agenda // Fungsi untuk sinkronisasi checkbox modal dengan Jenis Agenda
const syncModalWithJenisAgenda = () => { const syncModalWithJenisAgenda = () => {
// Hanya jalankan sinkronisasi jika perubahan berasal dari checkbox Jenis Agenda // Hanya jalankan sinkronisasi jika perubahan berasal dari checkbox Jenis Agenda
if (isUpdatingFromJenisAgenda) { if (isUpdatingFromJenisAgenda) {
const newCheckedLevels = new Set(checkedLevels); const newCheckedLevels = new Set(checkedLevels);
// Handle checklist actions - menambahkan semua item ke modal // Handle checklist actions - menambahkan semua item ke modal
if (jenisAgendaChangeType === "polda_checked") { if (jenisAgendaChangeType === "polda_checked") {
// Checklist semua polda // Checklist semua polda
@ -415,11 +391,7 @@ const EventModal = ({
} else if (jenisAgendaChangeType === "polres_checked") { } else if (jenisAgendaChangeType === "polres_checked") {
// Checklist semua polres, tapi hanya yang poldanya sudah di-checklist // Checklist semua polres, tapi hanya yang poldanya sudah di-checklist
listDest.forEach((item: any) => { listDest.forEach((item: any) => {
if ( if (item.levelNumber === 2 && item.name !== "SATKER POLRI" && newCheckedLevels.has(Number(item.id))) {
item.levelNumber === 2 &&
item.name !== "SATKER POLRI" &&
newCheckedLevels.has(Number(item.id))
) {
if (item.subDestination) { if (item.subDestination) {
item.subDestination.forEach((polres: any) => { item.subDestination.forEach((polres: any) => {
newCheckedLevels.add(Number(polres.id)); newCheckedLevels.add(Number(polres.id));
@ -429,9 +401,7 @@ const EventModal = ({
}); });
} else if (jenisAgendaChangeType === "satker_checked") { } else if (jenisAgendaChangeType === "satker_checked") {
// Checklist satker // Checklist satker
const satkerItem: any = listDest.find( const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
(item: any) => item.name === "SATKER POLRI"
);
if (satkerItem) { if (satkerItem) {
newCheckedLevels.add(Number(satkerItem.id)); newCheckedLevels.add(Number(satkerItem.id));
if (satkerItem.subDestination) { if (satkerItem.subDestination) {
@ -464,12 +434,10 @@ const EventModal = ({
} }
} }
}); });
setWilayahPublish((prev) => ({ ...prev, polres: false })); setWilayahPublish(prev => ({ ...prev, polres: false }));
} else if (jenisAgendaChangeType === "satker_unchecked") { } else if (jenisAgendaChangeType === "satker_unchecked") {
// Clear satker dari checkedLevels // Clear satker dari checkedLevels
const satkerItem: any = listDest.find( const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
(item: any) => item.name === "SATKER POLRI"
);
if (satkerItem) { if (satkerItem) {
newCheckedLevels.delete(Number(satkerItem.id)); newCheckedLevels.delete(Number(satkerItem.id));
if (satkerItem.subDestination) { if (satkerItem.subDestination) {
@ -479,9 +447,9 @@ const EventModal = ({
} }
} }
} }
setCheckedLevels(newCheckedLevels); setCheckedLevels(newCheckedLevels);
// Reset flag setelah sinkronisasi selesai // Reset flag setelah sinkronisasi selesai
setIsUpdatingFromJenisAgenda(false); setIsUpdatingFromJenisAgenda(false);
setJenisAgendaChangeType(""); setJenisAgendaChangeType("");
@ -516,14 +484,12 @@ const EventModal = ({
setCheckedLevels((prev) => { setCheckedLevels((prev) => {
const updatedLevels = new Set(prev); const updatedLevels = new Set(prev);
const isCurrentlyChecked = updatedLevels.has(levelId); const isCurrentlyChecked = updatedLevels.has(levelId);
if (isCurrentlyChecked) { if (isCurrentlyChecked) {
updatedLevels.delete(levelId); updatedLevels.delete(levelId);
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya // Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
const poldaItem = listDest.find( const poldaItem = listDest.find((item: any) => Number(item.id) === levelId) as any;
(item: any) => Number(item.id) === levelId
) as any;
if (poldaItem && poldaItem.subDestination) { if (poldaItem && poldaItem.subDestination) {
poldaItem.subDestination.forEach((polres: any) => { poldaItem.subDestination.forEach((polres: any) => {
updatedLevels.delete(Number(polres.id)); updatedLevels.delete(Number(polres.id));
@ -548,12 +514,7 @@ const EventModal = ({
const toggleWilayah = (key: string) => { const toggleWilayah = (key: string) => {
// Set flag bahwa perubahan berasal dari checkbox Jenis Agenda // Set flag bahwa perubahan berasal dari checkbox Jenis Agenda
setIsUpdatingFromJenisAgenda(true); setIsUpdatingFromJenisAgenda(true);
setJenisAgendaChangeType( setJenisAgendaChangeType(key + (wilayahPublish[key as keyof typeof wilayahPublish] ? "_unchecked" : "_checked"));
key +
(wilayahPublish[key as keyof typeof wilayahPublish]
? "_unchecked"
: "_checked")
);
setWilayahPublish((prev: any) => { setWilayahPublish((prev: any) => {
let newState = { ...prev }; let newState = { ...prev };
@ -590,21 +551,18 @@ const EventModal = ({
return newState; return newState;
} }
// Validasi khusus untuk POLRES // Validasi khusus untuk POLRES
if (key === "polres" && !prev[key]) { if (key === "polres" && !prev[key]) {
// Cek apakah ada POLDA yang sudah dipilih di modal // Cek apakah ada POLDA yang sudah dipilih di modal
const hasSelectedPolda = listDest.some( const hasSelectedPolda = listDest.some((item: any) =>
(item: any) => item.levelNumber === 2 &&
item.levelNumber === 2 && item.name !== "SATKER POLRI" &&
item.name !== "SATKER POLRI" && checkedLevels.has(Number(item.id))
checkedLevels.has(Number(item.id))
); );
if (!hasSelectedPolda) { if (!hasSelectedPolda) {
// Jika tidak ada POLDA yang dipilih, tampilkan peringatan dan batalkan // Jika tidak ada POLDA yang dipilih, tampilkan peringatan dan batalkan
alert( alert("Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.");
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
);
// Reset flag karena perubahan dibatalkan // Reset flag karena perubahan dibatalkan
setIsUpdatingFromJenisAgenda(false); setIsUpdatingFromJenisAgenda(false);
setJenisAgendaChangeType(""); setJenisAgendaChangeType("");
@ -640,9 +598,7 @@ const EventModal = ({
}); });
} else if (key === "satker") { } else if (key === "satker") {
// Clear satker // Clear satker
const satkerItem: any = listDest.find( const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
(item: any) => item.name === "SATKER POLRI"
);
if (satkerItem) { if (satkerItem) {
newCheckedLevels.delete(Number(satkerItem.id)); newCheckedLevels.delete(Number(satkerItem.id));
if (satkerItem.subDestination) { if (satkerItem.subDestination) {
@ -657,14 +613,9 @@ const EventModal = ({
// Update checkbox "semua" berdasarkan status semua checkbox lainnya // Update checkbox "semua" berdasarkan status semua checkbox lainnya
// Untuk level 1: semua, nasional, polda, polres, satker, international harus aktif // Untuk level 1: semua, nasional, polda, polres, satker, international harus aktif
// Untuk level 2: semua, polres harus aktif // Untuk level 2: semua, polres harus aktif
if (levelNumber === 1) { if (levelNumber === 1) {
newState.semua = newState.semua = newState.nasional && newState.polda && newState.polres && newState.satker && newState.international;
newState.nasional &&
newState.polda &&
newState.polres &&
newState.satker &&
newState.international;
} else if (levelNumber === 2) { } else if (levelNumber === 2) {
newState.semua = newState.polres; newState.semua = newState.polres;
} else { } else {
@ -726,7 +677,7 @@ const EventModal = ({
endDate: date?.to ? format(date.to, "yyyy-MM-dd") : null, endDate: date?.to ? format(date.to, "yyyy-MM-dd") : null,
}; };
console.log("Submitted Data:", reqData); // console.log("Submitted Data:", reqData);
const response = await saveAgendaSettings(reqData); const response = await saveAgendaSettings(reqData);
if (response?.error) { if (response?.error) {
@ -794,9 +745,6 @@ const EventModal = ({
}; };
useEffect(() => { useEffect(() => {
console.log("Event data:", event);
console.log("Selected date:", selectedDate);
if (selectedDate) { if (selectedDate) {
setDate({ setDate({
from: selectedDate.date, from: selectedDate.date,
@ -819,7 +767,7 @@ const EventModal = ({
const onDeleteEventAction = async () => { const onDeleteEventAction = async () => {
try { try {
} catch (error) {} } catch (error) { }
}; };
const handleOpenDeleteModal = (eventId: string) => { const handleOpenDeleteModal = (eventId: string) => {
@ -829,7 +777,7 @@ const EventModal = ({
}; };
const toggleExpand = (poldaId: any) => { const toggleExpand = (poldaId: any) => {
console.log("Toogle : ", expandedPolda); // console.log("Toogle : ", expandedPolda);
setExpandedPolda((prev: any) => ({ setExpandedPolda((prev: any) => ({
...prev, ...prev,
[poldaId]: !prev[poldaId], [poldaId]: !prev[poldaId],
@ -890,10 +838,11 @@ const EventModal = ({
fileTypeId: string, fileTypeId: string,
duration: string duration: string
) { ) {
console.log(idx, id, file, fileTypeId, duration); // console.log(idx, id, file, fileTypeId, duration);
const resCsrf = await getCsrfToken(); const resCsrf = await getCsrfToken();
const csrfToken = resCsrf?.data?.token; const csrfToken = resCsrf?.data?.token;
// console.log("CSRF TOKEN : ", csrfToken);
const headers = { const headers = {
"X-XSRF-TOKEN": csrfToken, "X-XSRF-TOKEN": csrfToken,
}; };
@ -915,7 +864,7 @@ const EventModal = ({
xhr.withCredentials = true; xhr.withCredentials = true;
}, },
onError: async (e: any) => { onError: async (e: any) => {
console.log("Error upload :", e); // console.log("Error upload :", e);
error(e); error(e);
}, },
onChunkComplete: ( onChunkComplete: (
@ -998,7 +947,7 @@ const EventModal = ({
); );
}; };
const handleRemoveFile = (id: number) => {}; const handleRemoveFile = (id: number) => { };
async function doDelete(id: any) { async function doDelete(id: any) {
loading(); loading();
@ -1037,7 +986,7 @@ const EventModal = ({
}).then(() => { }).then(() => {
if (redirect === window.location.pathname) { if (redirect === window.location.pathname) {
fetch(redirect, { method: "GET", cache: "reload" }).then(() => { fetch(redirect, { method: "GET", cache: "reload" }).then(() => {
console.log("Data diperbarui."); // console.log("Data diperbarui.");
}); });
} else { } else {
window.location.href = redirect; window.location.href = redirect;
@ -1139,7 +1088,7 @@ const EventModal = ({
defaultMonth={date?.from} defaultMonth={date?.from}
selected={date} selected={date}
onSelect={(newDate) => { onSelect={(newDate) => {
console.log("Date selected:", newDate); // console.log("Date selected:", newDate);
setDate(newDate); setDate(newDate);
if (newDate?.from && newDate?.to) { if (newDate?.from && newDate?.to) {
setIsDatePickerOpen(false); setIsDatePickerOpen(false);
@ -1154,42 +1103,40 @@ const EventModal = ({
<div className="space-y-1.5"> <div className="space-y-1.5">
<Label htmlFor="wilayahPublish">Jenis Agenda</Label> <Label htmlFor="wilayahPublish">Jenis Agenda</Label>
<div className="flex flex-wrap items-center gap-2"> <div className="flex flex-wrap items-center gap-2">
<div>
<Checkbox <div>
id="semua" <Checkbox
checked={wilayahPublish.semua} id="semua"
onCheckedChange={() => toggleWilayah("semua")} checked={wilayahPublish.semua}
/> onCheckedChange={() => toggleWilayah("semua")}
<label htmlFor="semua" className="ml-2 text-sm"> />
Semua <label htmlFor="semua" className="ml-2 text-sm">
</label> Semua
</div> </label>
</div>
{levelNumber === 1 && ( {levelNumber === 1 && (
<> <>
<div> <div>
<Checkbox <Checkbox
id="nasional" id="nasional"
checked={wilayahPublish.nasional} checked={wilayahPublish.nasional}
onCheckedChange={() => toggleWilayah("nasional")} onCheckedChange={() => toggleWilayah("nasional")}
/> />
<label <label htmlFor="nasional" className="ml-2 text-sm mr-2">
htmlFor="nasional" Nasional
className="ml-2 text-sm mr-2" </label>
> </div>
Nasional <div>
</label> <Checkbox
</div> id="polda"
<div> checked={wilayahPublish.polda}
<Checkbox onCheckedChange={() => toggleWilayah("polda")}
id="polda" />
checked={wilayahPublish.polda} <label htmlFor="polda" className="mx-2 text-sm mr-2">
onCheckedChange={() => toggleWilayah("polda")} Polda
/> </label>
<label htmlFor="polda" className="mx-2 text-sm mr-2"> </div>
Polda
</label>
</div>
</> </>
)} )}
@ -1201,41 +1148,39 @@ const EventModal = ({
onCheckedChange={() => toggleWilayah("polres")} onCheckedChange={() => toggleWilayah("polres")}
/> />
<label htmlFor="polres" className="ml-2 text-sm mr-2"> <label htmlFor="polres" className="ml-2 text-sm mr-2">
Polres Polres
</label> </label>
</div> </div>
)} )}
{levelNumber === 1 && ( {levelNumber === 1 && (
<> <>
<div> <div>
<Checkbox <Checkbox
id="satker" id="satker"
checked={wilayahPublish.satker} checked={wilayahPublish.satker}
onCheckedChange={() => toggleWilayah("satker")} onCheckedChange={() => toggleWilayah("satker")}
/> />
<label htmlFor="satker" className="mx-2 text-sm mr-2"> <label htmlFor="satker" className="mx-2 text-sm mr-2">
Satker Satker
</label> </label>
</div> </div>
<div> <div>
<Checkbox <Checkbox
id="international" id="international"
checked={wilayahPublish.international} checked={wilayahPublish.international}
onCheckedChange={() => onCheckedChange={() => toggleWilayah("international")}
toggleWilayah("international") />
} <label
/> htmlFor="international"
<label className="ml-2 text-sm mr-2"
htmlFor="international" >
className="ml-2 text-sm mr-2" Internasional
> </label>
Internasional </div>
</label>
</div>
</> </>
)} )}
<div className="pl-1"> <div className="pl-1">
<Dialog> <Dialog>
<DialogTrigger asChild> <DialogTrigger asChild>
@ -1254,9 +1199,7 @@ const EventModal = ({
<div key={polda.id} className="border p-2"> <div key={polda.id} className="border p-2">
<Label className="flex items-center"> <Label className="flex items-center">
<Checkbox <Checkbox
checked={checkedLevels.has( checked={checkedLevels.has(Number(polda.id))}
Number(polda.id)
)}
onCheckedChange={() => onCheckedChange={() =>
handleCheckboxChange(Number(polda.id)) handleCheckboxChange(Number(polda.id))
} }
@ -1294,13 +1237,9 @@ const EventModal = ({
polda?.subDestination?.forEach( polda?.subDestination?.forEach(
(polres: any) => { (polres: any) => {
if (isChecked) { if (isChecked) {
updatedLevels.add( updatedLevels.add(Number(polres.id));
Number(polres.id)
);
} else { } else {
updatedLevels.delete( updatedLevels.delete(Number(polres.id));
Number(polres.id)
);
} }
} }
); );
@ -1310,27 +1249,18 @@ const EventModal = ({
/> />
Pilih Semua Pilih Semua
</Label> </Label>
{polda?.subDestination?.map( {polda?.subDestination?.map((polres: any) => (
(polres: any) => ( <Label key={polres.id} className="block mt-1">
<Label <Checkbox
key={polres.id} checked={checkedLevels.has(Number(polres.id))}
className="block mt-1" onCheckedChange={() =>
> handleCheckboxChange(Number(polres.id))
<Checkbox }
checked={checkedLevels.has( className="mr-2"
Number(polres.id) />
)} {polres.name}
onCheckedChange={() => </Label>
handleCheckboxChange( ))}
Number(polres.id)
)
}
className="mr-2"
/>
{polres.name}
</Label>
)
)}
</div> </div>
)} )}
</div> </div>
@ -1371,7 +1301,8 @@ const EventModal = ({
<Label>Video</Label> <Label>Video</Label>
<FileUploader <FileUploader
accept={{ accept={{
"video/*": [], "mp4/*": [],
"mov/*": [],
}} }}
maxSize={100} maxSize={100}
label="Upload file dengan format .mp4 atau .mov." label="Upload file dengan format .mp4 atau .mov."
@ -1383,7 +1314,7 @@ const EventModal = ({
className="object-fill h-full w-full rounded-md" className="object-fill h-full w-full rounded-md"
src={file.url} src={file.url}
controls controls
title={`Video ${file.id}`} title={`Video ${file.id}`} // Mengganti alt dengan title
/> />
<div <div
key={index} key={index}
@ -1462,9 +1393,10 @@ const EventModal = ({
</div> </div>
<div> <div>
<Label>Teks</Label> <Label>Teks</Label>
<FileUploader <FileUploader
accept={{ accept={{
"application/pdf": [], "pdf/*": [],
}} }}
maxSize={100} maxSize={100}
label="Upload file dengan format .pdf." label="Upload file dengan format .pdf."
@ -1520,7 +1452,8 @@ const EventModal = ({
/> />
<FileUploader <FileUploader
accept={{ accept={{
"audio/*": [], "mp3/*": [],
"wav/*": [],
}} }}
maxSize={100} maxSize={100}
label="Upload file dengan format .mp3 atau .wav." label="Upload file dengan format .mp3 atau .wav."
@ -1546,8 +1479,7 @@ const EventModal = ({
type="button" type="button"
onClick={onPlayPause} onClick={onPlayPause}
disabled={isPlaying} disabled={isPlaying}
className={`flex items-center gap-2 ${ className={`flex items-center gap-2 ${isPlaying
isPlaying
? "bg-gray-300 cursor-not-allowed" ? "bg-gray-300 cursor-not-allowed"
: "bg-primary text-white" : "bg-primary text-white"
} p-2 rounded`} } p-2 rounded`}

View File

@ -22,14 +22,14 @@ const CalenderPage = () => {
let valueShowed: string[] = []; let valueShowed: string[] = [];
if (userLevelNumber == 1) { if (userLevelNumber == 1) {
valueShowed = ["0", "1", "2", "3", "4", "5"]; valueShowed = ["0", "1", "2", "3", "4", "5"];
} else if (userLevelNumber == 2 && userLevelId != 761) { } else if (userLevelNumber == 2 && userLevelId != 771) {
valueShowed = ["2", "3"]; valueShowed = ["2", "3"];
} else if ( } else if (
(userLevelNumber == 2 && userLevelId == 761) || (userLevelNumber == 2 && userLevelId == 771) ||
(userLevelNumber == 3 && userParentLevelId == 761) (userLevelNumber == 3 && userParentLevelId == 771)
) { ) {
valueShowed = ["4"]; valueShowed = ["4"];
} else if (userLevelNumber == 3 && userParentLevelId != 761) { } else if (userLevelNumber == 3 && userParentLevelId != 771) {
valueShowed = ["3"]; valueShowed = ["3"];
} }
@ -39,7 +39,7 @@ const CalenderPage = () => {
...category, ...category,
activeClass: "", activeClass: "",
})); }));
console.log(formattedCategories); // console.log(formattedCategories);
setCategories(formattedCategories); setCategories(formattedCategories);
} }
}, []); }, []);

View File

@ -127,7 +127,7 @@ const BlogTable = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -105,13 +105,13 @@ const useTableColumns = () => {
if (isPublish && !isPublishOnPolda) { if (isPublish && !isPublishOnPolda) {
displayText = "Mabes"; displayText = "Mabes";
} else if (isPublish && isPublishOnPolda) { } else if (isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Mabes & Satker"; displayText = "Mabes & Satker";
} else { } else {
displayText = "Mabes & Polda"; displayText = "Mabes & Polda";
} }
} else if (!isPublish && isPublishOnPolda) { } else if (!isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Satker"; displayText = "Satker";
} else { } else {
displayText = "Polda"; displayText = "Polda";

View File

@ -107,13 +107,13 @@ const useTableColumns = () => {
if (isPublish && !isPublishOnPolda) { if (isPublish && !isPublishOnPolda) {
displayText = "Mabes"; displayText = "Mabes";
} else if (isPublish && isPublishOnPolda) { } else if (isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Mabes & Satker"; displayText = "Mabes & Satker";
} else { } else {
displayText = "Mabes & Polda"; displayText = "Mabes & Polda";
} }
} else if (!isPublish && isPublishOnPolda) { } else if (!isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Satker"; displayText = "Satker";
} else { } else {
displayText = "Polda"; displayText = "Polda";

View File

@ -133,7 +133,7 @@ const TableTeks = () => {
item.no = (page - 1) * limit + index + 1; item.no = (page - 1) * limit + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -144,7 +144,7 @@ const useTableColumns = () => {
const handleClick = (e: React.MouseEvent) => { const handleClick = (e: React.MouseEvent) => {
if (e.ctrlKey) { if (e.ctrlKey) {
console.log("Ctrl + Click detected"); // console.log("Ctrl + Click detected");
} }
// Paksa buka menu meskipun ctrl ditekan // Paksa buka menu meskipun ctrl ditekan
setOpen(true); setOpen(true);

View File

@ -105,13 +105,13 @@ const useTableColumns = () => {
if (isPublish && !isPublishOnPolda) { if (isPublish && !isPublishOnPolda) {
displayText = "Mabes"; displayText = "Mabes";
} else if (isPublish && isPublishOnPolda) { } else if (isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Mabes & Satker"; displayText = "Mabes & Satker";
} else { } else {
displayText = "Mabes & Polda"; displayText = "Mabes & Polda";
} }
} else if (!isPublish && isPublishOnPolda) { } else if (!isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Satker"; displayText = "Satker";
} else { } else {
displayText = "Polda"; displayText = "Polda";

View File

@ -105,13 +105,13 @@ const useTableColumns = () => {
if (isPublish && !isPublishOnPolda) { if (isPublish && !isPublishOnPolda) {
displayText = "Mabes"; displayText = "Mabes";
} else if (isPublish && isPublishOnPolda) { } else if (isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Mabes & Satker"; displayText = "Mabes & Satker";
} else { } else {
displayText = "Mabes & Polda"; displayText = "Mabes & Polda";
} }
} else if (!isPublish && isPublishOnPolda) { } else if (!isPublish && isPublishOnPolda) {
if (Number(creatorGroupParentLevelId) == 761) { if (Number(creatorGroupParentLevelId) == 771) {
displayText = "Satker"; displayText = "Satker";
} else { } else {
displayText = "Polda"; displayText = "Polda";

View File

@ -65,7 +65,6 @@ const useTableColumns = () => {
header: "Status", header: "Status",
cell: ({ row }) => { cell: ({ row }) => {
const isActive = row.getValue<boolean>("isActive"); const isActive = row.getValue<boolean>("isActive");
console.log("isActive value:", isActive); // TypeScript type is inferred correctly
return ( return (
<div> <div>
{isActive ? ( {isActive ? (

View File

@ -121,9 +121,6 @@ const MediahubTable = () => {
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * limit + index + 1; item.no = (page - 1) * limit + index + 1;
}); });
console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);
setTotalPage(data?.totalPages); setTotalPage(data?.totalPages);

View File

@ -65,7 +65,6 @@ const useTableColumns = () => {
header: "Status", header: "Status",
cell: ({ row }) => { cell: ({ row }) => {
const isActive = row.getValue<boolean>("isActive"); const isActive = row.getValue<boolean>("isActive");
console.log("isActive value:", isActive); // TypeScript type is inferred correctly
return ( return (
<div> <div>
{isActive ? ( {isActive ? (

View File

@ -121,9 +121,6 @@ const MedsosTable = () => {
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * limit + index + 1; item.no = (page - 1) * limit + index + 1;
}); });
console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);
setTotalPage(data?.totalPages); setTotalPage(data?.totalPages);

View File

@ -153,7 +153,7 @@ const useTableColumns = ({
// try { // try {
// loading(); // loading();
// const response = await axios.get( // const response = await axios.get(
// `https://new.netidhub.com/api/media/report/download?id=${id}`, // `https://netidhub.com/api/media/report/download?id=${id}`,
// { // {
// responseType: "blob", // responseType: "blob",
// } // }

View File

@ -170,7 +170,7 @@ const ReportTable = () => {
}; };
const handlePreview = (id: string) => { const handlePreview = (id: string) => {
const url = `https://new.netidhub.com/api/media/report/view?id=${id}`; const url = `https://mediahub.polri.go.id/api/v2/media/report/view?id=${id}`;
setPreviewData({ url }); setPreviewData({ url });
setOpenPreview(true); setOpenPreview(true);
}; };
@ -223,9 +223,6 @@ const ReportTable = () => {
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);
setTotalPage(data?.totalPages); setTotalPage(data?.totalPages);

View File

@ -130,9 +130,6 @@ const CalendarPolriTable = () => {
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);
setTotalPage(data?.totalPages); setTotalPage(data?.totalPages);

View File

@ -62,7 +62,6 @@ const useTableColumns = () => {
accessorKey: "time", accessorKey: "time",
header: t("time", { defaultValue: "Time" }), header: t("time", { defaultValue: "Time" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original);
const { startTime, endTime } = row.original; const { startTime, endTime } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">
@ -113,7 +112,6 @@ const useTableColumns = () => {
accessorKey: "speaker", accessorKey: "speaker",
header: t("speaker", { defaultValue: "Speaker" }), header: t("speaker", { defaultValue: "Speaker" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original);
const { speakerTitle, speakerName } = row.original; const { speakerTitle, speakerName } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">

View File

@ -114,9 +114,6 @@ const EventTable = () => {
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);
setTotalPage(data?.totalPages); setTotalPage(data?.totalPages);

View File

@ -66,7 +66,7 @@ const useTableColumns = (props: { selectedTypeSchedule: string }) => {
accessorKey: "time", accessorKey: "time",
header: t("time", { defaultValue: "Time" }), header: t("time", { defaultValue: "Time" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original); // console.log("Row Original Data:", row.original);
const { startTime, endTime } = row.original; const { startTime, endTime } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">
@ -117,7 +117,7 @@ const useTableColumns = (props: { selectedTypeSchedule: string }) => {
accessorKey: "speaker", accessorKey: "speaker",
header: t("speaker", { defaultValue: "Speaker" }), header: t("speaker", { defaultValue: "Speaker" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original); // console.log("Row Original Data:", row.original);
const { speakerTitle, speakerName } = row.original; const { speakerTitle, speakerName } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">

View File

@ -139,7 +139,7 @@ const LiveReportTable = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -62,7 +62,7 @@ const useTableColumns = () => {
accessorKey: "time", accessorKey: "time",
header: t("time", { defaultValue: "Time" }), header: t("time", { defaultValue: "Time" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original); // console.log("Row Original Data:", row.original);
const { startTime, endTime } = row.original; const { startTime, endTime } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">
@ -113,7 +113,7 @@ const useTableColumns = () => {
accessorKey: "speaker", accessorKey: "speaker",
header: t("speaker", { defaultValue: "Speaker" }), header: t("speaker", { defaultValue: "Speaker" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original); // console.log("Row Original Data:", row.original);
const { speakerTitle, speakerName } = row.original; const { speakerTitle, speakerName } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">

View File

@ -129,7 +129,7 @@ const PressConferenceTable = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -62,7 +62,7 @@ const useTableColumns = () => {
accessorKey: "time", accessorKey: "time",
header: t("time", { defaultValue: "Time" }), header: t("time", { defaultValue: "Time" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original); // console.log("Row Original Data:", row.original);
const { startTime, endTime } = row.original; const { startTime, endTime } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">
@ -113,7 +113,7 @@ const useTableColumns = () => {
accessorKey: "speaker", accessorKey: "speaker",
header: t("speaker", { defaultValue: "Speaker" }), header: t("speaker", { defaultValue: "Speaker" }),
cell: ({ row }: { row: { original: any } }) => { cell: ({ row }: { row: { original: any } }) => {
console.log("Row Original Data:", row.original); // console.log("Row Original Data:", row.original);
const { speakerTitle, speakerName } = row.original; const { speakerTitle, speakerName } = row.original;
return ( return (
<span className="whitespace-nowrap"> <span className="whitespace-nowrap">

View File

@ -130,7 +130,7 @@ const PressReleaseTable = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -22,9 +22,7 @@ import withReactContent from "sweetalert2-react-content";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
const useTableColumns = ( const useTableColumns = () => {
activeTab: "ta" | "daily" | "special" | "mabes-koor",
) => {
const t = useTranslations("Table"); const t = useTranslations("Table");
const columns: ColumnDef<any>[] = [ const columns: ColumnDef<any>[] = [
{ {
@ -115,31 +113,6 @@ const useTableColumns = (
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const roleId = Number(getCookiesDecrypt("urie")) || 0; const roleId = Number(getCookiesDecrypt("urie")) || 0;
// ❗ jika tab = "special"
if (activeTab === "special") {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<Link href={`/contributor/task/detail/${row.original.id}`}>
<DropdownMenuItem className="p-2 text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
</Link>
</DropdownMenuContent>
</DropdownMenu>
);
}
async function deleteProcess(id: any) { async function deleteProcess(id: any) {
loading(); loading();
const resDelete = await deleteTaskTa(id); const resDelete = await deleteTaskTa(id);
@ -192,11 +165,7 @@ const useTableColumns = (
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end"> <DropdownMenuContent className="p-0" align="end">
{/* {(roleId == 11 || roleId == 12 || roleId == 19) && ( */} {(roleId == 11 || roleId == 12 || roleId == 19) && (
{(roleId == 11 ||
roleId == 12 ||
roleId == 19 ||
roleId == 3) && (
<Link href={`/contributor/task-ta/detail/${row.original.id}`}> <Link href={`/contributor/task-ta/detail/${row.original.id}`}>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none"> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" /> <Eye className="w-4 h-4 me-1.5" />
@ -204,16 +173,15 @@ const useTableColumns = (
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
)} )}
{roleId == 11 || {roleId == 11 && (
(roleId == 3 && ( <Link href={`/contributor/task-ta/update/${row.original.id}`}>
<Link href={`/contributor/task-ta/update/${row.original.id}`}> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none"> <SquarePen className="w-4 h-4 me-1.5" />
<SquarePen className="w-4 h-4 me-1.5" /> Edit
Edit </DropdownMenuItem>
</DropdownMenuItem> </Link>
</Link> )}
))} {(roleId == 11 || roleId == 12 || roleId == 19) && (
{(roleId == 12 || roleId == 19) && (
<Link <Link
href={`/contributor/task-ta/upload-task/${row.original.id}`} href={`/contributor/task-ta/upload-task/${row.original.id}`}
> >
@ -223,16 +191,15 @@ const useTableColumns = (
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
)} )}
{roleId == 11 || {roleId == 11 && (
(roleId == 3 && ( <DropdownMenuItem
<DropdownMenuItem onClick={() => TaskDelete(row.original.id)}
onClick={() => TaskDelete(row.original.id)} className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none" >
> <Trash2 className="w-4 h-4 me-1.5" />
<Trash2 className="w-4 h-4 me-1.5" /> Delete
Delete </DropdownMenuItem>
</DropdownMenuItem> )}
))}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
); );

View File

@ -35,19 +35,10 @@ const TaskTaPage = () => {
<CardTitle> <CardTitle>
<div className="flex flex-col sm:flex-row lg:flex-row lg:items-center"> <div className="flex flex-col sm:flex-row lg:flex-row lg:items-center">
<div className="flex-1 text-xl font-medium text-default-900"> <div className="flex-1 text-xl font-medium text-default-900">
{t("tabel", { defaultValue: "Tabel" })}{" "} {t("tabel", { defaultValue: "Tabel" })} {t("task-ta", { defaultValue: "Task Ta" })}
{t("task-ta", { defaultValue: "Task Ta" })}
</div> </div>
<div className="flex-none"> <div className="flex-none">
{/* {roleId !== 12 && ( {roleId !== 12 && (
<Link href={"/contributor/task-ta/create"}>
<Button color="primary" className="text-white">
<UploadIcon size={18} className="mr-2" />
{t("create-task", { defaultValue: "Create Task" })}
</Button>
</Link>
)} */}
{roleId !== 12 && roleId !== 19 && (
<Link href={"/contributor/task-ta/create"}> <Link href={"/contributor/task-ta/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon size={18} className="mr-2" /> <UploadIcon size={18} className="mr-2" />

View File

@ -160,7 +160,7 @@ const TaskTable = () => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -5,11 +5,7 @@ import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react"; import { UploadIcon } from "lucide-react";
import SiteBreadcrumb from "@/components/site-breadcrumb"; import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Link } from "@/components/navigation"; import { Link } from "@/components/navigation";
import { import { checkAuthorization, checkLoginSession } from "@/lib/utils";
checkAuthorization,
checkLoginSession,
getCookiesDecrypt,
} from "@/lib/utils";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
@ -17,13 +13,12 @@ const TaskPage = () => {
const t = useTranslations("AnalyticsDashboard"); const t = useTranslations("AnalyticsDashboard");
useEffect(() => { useEffect(() => {
function initState() { function initState() {
checkAuthorization("admin"); checkAuthorization("admin");
checkLoginSession(); checkLoginSession();
} }
initState(); initState();
}, []); }, []);
const levelNumber = getCookiesDecrypt("ulne");
return ( return (
<div> <div>
@ -34,28 +29,16 @@ const TaskPage = () => {
<CardTitle> <CardTitle>
<div className="flex flex-col sm:flex-row lg:flex-row lg:items-center"> <div className="flex flex-col sm:flex-row lg:flex-row lg:items-center">
<div className="flex-1 text-xl font-medium text-default-900"> <div className="flex-1 text-xl font-medium text-default-900">
{t("tabel", { defaultValue: "Tabel" })}{" "} {t("tabel", { defaultValue: "Tabel" })} {t("task", { defaultValue: "Task" })}
{t("task", { defaultValue: "Task" })}
</div> </div>
{Number(levelNumber) !== 3 && ( <div className="flex-none">
<div className="flex-none">
<Link href="/contributor/task/create">
<Button color="primary" className="text-white">
<UploadIcon size={18} className="mr-2" />
{t("create-task", { defaultValue: "Create Task" })}
</Button>
</Link>
</div>
)}
{/* <div className="flex-none">
<Link href={"/contributor/task/create"}> <Link href={"/contributor/task/create"}>
<Button color="primary" className="text-white"> <Button color="primary" className="text-white">
<UploadIcon size={18} className="mr-2" /> <UploadIcon size={18} className="mr-2" />
{t("create-task", { defaultValue: "Create Task" })} {t("create-task", { defaultValue: "Create Task" })}
</Button> </Button>
</Link> </Link>
</div> */} </div>
</div> </div>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>

View File

@ -14,7 +14,7 @@ export default function UserFeedback() {
}, []); }, []);
async function initState() { async function initState() {
const response = await getUserFeedbacks(); const response = await getUserFeedbacks();
console.log("ssss", response?.data?.data); // console.log("ssss", response?.data?.data);
setListData(response?.data?.data); setListData(response?.data?.data);
} }

View File

@ -115,7 +115,7 @@ const MediaTrackingTable = () => {
item.no = (page - 1) * limit + index + 1; item.no = (page - 1) * limit + index + 1;
}); });
console.log("contentData : ", data); // console.log("contentData : ", data);
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements);

View File

@ -113,13 +113,12 @@ const TaskPlanMediahubTable = (props: {
// try { // try {
// const res = await ticketingPagination("", limit, page - 1); // const res = await ticketingPagination("", limit, page - 1);
// const data = res?.data?.data; // const data = res?.data?.data;
console.log("datgaa", data);
const contentData = data; const contentData = data;
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * limit + index + 1; item.no = (page - 1) * limit + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
// setTotalData(data?.totalElements); // setTotalData(data?.totalElements);

View File

@ -153,8 +153,6 @@ export default function DetailDaily() {
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("data");
console.log("Data :", data);
form.setValue("title", data.title); form.setValue("title", data.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
form.setValue("date", new Date(data.date)); form.setValue("date", new Date(data.date));
@ -205,7 +203,7 @@ export default function DetailDaily() {
const editor = useRef(null); const editor = useRef(null);
const onSubmit = async (data: z.infer<typeof FormSchema>) => { const onSubmit = async (data: z.infer<typeof FormSchema>) => {
console.log("data", data); // console.log("data", data);
if (form.getValues("detail") == "") { if (form.getValues("detail") == "") {
form.setError("detail", { form.setError("detail", {
type: "manual", type: "manual",
@ -234,7 +232,7 @@ export default function DetailDaily() {
.filter((key) => selected[key]) .filter((key) => selected[key])
.join(", "); .join(", ");
}; };
console.log("data", data, selected); // console.log("data", data, selected);
loading(); loading();
const reqData = { const reqData = {
@ -258,7 +256,7 @@ export default function DetailDaily() {
assignmentMainTypeId: 1, assignmentMainTypeId: 1,
}; };
console.log("req =>", reqData); // console.log("req =>", reqData);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
if (response?.error) { if (response?.error) {

View File

@ -152,8 +152,6 @@ export default function EditDaily() {
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("data");
console.log("Data :", data);
form.setValue("title", data.title); form.setValue("title", data.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
form.setValue("date", new Date(data.date)); form.setValue("date", new Date(data.date));
@ -218,7 +216,7 @@ export default function EditDaily() {
const editor = useRef(null); const editor = useRef(null);
const onSubmit = async (data: z.infer<typeof FormSchema>) => { const onSubmit = async (data: z.infer<typeof FormSchema>) => {
console.log("data", data); // console.log("data", data);
if (form.getValues("detail") == "") { if (form.getValues("detail") == "") {
form.setError("detail", { form.setError("detail", {
type: "manual", type: "manual",
@ -247,7 +245,7 @@ export default function EditDaily() {
.filter((key) => selected[key]) .filter((key) => selected[key])
.join(", "); .join(", ");
}; };
console.log("data", data, selected); // console.log("data", data, selected);
loading(); loading();
const reqData = { const reqData = {

View File

@ -166,7 +166,7 @@ export default function CreateDaily() {
const editor = useRef(null); const editor = useRef(null);
const onSubmit = async (data: z.infer<typeof FormSchema>) => { const onSubmit = async (data: z.infer<typeof FormSchema>) => {
console.log("data", data); // console.log("data", data);
if (form.getValues("detail") == "") { if (form.getValues("detail") == "") {
form.setError("detail", { form.setError("detail", {
type: "manual", type: "manual",
@ -195,7 +195,7 @@ export default function CreateDaily() {
.filter((key) => selected[key]) .filter((key) => selected[key])
.join(", "); .join(", ");
}; };
console.log("data", data, selected); // console.log("data", data, selected);
loading(); loading();
const reqData = { const reqData = {
@ -219,7 +219,7 @@ export default function CreateDaily() {
assignmentMainTypeId: 1, assignmentMainTypeId: 1,
}; };
console.log("req =>", reqData); // console.log("req =>", reqData);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
if (response?.error) { if (response?.error) {

View File

@ -76,11 +76,9 @@ export default function DetailMonthly() {
close(); close();
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("Data :", data);
form.setValue("title", data?.title); form.setValue("title", data?.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
const date = parseDate(data.date); const date = parseDate(data.date);
console.log("date", date);
form.setValue( form.setValue(
"month", "month",
new Date(date.getFullYear(), date.getMonth(), 1) new Date(date.getFullYear(), date.getMonth(), 1)
@ -127,7 +125,7 @@ export default function DetailMonthly() {
).getFullYear()}`, ).getFullYear()}`,
status: "Open", status: "Open",
}; };
console.log("req", reqData, data.month); // console.log("req", reqData, data.month);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {
@ -154,7 +152,7 @@ export default function DetailMonthly() {
selectedDate.getMonth(), selectedDate.getMonth(),
1 1
); );
console.log("newDate", newDate, selectedDate); // console.log("newDate", newDate, selectedDate);
form.setValue("month", newDate); form.setValue("month", newDate);
}; };
return ( return (

View File

@ -77,11 +77,9 @@ export default function EditMonthly() {
close(); close();
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("Data :", data);
form.setValue("title", data?.title); form.setValue("title", data?.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
const date = parseDate(data.date); const date = parseDate(data.date);
console.log("date", date);
form.setValue( form.setValue(
"month", "month",
new Date(date.getFullYear(), date.getMonth(), 1) new Date(date.getFullYear(), date.getMonth(), 1)
@ -129,7 +127,7 @@ export default function EditMonthly() {
date: `${month.toString().padStart(2, "0")}/${year}`, date: `${month.toString().padStart(2, "0")}/${year}`,
status: "Open", status: "Open",
}; };
console.log("req", reqData, data.month); // console.log("req", reqData, data.month);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {
@ -156,7 +154,7 @@ export default function EditMonthly() {
selectedDate.getMonth(), selectedDate.getMonth(),
1 1
); );
console.log("newDate", newDate, selectedDate); // console.log("newDate", newDate, selectedDate);
form.setValue("month", newDate); form.setValue("month", newDate);
}; };
return ( return (

View File

@ -97,7 +97,7 @@ export default function CreateMonthly() {
date: `${month.toString().padStart(2, "0")}/${year}`, date: `${month.toString().padStart(2, "0")}/${year}`,
status: "Open", status: "Open",
}; };
console.log("req", reqData, data.month); // console.log("req", reqData, data.month);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {

View File

@ -119,7 +119,7 @@ export default function DetailWeekly() {
status: "Open", status: "Open",
parentId: parentId, parentId: parentId,
}; };
console.log("req", reqData); // console.log("req", reqData);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {
@ -147,7 +147,7 @@ export default function DetailWeekly() {
close(); close();
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("Data :", data); // console.log("Data :", data);
form.setValue("title", data?.title); form.setValue("title", data?.title);
form.setValue("week", { form.setValue("week", {
from: new Date(data?.startDate), from: new Date(data?.startDate),

View File

@ -118,7 +118,7 @@ export default function EditWeekly() {
status: "Open", status: "Open",
parentId: parentId, parentId: parentId,
}; };
console.log("req", reqData); // console.log("req", reqData);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {
@ -146,7 +146,7 @@ export default function EditWeekly() {
close(); close();
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("Data :", data); // console.log("Data :", data);
form.setValue("title", data?.title); form.setValue("title", data?.title);
form.setValue("week", { form.setValue("week", {
from: new Date(data?.startDate), from: new Date(data?.startDate),

View File

@ -117,7 +117,7 @@ export default function CreateMonthly() {
status: "Open", status: "Open",
parentId: Number(data.parentId), parentId: Number(data.parentId),
}; };
console.log("req", reqData); // console.log("req", reqData);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {

View File

@ -48,7 +48,7 @@ export default function DetailTaskPlanMediahub() {
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("Data :", data); // console.log("Data :", data);
setPlanningData(data); setPlanningData(data);
setAssignedTopLevel(data?.assignedToTopLevel); setAssignedTopLevel(data?.assignedToTopLevel);
setArrayDestination(data?.assignedToLevel); setArrayDestination(data?.assignedToLevel);
@ -112,7 +112,7 @@ export default function DetailTaskPlanMediahub() {
label: option.title, label: option.title,
value: option.id, value: option.id,
})); }));
console.log("res", optionArr); // console.log("res", optionArr);
setWeeklyList(optionArr); setWeeklyList(optionArr);
} }

View File

@ -113,13 +113,13 @@ const TaskPlanMediahubTable = (props: {
// try { // try {
// const res = await ticketingPagination("", limit, page - 1); // const res = await ticketingPagination("", limit, page - 1);
// const data = res?.data?.data; // const data = res?.data?.data;
console.log("datgaa", data); // console.log("datgaa", data);
const contentData = data; const contentData = data;
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * limit + index + 1; item.no = (page - 1) * limit + index + 1;
}); });
console.log("contentData : ", contentData); // console.log("contentData : ", contentData);
setDataTable(contentData); setDataTable(contentData);
// setTotalData(data?.totalElements); // setTotalData(data?.totalElements);

View File

@ -153,8 +153,6 @@ export default function DetailDaily() {
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("data");
console.log("Data :", data);
form.setValue("title", data.title); form.setValue("title", data.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
form.setValue("date", new Date(data.date)); form.setValue("date", new Date(data.date));
@ -205,7 +203,7 @@ export default function DetailDaily() {
const editor = useRef(null); const editor = useRef(null);
const onSubmit = async (data: z.infer<typeof FormSchema>) => { const onSubmit = async (data: z.infer<typeof FormSchema>) => {
console.log("data", data); // console.log("data", data);
if (form.getValues("detail") == "") { if (form.getValues("detail") == "") {
form.setError("detail", { form.setError("detail", {
type: "manual", type: "manual",
@ -234,7 +232,7 @@ export default function DetailDaily() {
.filter((key) => selected[key]) .filter((key) => selected[key])
.join(", "); .join(", ");
}; };
console.log("data", data, selected); // console.log("data", data, selected);
loading(); loading();
const reqData = { const reqData = {
@ -258,7 +256,7 @@ export default function DetailDaily() {
assignmentMainTypeId: 1, assignmentMainTypeId: 1,
}; };
console.log("req =>", reqData); // console.log("req =>", reqData);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
if (response?.error) { if (response?.error) {

View File

@ -152,8 +152,6 @@ export default function EditDaily() {
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("data");
console.log("Data :", data);
form.setValue("title", data.title); form.setValue("title", data.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
form.setValue("date", new Date(data.date)); form.setValue("date", new Date(data.date));
@ -218,7 +216,7 @@ export default function EditDaily() {
const editor = useRef(null); const editor = useRef(null);
const onSubmit = async (data: z.infer<typeof FormSchema>) => { const onSubmit = async (data: z.infer<typeof FormSchema>) => {
console.log("data", data); // console.log("data", data);
if (form.getValues("detail") == "") { if (form.getValues("detail") == "") {
form.setError("detail", { form.setError("detail", {
type: "manual", type: "manual",
@ -247,7 +245,7 @@ export default function EditDaily() {
.filter((key) => selected[key]) .filter((key) => selected[key])
.join(", "); .join(", ");
}; };
console.log("data", data, selected); // console.log("data", data, selected);
loading(); loading();
const reqData = { const reqData = {

View File

@ -239,7 +239,7 @@ export default function CreateDaily() {
assignmentMainTypeId: 2, assignmentMainTypeId: 2,
}; };
console.log("req =>", reqData); // console.log("req =>", reqData);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
if (response?.error) { if (response?.error) {

View File

@ -76,11 +76,11 @@ export default function DetailMonthly() {
close(); close();
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("Data :", data); // console.log("Data :", data);
form.setValue("title", data?.title); form.setValue("title", data?.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
const date = parseDate(data.date); const date = parseDate(data.date);
console.log("date", date); // console.log("date", date);
form.setValue( form.setValue(
"month", "month",
new Date(date.getFullYear(), date.getMonth(), 1) new Date(date.getFullYear(), date.getMonth(), 1)
@ -127,7 +127,7 @@ export default function DetailMonthly() {
date: `${month.toString().padStart(2, "0")}/${year}`, date: `${month.toString().padStart(2, "0")}/${year}`,
status: "Open", status: "Open",
}; };
console.log("req", reqData, data.month); // console.log("req", reqData, data.month);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {
@ -154,7 +154,7 @@ export default function DetailMonthly() {
selectedDate.getMonth(), selectedDate.getMonth(),
1 1
); );
console.log("newDate", newDate, selectedDate); // console.log("newDate", newDate, selectedDate);
form.setValue("month", newDate); form.setValue("month", newDate);
}; };
return ( return (

View File

@ -76,11 +76,11 @@ export default function EditMonthly() {
close(); close();
if (res?.data?.data != undefined) { if (res?.data?.data != undefined) {
const data = res?.data?.data; const data = res?.data?.data;
console.log("Data :", data); // console.log("Data :", data);
form.setValue("title", data?.title); form.setValue("title", data?.title);
form.setValue("detail", data.description); form.setValue("detail", data.description);
const date = parseDate(data.date); const date = parseDate(data.date);
console.log("date", date); // console.log("date", date);
form.setValue( form.setValue(
"month", "month",
new Date(date.getFullYear(), date.getMonth(), 1) new Date(date.getFullYear(), date.getMonth(), 1)
@ -128,7 +128,7 @@ export default function EditMonthly() {
date: `${month.toString().padStart(2, "0")}/${year}`, date: `${month.toString().padStart(2, "0")}/${year}`,
status: "Open", status: "Open",
}; };
console.log("req", reqData, data.month); // console.log("req", reqData, data.month);
const response = await savePlanning(reqData); const response = await savePlanning(reqData);
close(); close();
if (response?.error) { if (response?.error) {
@ -155,7 +155,7 @@ export default function EditMonthly() {
selectedDate.getMonth(), selectedDate.getMonth(),
1 1
); );
console.log("newDate", newDate, selectedDate); // console.log("newDate", newDate, selectedDate);
form.setValue("month", newDate); form.setValue("month", newDate);
}; };
return ( return (

Some files were not shown because too many files have changed in this diff Show More