Compare commits
69 Commits
prod-with-
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
9223122e66 | |
|
|
9e286ffd06 | |
|
|
18d6f32536 | |
|
|
9c2b3612c6 | |
|
|
6bd83237c4 | |
|
|
61df236e13 | |
|
|
7f9166b866 | |
|
|
2876e4eb30 | |
|
|
292cde6ed0 | |
|
|
3c5e644668 | |
|
|
d80adaa133 | |
|
|
eefa43a5b0 | |
|
|
277f1cc805 | |
|
|
f357a4e8ce | |
|
|
bb91379058 | |
|
|
740d73d689 | |
|
|
76c4ed9238 | |
|
|
44c6cc6d9d | |
|
|
2b8f7b724e | |
|
|
10694547d1 | |
|
|
e5e32496ab | |
|
|
78d1fc0d93 | |
|
|
c99e1a5c7d | |
|
|
274fd022e1 | |
|
|
933a672280 | |
|
|
ce7c343808 | |
|
|
cba94cf0a9 | |
|
|
7c721dcc96 | |
|
|
78ddd461df | |
|
|
ec2d7eb203 | |
|
|
ad5d048e78 | |
|
|
5614b5ada5 | |
|
|
f1b59ee537 | |
|
|
0ad1acee09 | |
|
|
2d09af2e8b | |
|
|
edafc223db | |
|
|
933cdb1100 | |
|
|
280ea508e9 | |
|
|
1a0d53bb11 | |
|
|
be1c799629 | |
|
|
3d23d75e05 | |
|
|
1ee379df71 | |
|
|
9a1b41e90b | |
|
|
fcfa24b06c | |
|
|
cf91ea33ec | |
|
|
1cc7786dee | |
|
|
f1ecebfb0f | |
|
|
76b7b4b86e | |
|
|
3698996c0c | |
|
|
3349450cb9 | |
|
|
80d07d358f | |
|
|
f9417b63ae | |
|
|
8f494739c6 | |
|
|
dd94afc81d | |
|
|
4c32b76ea3 | |
|
|
d21d377e17 | |
|
|
f90c9f73e1 | |
|
|
3c14fd2358 | |
|
|
6951ccd137 | |
|
|
cd822a7b5d | |
|
|
68b9439f23 | |
|
|
6afd7d1183 | |
|
|
1f7b912b52 | |
|
|
ae61d19a61 | |
|
|
3b0bf64e39 | |
|
|
0c5a7f86bb | |
|
|
15a395ccd2 | |
|
|
c71532cdd5 | |
|
|
eaa9001c98 |
|
|
@ -0,0 +1,45 @@
|
||||||
|
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
|
||||||
|
- 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:
|
||||||
|
- prod
|
||||||
|
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
4
.env
|
|
@ -1,3 +1,3 @@
|
||||||
NEXT_PUBLIC_API=https://mediahub.polri.go.id/api/v2
|
NEXT_PUBLIC_API=https://new.netidhub.com/api
|
||||||
NEXT_PUBLIC=https://mediahub.polri.go.id
|
NEXT_PUBLIC=https://new.netidhub.com
|
||||||
NEXT_PUBLIC_TINYMCE_API_KEY=bhteuja26yz5p0aubxry9b95hs33amgn65kjv5km0fd5iuev
|
NEXT_PUBLIC_TINYMCE_API_KEY=bhteuja26yz5p0aubxry9b95hs33amgn65kjv5km0fd5iuev
|
||||||
|
|
@ -1,26 +1,23 @@
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
build-prod:
|
build-dev:
|
||||||
stage: build
|
stage: build
|
||||||
when: on_success
|
when: on_success
|
||||||
only:
|
only:
|
||||||
- main
|
- main
|
||||||
- dev-landing-v2
|
- dev-landing-v2
|
||||||
- prod
|
image:
|
||||||
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=103.82.242.92:8900"]
|
command: ["--insecure-registry=38.47.185.86:8900"]
|
||||||
script:
|
script:
|
||||||
- docker logout
|
- docker logout
|
||||||
- echo "Username:$DEPLOY_USERNAME"
|
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN 38.47.185.86:8900
|
||||||
- echo "Token:$DEPLOY_TOKEN"
|
- docker build -t 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 push 38.47.185.86:8900/mediahub/new-mediahub-fe:dev
|
||||||
- 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
|
||||||
|
|
@ -29,7 +26,5 @@ 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.180.165:8080/job/auto-deploy-new-mediahub-fe/build?token=autodeploynewmediahub
|
- curl --user admin:$JENKINS_PWD http://38.47.185.86:8080/job/auto-deploy-new-mediahub-fe/build?token=autodeploynewmediahub
|
||||||
|
|
|
||||||
|
|
@ -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 columns: ColumnDef<any>[] = [
|
const getColumns = ({ onRefresh }: { onRefresh: () => void }): ColumnDef<any>[] => [
|
||||||
{
|
{
|
||||||
accessorKey: "no",
|
accessorKey: "no",
|
||||||
header: "No",
|
header: "No",
|
||||||
|
|
@ -30,11 +30,13 @@ const columns: 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: ({ row }) => <span>MABES</span>,
|
cell: () => <span>MABES</span>,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
accessorKey: "userRolePlacements",
|
accessorKey: "userRolePlacements",
|
||||||
header: "Posisi",
|
header: "Posisi",
|
||||||
|
|
@ -52,6 +54,7 @@ const columns: ColumnDef<any>[] = [
|
||||||
return <span>{posisi}</span>;
|
return <span>{posisi}</span>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
accessorKey: "role.name",
|
accessorKey: "role.name",
|
||||||
header: "Bidang Keahlian",
|
header: "Bidang Keahlian",
|
||||||
|
|
@ -81,72 +84,77 @@ const columns: 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",
|
|
||||||
});
|
|
||||||
|
|
||||||
router.push("?dataChange=true");
|
toast({ title: "Berhasil menghapus user" });
|
||||||
|
|
||||||
|
// ⬅️ INI YANG PENTING → REFRESH TABLE TANPA RELOAD
|
||||||
|
onRefresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (id: number) => {
|
const handleDelete = (id: number) => {
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
title: "Apakah anda ingin menghapus data user?",
|
title: "Hapus user ini?",
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: "#dc3545",
|
confirmButtonColor: "#dc3545",
|
||||||
confirmButtonText: "Iya",
|
confirmButtonText: "Iya",
|
||||||
cancelButtonText: "Tidak",
|
cancelButtonText: "Tidak",
|
||||||
}).then((result) => {
|
}).then((res) => {
|
||||||
if (result.isConfirmed) {
|
if (res.isConfirmed) doDelete(id);
|
||||||
doDelete(id);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button size="icon" variant="ghost">
|
||||||
size="icon"
|
<MoreVertical className="h-4 w-4" />
|
||||||
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 className="p-0" align="end">
|
<DropdownMenuContent align="end">
|
||||||
<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">
|
<Link href={`/admin/add-experts/detail/${row.original.id}`}>
|
||||||
<Eye className="w-4 h-4 me-1.5" />
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer">
|
||||||
View
|
<Eye className="w-4 h-4 me-1.5" /> 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">
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none cursor-pointer">
|
||||||
<SquarePen className="w-4 h-4 me-1.5" />
|
<SquarePen className="w-4 h-4 me-1.5" /> Edit
|
||||||
Edit
|
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={() => handleDelete(row.original.userKeycloakId)}
|
onClick={() => handleDelete(row.original.userKeycloakId)}
|
||||||
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
|
className="text-red-600 cursor-pointer hover:bg-red-300"
|
||||||
>
|
>
|
||||||
<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>
|
||||||
);
|
);
|
||||||
|
|
@ -154,4 +162,4 @@ const columns: ColumnDef<any>[] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default columns;
|
export default getColumns;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import {
|
||||||
ColumnDef,
|
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
PaginationState,
|
PaginationState,
|
||||||
SortingState,
|
SortingState,
|
||||||
|
|
@ -15,7 +14,6 @@ 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,
|
||||||
|
|
@ -25,7 +23,6 @@ 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,
|
||||||
|
|
@ -35,43 +32,14 @@ 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 { getPlanningPagination } from "@/service/agenda-setting/agenda-setting";
|
import getColumns from "./column";
|
||||||
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();
|
||||||
|
|
@ -97,7 +65,8 @@ 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(),
|
||||||
|
|
@ -283,7 +252,11 @@ const AddExpertTable = () => {
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={columns.length} className="h-24 text-center">
|
<TableCell
|
||||||
|
// colSpan={columns.length}
|
||||||
|
colSpan={table.getAllLeafColumns().length}
|
||||||
|
className="h-24 text-center"
|
||||||
|
>
|
||||||
No results.
|
No results.
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|
|
||||||
|
|
@ -35,32 +35,61 @@ 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({
|
name: z.string({ required_error: "Required" }),
|
||||||
required_error: "Required",
|
username: z
|
||||||
}),
|
.string({ required_error: "Required" })
|
||||||
username: z.string({
|
.refine((val) => !/\s/.test(val), {
|
||||||
required_error: "Required",
|
message: "Username tidak boleh mengandung spasi",
|
||||||
}),
|
}),
|
||||||
password: z.string({
|
// .transform((val) => val.toLowerCase()),
|
||||||
required_error: "Required",
|
|
||||||
}),
|
password: z
|
||||||
phoneNumber: z.string({
|
.string({ required_error: "Required" })
|
||||||
required_error: "Required",
|
.min(8, "Minimal 8 karakter")
|
||||||
}),
|
.regex(/[A-Z]/, "Harus mengandung huruf besar (A-Z)")
|
||||||
email: z.string({
|
.regex(/[0-9]/, "Harus mengandung angka (0-9)")
|
||||||
required_error: "Required",
|
.regex(/[^A-Za-z0-9]/, "Harus mengandung karakter spesial (!@#$%^&*)"),
|
||||||
}),
|
|
||||||
skills: z.string({
|
// confirmPassword: z.string({ required_error: "Required" }),
|
||||||
required_error: "Required",
|
|
||||||
}),
|
phoneNumber: z.string({ required_error: "Required" }),
|
||||||
experiences: z.string({
|
email: z.string({ required_error: "Required" }),
|
||||||
required_error: "Required",
|
skills: z.string({ required_error: "Required" }),
|
||||||
}),
|
experiences: z.string({ required_error: "Required" }),
|
||||||
company: z.string({
|
company: z.string({ required_error: "Required" }),
|
||||||
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;
|
||||||
|
|
@ -74,6 +103,7 @@ 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 },
|
||||||
|
|
@ -118,7 +148,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,
|
||||||
|
|
@ -135,7 +165,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) => {
|
||||||
|
|
@ -244,10 +274,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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -261,6 +291,19 @@ 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 />
|
||||||
|
|
@ -288,6 +331,39 @@ 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 }) => (
|
||||||
|
|
@ -303,7 +379,7 @@ export default function AddExpertForm() {
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/> */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="phoneNumber"
|
name="phoneNumber"
|
||||||
|
|
@ -349,6 +425,69 @@ 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 }) => (
|
||||||
|
|
@ -373,7 +512,7 @@ export default function AddExpertForm() {
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/> */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="skills"
|
name="skills"
|
||||||
|
|
|
||||||
|
|
@ -37,32 +37,43 @@ 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({
|
name: z.string().optional(),
|
||||||
required_error: "Required",
|
username: z.string().optional(),
|
||||||
}),
|
password: z.string().optional(),
|
||||||
username: z.string({
|
phoneNumber: z.string().optional(),
|
||||||
required_error: "Required",
|
email: z.string().optional(),
|
||||||
}),
|
skills: z.string().optional(),
|
||||||
password: z.string({
|
experiences: z.string().optional(),
|
||||||
required_error: "Required",
|
company: z.string().optional(),
|
||||||
}),
|
|
||||||
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;
|
||||||
|
|
@ -96,6 +107,10 @@ interface Detail {
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
userRolePlacements?: {
|
||||||
|
roleId: number;
|
||||||
|
userLevelId: number;
|
||||||
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function UpdateExpertForm() {
|
export default function UpdateExpertForm() {
|
||||||
|
|
@ -149,6 +164,39 @@ 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 = () => {
|
||||||
|
|
@ -185,22 +233,39 @@ 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,
|
firstName: data.name || detail.fullname,
|
||||||
username: data.username,
|
username: data.username || detail.username,
|
||||||
email: data.email,
|
email: data.email || detail.email,
|
||||||
password: data.password,
|
password: data.password || undefined,
|
||||||
address: "",
|
address: "",
|
||||||
roleId: "EXP-ID",
|
roleId: "EXP-ID",
|
||||||
phoneNumber: data.phoneNumber,
|
phoneNumber: data.phoneNumber || detail.phoneNumber,
|
||||||
userCompetencyId: data.skills,
|
userCompetencyId:
|
||||||
userExperienceId: data.experiences,
|
data.skills || detail.userProfilesAdditional?.userCompetency?.id,
|
||||||
companyName: data.company,
|
userExperienceId:
|
||||||
|
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;
|
||||||
|
|
@ -245,7 +310,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;
|
||||||
|
|
@ -288,10 +353,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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -322,10 +387,15 @@ 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 />
|
||||||
|
|
@ -333,18 +403,24 @@ 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>
|
||||||
)}
|
)}
|
||||||
|
|
@ -355,11 +431,17 @@ 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>
|
||||||
|
|
@ -371,17 +453,46 @@ 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 }) => (
|
||||||
|
|
@ -406,7 +517,7 @@ export default function UpdateExpertForm() {
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/> */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="skills"
|
name="skills"
|
||||||
|
|
@ -481,12 +592,21 @@ 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>
|
||||||
)}
|
)}
|
||||||
|
|
@ -497,6 +617,7 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
@ -533,6 +654,7 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
@ -562,7 +684,7 @@ export default function UpdateExpertForm() {
|
||||||
type="button"
|
type="button"
|
||||||
size="md"
|
size="md"
|
||||||
onClick={handleAddRow}
|
onClick={handleAddRow}
|
||||||
disabled={placementRows.length >= 2} // optional: disable button if already 1 row added
|
disabled={placementRows.length >= 2}
|
||||||
>
|
>
|
||||||
Tambah
|
Tambah
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -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://db-mediahub.polri.go.id/";
|
const baseUrl = "https://analytic.sitani.info/";
|
||||||
const url = "https://db-mediahub.polri.go.id/trusted/";
|
const url = "https://analytic.sitani.info/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=yes&:iframeSizedToWindow=true";
|
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
|
|
|
||||||
|
|
@ -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://db-mediahub.polri.go.id/";
|
const baseUrl = "https://analytic.sitani.info/";
|
||||||
const url = "https://db-mediahub.polri.go.id/trusted/";
|
const url = "https://analytic.sitani.info/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=yes&:iframeSizedToWindow=true";
|
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
|
|
|
||||||
|
|
@ -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://db-mediahub.polri.go.id/";
|
const baseUrl = "https://analytic.sitani.info/";
|
||||||
const url = "https://db-mediahub.polri.go.id/trusted/";
|
const url = "https://analytic.sitani.info/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=yes&:iframeSizedToWindow=true";
|
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
|
|
|
||||||
|
|
@ -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://db-mediahub.polri.go.id/";
|
const baseUrl = "https://analytic.sitani.info/";
|
||||||
const url = "https://db-mediahub.polri.go.id/trusted/";
|
const url = "https://analytic.sitani.info/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=yes&:iframeSizedToWindow=true";
|
const param = ":embed=yes&:toolbar=no&:iframeSizedToWindow=true";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,12 @@ import {
|
||||||
deleteMediaBlastCampaignAccount,
|
deleteMediaBlastCampaignAccount,
|
||||||
saveMediaBlastCampaignAccountBulk,
|
saveMediaBlastCampaignAccountBulk,
|
||||||
} from "@/service/broadcast/broadcast";
|
} from "@/service/broadcast/broadcast";
|
||||||
import { AdministrationUserList, getUserListAll } from "@/service/management-user/management-user";
|
import {
|
||||||
|
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 = [
|
||||||
|
|
@ -98,7 +102,8 @@ 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] = React.useState<any[]>(availableAccounts);
|
const [availableAccountsList, setAvailableAccountsList] =
|
||||||
|
React.useState<any[]>(availableAccounts);
|
||||||
const [usersList, setUsersList] = React.useState<any[]>([]);
|
const [usersList, setUsersList] = React.useState<any[]>([]);
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
|
|
@ -171,7 +176,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 = {
|
||||||
|
|
@ -202,7 +207,7 @@ const AccountListTable = () => {
|
||||||
default:
|
default:
|
||||||
roleId = "5";
|
roleId = "5";
|
||||||
}
|
}
|
||||||
|
|
||||||
const request = {
|
const request = {
|
||||||
mediaBlastCampaignId: campaignId,
|
mediaBlastCampaignId: campaignId,
|
||||||
mediaBlastAccountCategory: `role-${roleId}`,
|
mediaBlastAccountCategory: `role-${roleId}`,
|
||||||
|
|
@ -216,7 +221,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) {
|
||||||
|
|
@ -224,7 +229,7 @@ const AccountListTable = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close();
|
close();
|
||||||
successCallback("Akun berhasil ditambahkan ke campaign!");
|
successCallback("Akun berhasil ditambahkan ke campaign!");
|
||||||
resetDialogState();
|
resetDialogState();
|
||||||
|
|
@ -247,7 +252,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);
|
||||||
}
|
}
|
||||||
|
|
@ -265,15 +270,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(acc => acc.category === selectedCategory);
|
return availableAccountsList.filter(
|
||||||
|
(acc) => acc.category === selectedCategory
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return availableAccountsList;
|
return availableAccountsList;
|
||||||
};
|
};
|
||||||
|
|
@ -291,7 +296,10 @@ const AccountListTable = () => {
|
||||||
Pilih Akun
|
Pilih Akun
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent size="md" className="max-w-xl max-h-[80vh] overflow-y-auto">
|
<DialogContent
|
||||||
|
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>
|
||||||
|
|
@ -350,15 +358,17 @@ 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 ? selectedOptions.map((option: any) => option.user) : [];
|
const selectedUsers = selectedOptions
|
||||||
|
? selectedOptions.map((option: any) => option.user)
|
||||||
|
: [];
|
||||||
setSelectedAccount(selectedUsers);
|
setSelectedAccount(selectedUsers);
|
||||||
}}
|
}}
|
||||||
placeholder="Cari dan pilih user..."
|
placeholder="Cari dan pilih user..."
|
||||||
|
|
@ -369,14 +379,17 @@ 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 key={acc.id} className="flex items-center gap-1">
|
<Badge
|
||||||
|
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"
|
||||||
|
|
@ -403,7 +416,8 @@ 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()}" akan ditambahkan.
|
Semua akun dengan role "{selectedCategory.toUpperCase()}"
|
||||||
|
akan ditambahkan.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -412,7 +426,8 @@ 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 campaign ini.
|
{selectedAccount.length} user terpilih akan ditambahkan ke
|
||||||
|
campaign ini.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -423,7 +438,8 @@ const AccountListTable = () => {
|
||||||
onClick={saveCampaignAccount}
|
onClick={saveCampaignAccount}
|
||||||
disabled={
|
disabled={
|
||||||
!accountCategory ||
|
!accountCategory ||
|
||||||
(accountCategory === "custom" && selectedAccount.length < 1) ||
|
(accountCategory === "custom" &&
|
||||||
|
selectedAccount.length < 1) ||
|
||||||
(accountCategory === "kategori" && !selectedCategory)
|
(accountCategory === "kategori" && !selectedCategory)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -441,7 +457,47 @@ const AccountListTable = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* === Filter Akun === */}
|
{/* === Filter Akun === */}
|
||||||
<div className="flex justify-end">
|
<div className="flex flex-row 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">
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormDescription,
|
|
||||||
FormField,
|
FormField,
|
||||||
FormItem,
|
FormItem,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
|
|
@ -14,55 +13,80 @@ 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 { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
// ----------------------------
|
||||||
|
// ZOD SCHEMA (dinamis)
|
||||||
|
// ----------------------------
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
name: z.string({
|
name: z.string({ required_error: "Required" }),
|
||||||
required_error: "Required",
|
|
||||||
}),
|
|
||||||
accountType: z
|
accountType: z
|
||||||
.array(z.string())
|
.array(z.string())
|
||||||
.refine((value) => value.some((item) => item), {
|
.min(1, "Pilih minimal satu tipe akun"),
|
||||||
message: "Required",
|
|
||||||
}),
|
email: z.string().optional(),
|
||||||
accountCategory: z.enum(["polri", "jurnalis", "umum", "ksp"], {
|
whatsapp: z.string().optional(),
|
||||||
required_error: "Required",
|
|
||||||
}),
|
campaignId: z.string({ required_error: "Required" }),
|
||||||
email: z.string({
|
}).refine(
|
||||||
required_error: "Required",
|
(data) => {
|
||||||
}),
|
if (data.accountType.includes("email") && !data.email) return false;
|
||||||
whatsapp: z.string({
|
return true;
|
||||||
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: { accountType: [] },
|
defaultValues: {
|
||||||
|
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",
|
||||||
|
|
@ -85,10 +109,8 @@ export default function CreateAccountForBroadcast() {
|
||||||
icon: "success",
|
icon: "success",
|
||||||
confirmButtonColor: "#3085d6",
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: "OK",
|
confirmButtonText: "OK",
|
||||||
}).then((result) => {
|
}).then(() => {
|
||||||
if (result.isConfirmed) {
|
router.push("/admin/broadcast/campaign-list/account-list");
|
||||||
router.push("/admin/broadcast/campaign-list/account-list");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,20 +118,21 @@ export default function CreateAccountForBroadcast() {
|
||||||
const reqData = {
|
const reqData = {
|
||||||
accountName: data.name,
|
accountName: data.name,
|
||||||
accountType: data.accountType.join(","),
|
accountType: data.accountType.join(","),
|
||||||
accountCategory: data.accountCategory,
|
emailAddress: data.email ?? "",
|
||||||
emailAddress: data.email,
|
whatsappNumber: data.whatsapp ?? "",
|
||||||
whatsappNumber: data.whatsapp,
|
campaignId: data.campaignId,
|
||||||
};
|
};
|
||||||
// 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 false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
successSubmit();
|
successSubmit();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SiteBreadcrumb />
|
<SiteBreadcrumb />
|
||||||
|
|
@ -118,7 +141,9 @@ 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="fonnt-semibold">Account</p>
|
<p className="font-semibold">Account</p>
|
||||||
|
|
||||||
|
{/* NAMA */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="name"
|
name="name"
|
||||||
|
|
@ -130,172 +155,125 @@ 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={() => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Tipe Akun</FormLabel>
|
<FormLabel>Tipe Akun</FormLabel>
|
||||||
<div className="flex flex-row gap-2">
|
<div className="flex flex-row gap-4">
|
||||||
{" "}
|
{/* WA */}
|
||||||
<FormField
|
<div className="flex items-center gap-2">
|
||||||
key="wa"
|
<Checkbox
|
||||||
control={form.control}
|
checked={field.value.includes("wa")}
|
||||||
name="accountType"
|
onCheckedChange={(checked) =>
|
||||||
render={({ field }) => {
|
checked
|
||||||
return (
|
? field.onChange([...field.value, "wa"])
|
||||||
<FormItem
|
: field.onChange(field.value.filter((v) => v !== "wa"))
|
||||||
key="wa"
|
}
|
||||||
className="flex flex-row items-start space-x-3 space-y-0"
|
/>
|
||||||
>
|
<label>Whatsapp</label>
|
||||||
<FormControl>
|
</div>
|
||||||
<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>
|
|
||||||
|
|
||||||
|
{/* EMAIL */}
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Checkbox
|
||||||
|
checked={field.value.includes("email")}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
checked
|
||||||
|
? field.onChange([...field.value, "email"])
|
||||||
|
: field.onChange(
|
||||||
|
field.value.filter((v) => v !== "email")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<label>Email</label>
|
||||||
|
</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="accountCategory"
|
name="campaignId"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="space-y-3">
|
<FormItem>
|
||||||
<FormLabel>Kategori</FormLabel>
|
<FormLabel>Campaign</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RadioGroup
|
<select
|
||||||
onValueChange={field.onChange}
|
className="w-full border rounded-md p-2 text-sm"
|
||||||
defaultValue={field.value}
|
value={field.value}
|
||||||
className="flex flex-row gap-2"
|
onChange={field.onChange}
|
||||||
>
|
>
|
||||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
<option value="" className="text-slate-400">
|
||||||
<FormControl>
|
Pilih campaign
|
||||||
<RadioGroupItem value="polri" />
|
</option>
|
||||||
</FormControl>
|
|
||||||
<FormLabel className="font-normal">POLRI</FormLabel>
|
{campaigns.map((c: any) => (
|
||||||
</FormItem>
|
<option key={c.id} value={c.id}>
|
||||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
{c.title || `Campaign ${c.id}`}
|
||||||
<FormControl>
|
</option>
|
||||||
<RadioGroupItem value="jurnalis" />
|
))}
|
||||||
</FormControl>
|
</select>
|
||||||
<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}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
{/* BUTTON */}
|
||||||
</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
|
<Button type="button" variant="outline" color="destructive">
|
||||||
size="md"
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
color="destructive"
|
|
||||||
className="text-xs"
|
|
||||||
>
|
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="md" type="submit" color="primary" className="text-xs">
|
<Button type="submit" color="primary">
|
||||||
Submit
|
Submit
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -304,3 +282,380 @@ 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>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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} />
|
||||||
|
|
|
||||||
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export default function CreateEmailBlast() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SiteBreadcrumb />
|
<SiteBreadcrumb />
|
||||||
<ContentBlast type="email" />
|
<ContentBlast />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -90,16 +90,16 @@ const columns: ColumnDef<any>[] = [
|
||||||
Detail
|
Detail
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href={`/admin/broadcast/email/${row.original.id}`}>
|
<Link href={`/admin/broadcast/create/${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 Blast
|
Email & Whatsapp 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>
|
||||||
);
|
);
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||||
import BroadcastTable from "./email/component/table";
|
import BroadcastTable from "./create/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 "./email/component/table";
|
import BroadcastEmailTable from "./create/component/table";
|
||||||
import BroadcastWhatsAppTable from "./whatsapp/component/table";
|
import BroadcastWhatsAppTable from "./whatsapp/component/table";
|
||||||
|
|
||||||
export default function AdminBroadcast() {
|
export default function AdminBroadcast() {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export default function CreateWABlast() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SiteBreadcrumb />
|
<SiteBreadcrumb />
|
||||||
<ContentBlast type="wa" />
|
{/* <ContentBlast /> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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("&")}`);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ 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>[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -52,12 +54,132 @@ 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 }) => {
|
||||||
<span className="normal-case">{row.getValue("link")}</span>
|
const link = row.getValue<string>("link");
|
||||||
),
|
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,18 @@ 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,
|
||||||
|
|
@ -154,7 +166,7 @@ const NewsDetailTable = () => {
|
||||||
pageIndex: 0,
|
pageIndex: 0,
|
||||||
pageSize: Number(showData),
|
pageSize: Number(showData),
|
||||||
});
|
});
|
||||||
}, [page, showData]);
|
}, [page, showData, id]);
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
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 { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
|
import { loading, close } from "@/config/swal";
|
||||||
|
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,
|
||||||
|
|
@ -45,19 +53,101 @@ const columns: ColumnDef<any>[] = [
|
||||||
cell: ({ row }) => <span>{row.getValue("title")}</span>,
|
cell: ({ row }) => <span>{row.getValue("title")}</span>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "link",
|
accessorKey: "resultTotal",
|
||||||
header: "Jumlah Amplifikasi",
|
header: () => <div className="text-center w-full">Total Artikel</div>,
|
||||||
cell: ({ row }) => <span>{row.getValue("link")}</span>,
|
cell: ({ row }) => {
|
||||||
|
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: "status",
|
accessorKey: "amplification",
|
||||||
header: "Status",
|
header: () => <div className="text-center w-full">Jumlah Amplifikasi</div>,
|
||||||
cell: ({ row }) => <span>{row.getValue("status")}</span>,
|
cell: ({ row }) => {
|
||||||
|
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: "date",
|
accessorKey: "isProcessing",
|
||||||
header: "Tanggal Penarikan",
|
header: () => <div className="text-center">Status</div>,
|
||||||
cell: ({ row }) => <span>{row.getValue("date")}</span>,
|
cell: ({ row }) => {
|
||||||
|
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",
|
||||||
|
|
@ -78,13 +168,31 @@ 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 text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
<DropdownMenuItem className="p-2 border-b cursor-pointer text-default-700 group focus:bg-default focus:text-primary-foreground items-center rounded-none">
|
||||||
<Eye className="w-4 h-4 me-1.5" />
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
View
|
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>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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("&")}`);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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("&")}`);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export default function TrackingBeritaCard() {
|
||||||
|
|
||||||
const initFecth = async () => {
|
const initFecth = async () => {
|
||||||
loading();
|
loading();
|
||||||
const response = await listDataTracking(showData, page - 1);
|
const response = await listDataTracking(Number(showData), page - 1, search);
|
||||||
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,23 +56,85 @@ export default function TrackingBeritaCard() {
|
||||||
setContent(response?.data?.data?.content || []);
|
setContent(response?.data?.data?.content || []);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
setSearch(value);
|
setSearch(value);
|
||||||
|
|
||||||
if (value.trim() === "") {
|
const response = await listDataTracking(Number(showData), 0, value);
|
||||||
initFecth();
|
setContent(response?.data?.data?.content || []);
|
||||||
} 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.");
|
||||||
|
|
@ -99,48 +161,63 @@ 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 (
|
||||||
|
|
@ -188,7 +265,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 {29 - selectedItems.length}
|
/ Tracking Berita tersisa {5 - selectedItems.length}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<Button className="bg-blue-600 text-white" onClick={doSave}>
|
<Button className="bg-blue-600 text-white" onClick={doSave}>
|
||||||
|
|
@ -198,6 +275,48 @@ 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
|
||||||
|
|
@ -222,7 +341,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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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({
|
||||||
|
|
|
||||||
|
|
@ -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({
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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(",")
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,9 @@ 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);
|
||||||
|
|
@ -153,9 +155,11 @@ 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] = useState(false);
|
const [isUpdatingFromJenisAgenda, setIsUpdatingFromJenisAgenda] =
|
||||||
|
useState(false);
|
||||||
// State untuk melacak jenis perubahan spesifik
|
// State untuk melacak jenis perubahan spesifik
|
||||||
const [jenisAgendaChangeType, setJenisAgendaChangeType] = useState<string>("");
|
const [jenisAgendaChangeType, setJenisAgendaChangeType] =
|
||||||
|
useState<string>("");
|
||||||
|
|
||||||
const levelNumber = Number(getCookiesDecrypt("ulne")) || 0;
|
const levelNumber = Number(getCookiesDecrypt("ulne")) || 0;
|
||||||
const userLevelId = getCookiesDecrypt("ulie");
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
|
|
@ -261,7 +265,11 @@ const EventModal = ({
|
||||||
|
|
||||||
// useEffect untuk sinkronisasi checkbox modal dengan Jenis Agenda
|
// useEffect untuk sinkronisasi checkbox modal dengan Jenis Agenda
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (listDest.length > 0 && isUpdatingFromJenisAgenda && jenisAgendaChangeType) {
|
if (
|
||||||
|
listDest.length > 0 &&
|
||||||
|
isUpdatingFromJenisAgenda &&
|
||||||
|
jenisAgendaChangeType
|
||||||
|
) {
|
||||||
syncModalWithJenisAgenda();
|
syncModalWithJenisAgenda();
|
||||||
}
|
}
|
||||||
}, [isUpdatingFromJenisAgenda, jenisAgendaChangeType]);
|
}, [isUpdatingFromJenisAgenda, jenisAgendaChangeType]);
|
||||||
|
|
@ -273,44 +281,55 @@ 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((item: any) =>
|
const checkedPoldaCount = listDest.filter(
|
||||||
item.levelNumber === 2 &&
|
(item: any) =>
|
||||||
item.name !== "SATKER POLRI" &&
|
item.levelNumber === 2 &&
|
||||||
checkedLevels.has(Number(item.id))
|
item.name !== "SATKER POLRI" &&
|
||||||
|
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 total + item.subDestination.filter((sub: any) => checkedLevels.has(Number(sub.id))).length;
|
return (
|
||||||
|
total +
|
||||||
|
item.subDestination.filter((sub: any) =>
|
||||||
|
checkedLevels.has(Number(sub.id))
|
||||||
|
).length
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
|
const satkerItem: any = listDest.find(
|
||||||
const checkedSatkerCount = satkerItem ? (
|
(item: any) => item.name === "SATKER POLRI"
|
||||||
(checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) +
|
);
|
||||||
(satkerItem.subDestination?.filter((sub: any) => checkedLevels.has(Number(sub.id))).length || 0)
|
const checkedSatkerCount = satkerItem
|
||||||
) : 0;
|
? (checkedLevels.has(Number(satkerItem.id)) ? 1 : 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((item: any) =>
|
.filter(
|
||||||
item.levelNumber === 2 &&
|
(item: any) =>
|
||||||
item.name !== "SATKER POLRI" &&
|
item.levelNumber === 2 &&
|
||||||
checkedLevels.has(Number(item.id))
|
item.name !== "SATKER POLRI" &&
|
||||||
|
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) {
|
||||||
|
|
@ -321,7 +340,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))) {
|
||||||
|
|
@ -335,51 +354,56 @@ 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.nasional && hasSelectedPolda && hasSelectedPolres && hasSelectedSatker && newState.international;
|
newState.semua =
|
||||||
|
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
|
||||||
|
|
@ -391,7 +415,11 @@ 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 (item.levelNumber === 2 && item.name !== "SATKER POLRI" && newCheckedLevels.has(Number(item.id))) {
|
if (
|
||||||
|
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));
|
||||||
|
|
@ -401,7 +429,9 @@ const EventModal = ({
|
||||||
});
|
});
|
||||||
} else if (jenisAgendaChangeType === "satker_checked") {
|
} else if (jenisAgendaChangeType === "satker_checked") {
|
||||||
// Checklist satker
|
// Checklist satker
|
||||||
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
|
const satkerItem: any = listDest.find(
|
||||||
|
(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) {
|
||||||
|
|
@ -434,10 +464,12 @@ 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((item: any) => item.name === "SATKER POLRI");
|
const satkerItem: any = listDest.find(
|
||||||
|
(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) {
|
||||||
|
|
@ -447,9 +479,9 @@ const EventModal = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCheckedLevels(newCheckedLevels);
|
setCheckedLevels(newCheckedLevels);
|
||||||
|
|
||||||
// Reset flag setelah sinkronisasi selesai
|
// Reset flag setelah sinkronisasi selesai
|
||||||
setIsUpdatingFromJenisAgenda(false);
|
setIsUpdatingFromJenisAgenda(false);
|
||||||
setJenisAgendaChangeType("");
|
setJenisAgendaChangeType("");
|
||||||
|
|
@ -484,12 +516,14 @@ 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((item: any) => Number(item.id) === levelId) as any;
|
const poldaItem = listDest.find(
|
||||||
|
(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));
|
||||||
|
|
@ -514,7 +548,12 @@ 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(key + (wilayahPublish[key as keyof typeof wilayahPublish] ? "_unchecked" : "_checked"));
|
setJenisAgendaChangeType(
|
||||||
|
key +
|
||||||
|
(wilayahPublish[key as keyof typeof wilayahPublish]
|
||||||
|
? "_unchecked"
|
||||||
|
: "_checked")
|
||||||
|
);
|
||||||
|
|
||||||
setWilayahPublish((prev: any) => {
|
setWilayahPublish((prev: any) => {
|
||||||
let newState = { ...prev };
|
let newState = { ...prev };
|
||||||
|
|
@ -551,18 +590,21 @@ 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((item: any) =>
|
const hasSelectedPolda = listDest.some(
|
||||||
item.levelNumber === 2 &&
|
(item: any) =>
|
||||||
item.name !== "SATKER POLRI" &&
|
item.levelNumber === 2 &&
|
||||||
checkedLevels.has(Number(item.id))
|
item.name !== "SATKER POLRI" &&
|
||||||
|
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("Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.");
|
alert(
|
||||||
|
"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("");
|
||||||
|
|
@ -598,7 +640,9 @@ const EventModal = ({
|
||||||
});
|
});
|
||||||
} else if (key === "satker") {
|
} else if (key === "satker") {
|
||||||
// Clear satker
|
// Clear satker
|
||||||
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
|
const satkerItem: any = listDest.find(
|
||||||
|
(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) {
|
||||||
|
|
@ -613,9 +657,14 @@ 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.nasional && newState.polda && newState.polres && newState.satker && newState.international;
|
newState.semua =
|
||||||
|
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 {
|
||||||
|
|
@ -677,7 +726,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) {
|
||||||
|
|
@ -745,6 +794,9 @@ 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,
|
||||||
|
|
@ -767,7 +819,7 @@ const EventModal = ({
|
||||||
|
|
||||||
const onDeleteEventAction = async () => {
|
const onDeleteEventAction = async () => {
|
||||||
try {
|
try {
|
||||||
} catch (error) { }
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenDeleteModal = (eventId: string) => {
|
const handleOpenDeleteModal = (eventId: string) => {
|
||||||
|
|
@ -777,7 +829,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],
|
||||||
|
|
@ -838,11 +890,10 @@ 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,
|
||||||
};
|
};
|
||||||
|
|
@ -864,7 +915,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: (
|
||||||
|
|
@ -947,7 +998,7 @@ const EventModal = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveFile = (id: number) => { };
|
const handleRemoveFile = (id: number) => {};
|
||||||
|
|
||||||
async function doDelete(id: any) {
|
async function doDelete(id: any) {
|
||||||
loading();
|
loading();
|
||||||
|
|
@ -986,7 +1037,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;
|
||||||
|
|
@ -1088,7 +1139,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);
|
||||||
|
|
@ -1103,40 +1154,42 @@ 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
|
|
||||||
id="semua"
|
|
||||||
checked={wilayahPublish.semua}
|
|
||||||
onCheckedChange={() => toggleWilayah("semua")}
|
|
||||||
/>
|
|
||||||
<label htmlFor="semua" className="ml-2 text-sm">
|
|
||||||
Semua
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{levelNumber === 1 && (
|
|
||||||
<>
|
|
||||||
<div>
|
|
||||||
<Checkbox
|
|
||||||
id="nasional"
|
|
||||||
checked={wilayahPublish.nasional}
|
|
||||||
onCheckedChange={() => toggleWilayah("nasional")}
|
|
||||||
/>
|
|
||||||
<label htmlFor="nasional" className="ml-2 text-sm mr-2">
|
|
||||||
Nasional
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id="polda"
|
id="semua"
|
||||||
checked={wilayahPublish.polda}
|
checked={wilayahPublish.semua}
|
||||||
onCheckedChange={() => toggleWilayah("polda")}
|
onCheckedChange={() => toggleWilayah("semua")}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="polda" className="mx-2 text-sm mr-2">
|
<label htmlFor="semua" className="ml-2 text-sm">
|
||||||
Polda
|
Semua
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{levelNumber === 1 && (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<Checkbox
|
||||||
|
id="nasional"
|
||||||
|
checked={wilayahPublish.nasional}
|
||||||
|
onCheckedChange={() => toggleWilayah("nasional")}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="nasional"
|
||||||
|
className="ml-2 text-sm mr-2"
|
||||||
|
>
|
||||||
|
Nasional
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Checkbox
|
||||||
|
id="polda"
|
||||||
|
checked={wilayahPublish.polda}
|
||||||
|
onCheckedChange={() => toggleWilayah("polda")}
|
||||||
|
/>
|
||||||
|
<label htmlFor="polda" className="mx-2 text-sm mr-2">
|
||||||
|
Polda
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -1148,39 +1201,41 @@ 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={() => toggleWilayah("international")}
|
onCheckedChange={() =>
|
||||||
/>
|
toggleWilayah("international")
|
||||||
<label
|
}
|
||||||
htmlFor="international"
|
/>
|
||||||
className="ml-2 text-sm mr-2"
|
<label
|
||||||
>
|
htmlFor="international"
|
||||||
Internasional
|
className="ml-2 text-sm mr-2"
|
||||||
</label>
|
>
|
||||||
</div>
|
Internasional
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="pl-1">
|
<div className="pl-1">
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
|
|
@ -1199,7 +1254,9 @@ 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(Number(polda.id))}
|
checked={checkedLevels.has(
|
||||||
|
Number(polda.id)
|
||||||
|
)}
|
||||||
onCheckedChange={() =>
|
onCheckedChange={() =>
|
||||||
handleCheckboxChange(Number(polda.id))
|
handleCheckboxChange(Number(polda.id))
|
||||||
}
|
}
|
||||||
|
|
@ -1237,9 +1294,13 @@ const EventModal = ({
|
||||||
polda?.subDestination?.forEach(
|
polda?.subDestination?.forEach(
|
||||||
(polres: any) => {
|
(polres: any) => {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
updatedLevels.add(Number(polres.id));
|
updatedLevels.add(
|
||||||
|
Number(polres.id)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
updatedLevels.delete(Number(polres.id));
|
updatedLevels.delete(
|
||||||
|
Number(polres.id)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -1249,18 +1310,27 @@ const EventModal = ({
|
||||||
/>
|
/>
|
||||||
Pilih Semua
|
Pilih Semua
|
||||||
</Label>
|
</Label>
|
||||||
{polda?.subDestination?.map((polres: any) => (
|
{polda?.subDestination?.map(
|
||||||
<Label key={polres.id} className="block mt-1">
|
(polres: any) => (
|
||||||
<Checkbox
|
<Label
|
||||||
checked={checkedLevels.has(Number(polres.id))}
|
key={polres.id}
|
||||||
onCheckedChange={() =>
|
className="block mt-1"
|
||||||
handleCheckboxChange(Number(polres.id))
|
>
|
||||||
}
|
<Checkbox
|
||||||
className="mr-2"
|
checked={checkedLevels.has(
|
||||||
/>
|
Number(polres.id)
|
||||||
{polres.name}
|
)}
|
||||||
</Label>
|
onCheckedChange={() =>
|
||||||
))}
|
handleCheckboxChange(
|
||||||
|
Number(polres.id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="mr-2"
|
||||||
|
/>
|
||||||
|
{polres.name}
|
||||||
|
</Label>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1301,8 +1371,7 @@ const EventModal = ({
|
||||||
<Label>Video</Label>
|
<Label>Video</Label>
|
||||||
<FileUploader
|
<FileUploader
|
||||||
accept={{
|
accept={{
|
||||||
"mp4/*": [],
|
"video/*": [],
|
||||||
"mov/*": [],
|
|
||||||
}}
|
}}
|
||||||
maxSize={100}
|
maxSize={100}
|
||||||
label="Upload file dengan format .mp4 atau .mov."
|
label="Upload file dengan format .mp4 atau .mov."
|
||||||
|
|
@ -1314,7 +1383,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}`} // Mengganti alt dengan title
|
title={`Video ${file.id}`}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
|
|
@ -1393,10 +1462,9 @@ const EventModal = ({
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label>Teks</Label>
|
<Label>Teks</Label>
|
||||||
|
|
||||||
<FileUploader
|
<FileUploader
|
||||||
accept={{
|
accept={{
|
||||||
"pdf/*": [],
|
"application/pdf": [],
|
||||||
}}
|
}}
|
||||||
maxSize={100}
|
maxSize={100}
|
||||||
label="Upload file dengan format .pdf."
|
label="Upload file dengan format .pdf."
|
||||||
|
|
@ -1452,8 +1520,7 @@ const EventModal = ({
|
||||||
/>
|
/>
|
||||||
<FileUploader
|
<FileUploader
|
||||||
accept={{
|
accept={{
|
||||||
"mp3/*": [],
|
"audio/*": [],
|
||||||
"wav/*": [],
|
|
||||||
}}
|
}}
|
||||||
maxSize={100}
|
maxSize={100}
|
||||||
label="Upload file dengan format .mp3 atau .wav."
|
label="Upload file dengan format .mp3 atau .wav."
|
||||||
|
|
@ -1479,7 +1546,8 @@ const EventModal = ({
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onPlayPause}
|
onClick={onPlayPause}
|
||||||
disabled={isPlaying}
|
disabled={isPlaying}
|
||||||
className={`flex items-center gap-2 ${isPlaying
|
className={`flex items-center gap-2 ${
|
||||||
|
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`}
|
||||||
|
|
|
||||||
|
|
@ -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 != 771) {
|
} else if (userLevelNumber == 2 && userLevelId != 761) {
|
||||||
valueShowed = ["2", "3"];
|
valueShowed = ["2", "3"];
|
||||||
} else if (
|
} else if (
|
||||||
(userLevelNumber == 2 && userLevelId == 771) ||
|
(userLevelNumber == 2 && userLevelId == 761) ||
|
||||||
(userLevelNumber == 3 && userParentLevelId == 771)
|
(userLevelNumber == 3 && userParentLevelId == 761)
|
||||||
) {
|
) {
|
||||||
valueShowed = ["4"];
|
valueShowed = ["4"];
|
||||||
} else if (userLevelNumber == 3 && userParentLevelId != 771) {
|
} else if (userLevelNumber == 3 && userParentLevelId != 761) {
|
||||||
valueShowed = ["3"];
|
valueShowed = ["3"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ const CalenderPage = () => {
|
||||||
...category,
|
...category,
|
||||||
activeClass: "",
|
activeClass: "",
|
||||||
}));
|
}));
|
||||||
// console.log(formattedCategories);
|
console.log(formattedCategories);
|
||||||
setCategories(formattedCategories);
|
setCategories(formattedCategories);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
displayText = "Satker";
|
displayText = "Satker";
|
||||||
} else {
|
} else {
|
||||||
displayText = "Polda";
|
displayText = "Polda";
|
||||||
|
|
|
||||||
|
|
@ -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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
displayText = "Satker";
|
displayText = "Satker";
|
||||||
} else {
|
} else {
|
||||||
displayText = "Polda";
|
displayText = "Polda";
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
displayText = "Satker";
|
displayText = "Satker";
|
||||||
} else {
|
} else {
|
||||||
displayText = "Polda";
|
displayText = "Polda";
|
||||||
|
|
|
||||||
|
|
@ -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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
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) == 771) {
|
if (Number(creatorGroupParentLevelId) == 761) {
|
||||||
displayText = "Satker";
|
displayText = "Satker";
|
||||||
} else {
|
} else {
|
||||||
displayText = "Polda";
|
displayText = "Polda";
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ 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 ? (
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,9 @@ 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);
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ 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 ? (
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,9 @@ 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);
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ const useTableColumns = ({
|
||||||
// try {
|
// try {
|
||||||
// loading();
|
// loading();
|
||||||
// const response = await axios.get(
|
// const response = await axios.get(
|
||||||
// `https://netidhub.com/api/media/report/download?id=${id}`,
|
// `https://new.netidhub.com/api/media/report/download?id=${id}`,
|
||||||
// {
|
// {
|
||||||
// responseType: "blob",
|
// responseType: "blob",
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ const ReportTable = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePreview = (id: string) => {
|
const handlePreview = (id: string) => {
|
||||||
const url = `https://mediahub.polri.go.id/api/v2/media/report/view?id=${id}`;
|
const url = `https://new.netidhub.com/api/media/report/view?id=${id}`;
|
||||||
setPreviewData({ url });
|
setPreviewData({ url });
|
||||||
setOpenPreview(true);
|
setOpenPreview(true);
|
||||||
};
|
};
|
||||||
|
|
@ -223,6 +223,9 @@ 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);
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,9 @@ 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);
|
||||||
|
|
|
||||||
|
|
@ -62,6 +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);
|
||||||
const { startTime, endTime } = row.original;
|
const { startTime, endTime } = row.original;
|
||||||
return (
|
return (
|
||||||
<span className="whitespace-nowrap">
|
<span className="whitespace-nowrap">
|
||||||
|
|
@ -112,6 +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);
|
||||||
const { speakerTitle, speakerName } = row.original;
|
const { speakerTitle, speakerName } = row.original;
|
||||||
return (
|
return (
|
||||||
<span className="whitespace-nowrap">
|
<span className="whitespace-nowrap">
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,9 @@ 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);
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ 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>[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -113,6 +115,31 @@ 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);
|
||||||
|
|
@ -165,7 +192,11 @@ 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" />
|
||||||
|
|
@ -173,15 +204,16 @@ const useTableColumns = () => {
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
{roleId == 11 && (
|
{roleId == 11 ||
|
||||||
<Link href={`/contributor/task-ta/update/${row.original.id}`}>
|
(roleId == 3 && (
|
||||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
<Link href={`/contributor/task-ta/update/${row.original.id}`}>
|
||||||
<SquarePen className="w-4 h-4 me-1.5" />
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
Edit
|
<SquarePen className="w-4 h-4 me-1.5" />
|
||||||
</DropdownMenuItem>
|
Edit
|
||||||
</Link>
|
</DropdownMenuItem>
|
||||||
)}
|
</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}`}
|
||||||
>
|
>
|
||||||
|
|
@ -191,15 +223,16 @@ const useTableColumns = () => {
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
{roleId == 11 && (
|
{roleId == 11 ||
|
||||||
<DropdownMenuItem
|
(roleId == 3 && (
|
||||||
onClick={() => TaskDelete(row.original.id)}
|
<DropdownMenuItem
|
||||||
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
|
onClick={() => TaskDelete(row.original.id)}
|
||||||
>
|
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"
|
||||||
<Trash2 className="w-4 h-4 me-1.5" />
|
>
|
||||||
Delete
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
</DropdownMenuItem>
|
Delete
|
||||||
)}
|
</DropdownMenuItem>
|
||||||
|
))}
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -35,10 +35,19 @@ 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("task-ta", { defaultValue: "Task Ta" })}
|
{t("tabel", { defaultValue: "Tabel" })}{" "}
|
||||||
|
{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" />
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@ 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 { checkAuthorization, checkLoginSession } from "@/lib/utils";
|
import {
|
||||||
|
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";
|
||||||
|
|
||||||
|
|
@ -13,12 +17,13 @@ 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>
|
||||||
|
|
@ -29,16 +34,28 @@ 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("task", { defaultValue: "Task" })}
|
{t("tabel", { defaultValue: "Tabel" })}{" "}
|
||||||
|
{t("task", { defaultValue: "Task" })}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-none">
|
{Number(levelNumber) !== 3 && (
|
||||||
|
<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>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -113,12 +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);
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,8 @@ 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));
|
||||||
|
|
@ -203,7 +205,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",
|
||||||
|
|
@ -232,7 +234,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 = {
|
||||||
|
|
@ -256,7 +258,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) {
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,8 @@ 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));
|
||||||
|
|
@ -216,7 +218,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",
|
||||||
|
|
@ -245,7 +247,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 = {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -76,9 +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);
|
||||||
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)
|
||||||
|
|
@ -125,7 +127,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) {
|
||||||
|
|
@ -152,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 (
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,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);
|
||||||
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 +129,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) {
|
||||||
|
|
@ -154,7 +156,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 (
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,8 @@ 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));
|
||||||
|
|
@ -203,7 +205,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",
|
||||||
|
|
@ -232,7 +234,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 = {
|
||||||
|
|
@ -256,7 +258,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) {
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,8 @@ 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));
|
||||||
|
|
@ -216,7 +218,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",
|
||||||
|
|
@ -245,7 +247,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 = {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
||||||
|
|
|
||||||
|
|
@ -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
Loading…
Reference in New Issue