feat:update calendar-polri
This commit is contained in:
parent
5b6ba3e23d
commit
88501ac84f
|
|
@ -45,18 +45,20 @@ const columns: ColumnDef<any>[] = [
|
|||
{
|
||||
accessorKey: "title",
|
||||
header: "Judul",
|
||||
cell: ({ row }) => <span>{row.getValue("title")}</span>,
|
||||
cell: ({ row }) => <div className="w-[150px]">{row.getValue("title")}</div>,
|
||||
},
|
||||
{
|
||||
accessorKey: "categoryName",
|
||||
header: "Kategori",
|
||||
cell: ({ row }) => <span>{row.getValue("categoryName")}</span>,
|
||||
},
|
||||
{
|
||||
accessorKey: "createdAt",
|
||||
header: "Tanggal Unggah",
|
||||
accessorKey: "contentFileName",
|
||||
header: "Judul Gambar",
|
||||
cell: ({ row }) => (
|
||||
<span>{formatDateToIndonesian(row.getValue("createdAt"))}</span>
|
||||
<div className="w-[450px]">{row.getValue("contentFileName")}</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "placements",
|
||||
header: "Posisi",
|
||||
cell: ({ row }) => (
|
||||
<div className="w-[150px]">{row.getValue("placements")}</div>
|
||||
),
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -61,14 +61,17 @@ import {
|
|||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { listDataMedia } from "@/service/broadcast/broadcast";
|
||||
import {
|
||||
listDataAdvertisements,
|
||||
listDataMedia,
|
||||
} from "@/service/broadcast/broadcast";
|
||||
import { listEnableCategory } from "@/service/content/content";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { close, loading } from "@/config/swal";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import { TambahIklanModal } from "@/components/form/setting/form-add-iklan";
|
||||
|
||||
const IklanList = () => {
|
||||
const AdvertisementsList = () => {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const [showData, setShowData] = React.useState("10");
|
||||
|
|
@ -146,7 +149,7 @@ const IklanList = () => {
|
|||
async function fetchData() {
|
||||
try {
|
||||
loading();
|
||||
const res = await listDataMedia(
|
||||
const res = await listDataAdvertisements(
|
||||
page - 1,
|
||||
showData,
|
||||
"",
|
||||
|
|
@ -395,4 +398,4 @@ const IklanList = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default IklanList;
|
||||
export default AdvertisementsList;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
"use client";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import PopUpList from "../popup/component/table";
|
||||
import PopUpListTable from "../popup/component/popup-table";
|
||||
import IklanList from "./component/table";
|
||||
import IklanListTable from "./component/popup-table";
|
||||
import AdvertisementsList from "./component/table";
|
||||
|
||||
export default function AdminIklan() {
|
||||
export default function AdminAdvertisements() {
|
||||
const [selectedTab, setSelectedTab] = useState("content");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="w-full overflow-x-auto bg-white p-4 rounded-sm space-y-3">
|
||||
<IklanList />
|
||||
<AdvertisementsList />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,10 @@ import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
|||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import TablePagination from "@/components/table/table-pagination";
|
||||
import columns from "./columns";
|
||||
import { paginationSchedule } from "@/service/schedule/schedule";
|
||||
import {
|
||||
paginationCalendar,
|
||||
paginationSchedule,
|
||||
} from "@/service/schedule/schedule";
|
||||
import { CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
|
@ -117,7 +120,7 @@ const CalendarPolriTable = () => {
|
|||
|
||||
async function fetchData() {
|
||||
try {
|
||||
const res = await paginationSchedule(
|
||||
const res = await paginationCalendar(
|
||||
showData,
|
||||
page - 1,
|
||||
1,
|
||||
|
|
@ -162,7 +165,12 @@ const CalendarPolriTable = () => {
|
|||
{t("calendar-polri")} {t("schedule")}
|
||||
</div>
|
||||
<div className="flex-none">
|
||||
<CalendarPolriAdd />
|
||||
<Link href={"/contributor/schedule/calendar-polri/create"}>
|
||||
<Button color="primary" className="text-white" size="md">
|
||||
<UploadIcon size={18} className="mr-2" />
|
||||
Buat Kalender Polri
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</CardTitle>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ import { Button } from "@/components/ui/button";
|
|||
import { Badge } from "@/components/ui/badge";
|
||||
import { Link } from "@/components/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import { error } from "@/lib/swal";
|
||||
import { deleteCalendar } from "@/service/schedule/schedule";
|
||||
|
||||
const useTableColumns = () => {
|
||||
const t = useTranslations("Table"); // Panggil di dalam hook
|
||||
|
|
@ -58,76 +62,33 @@ const useTableColumns = () => {
|
|||
<span className="whitespace-nowrap">{row.getValue("endDate")}</span>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
accessorKey: "time",
|
||||
header: t("time"),
|
||||
cell: ({ row }: { row: { original: any } }) => {
|
||||
console.log("Row Original Data:", row.original);
|
||||
const { startTime, endTime } = row.original;
|
||||
return (
|
||||
<span className="whitespace-nowrap">
|
||||
{startTime || "N/A"} - {endTime || "N/A"}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "address",
|
||||
header: t("address"),
|
||||
cell: ({ row }: { row: { getValue: (key: string) => string } }) => {
|
||||
const address: string = row.getValue("address");
|
||||
return (
|
||||
<span className="whitespace-nowrap">
|
||||
{address.length > 50 ? `${address.slice(0, 40)}...` : address}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "statusName",
|
||||
accessorKey: "isActive",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
const statusColors: Record<string, string> = {
|
||||
diterima: "bg-green-100 text-green-600",
|
||||
"menunggu review": "bg-orange-100 text-orange-600",
|
||||
};
|
||||
const isActive = row.getValue("isActive") as boolean;
|
||||
|
||||
// Mengambil `statusName` dari data API
|
||||
const status = row.getValue("statusName") as string;
|
||||
const statusName = status?.toLocaleLowerCase(); // Ubah ke huruf kecil
|
||||
|
||||
// Gunakan `statusName` untuk pencocokan
|
||||
const statusStyles =
|
||||
statusColors[statusName] || "bg-gray-100 text-gray-600";
|
||||
const status = isActive ? "Aktif" : "Tidak Aktif";
|
||||
const statusStyles = isActive
|
||||
? "bg-green-100 text-green-600"
|
||||
: "bg-gray-100 text-gray-600";
|
||||
|
||||
return (
|
||||
<Badge
|
||||
className={cn("rounded-full px-5 whitespace-nowrap", statusStyles)}
|
||||
>
|
||||
{status} {/* Tetap tampilkan nilai asli */}
|
||||
{status}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "speaker",
|
||||
header: t("speaker"),
|
||||
cell: ({ row }: { row: { original: any } }) => {
|
||||
console.log("Row Original Data:", row.original);
|
||||
const { speakerTitle, speakerName } = row.original;
|
||||
return (
|
||||
<span className="whitespace-nowrap">
|
||||
{speakerTitle || ""} {speakerName || ""}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "uploaderName",
|
||||
accessorKey: "createdByName",
|
||||
header: t("source"),
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("uploaderName")}
|
||||
{row.getValue("createdByName")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
|
|
@ -138,6 +99,51 @@ const useTableColumns = () => {
|
|||
header: t("action"),
|
||||
enableHiding: false,
|
||||
cell: ({ row }) => {
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
||||
async function doDelete(id: any) {
|
||||
// loading();
|
||||
const data = {
|
||||
id,
|
||||
};
|
||||
|
||||
const response = await deleteCalendar(id);
|
||||
|
||||
if (response?.error) {
|
||||
error(response.message);
|
||||
return false;
|
||||
}
|
||||
success();
|
||||
}
|
||||
|
||||
function success() {
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const handleDeleteCalendars = (id: any) => {
|
||||
MySwal.fire({
|
||||
title: "Hapus Data",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#3085d6",
|
||||
confirmButtonColor: "#d33",
|
||||
confirmButtonText: "Hapus",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
doDelete(id);
|
||||
}
|
||||
});
|
||||
};
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
|
@ -151,7 +157,7 @@ const useTableColumns = () => {
|
|||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="p-0" align="end">
|
||||
<Link
|
||||
href={`/contributor/schedule/press-conference/detail/${row.original.id}`}
|
||||
href={`/contributor/schedule/calendar-polri/detail/${row.original.id}`}
|
||||
>
|
||||
<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" />
|
||||
|
|
@ -159,14 +165,17 @@ const useTableColumns = () => {
|
|||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<Link
|
||||
href={`/contributor/schedule/press-conference/update/${row.original.id}`}
|
||||
href={`/contributor/schedule/calendar-polri/update/${row.original.id}`}
|
||||
>
|
||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||
<SquarePen className="w-4 h-4 me-1.5" />
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleDeleteCalendars(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
|
||||
</DropdownMenuItem>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ import { Card, CardContent } from "@/components/ui/card";
|
|||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import FormTask from "@/components/form/task/task-form";
|
||||
import FormPressConference from "@/components/form/schedule/press-conference-form";
|
||||
import { CalendarPolriAdd } from "@/components/form/schedule/form-calendar-polri";
|
||||
|
||||
const CalendarPolriCreatePage = () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormPressConference />
|
||||
<CalendarPolriAdd />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ import FormPressConference from "@/components/form/schedule/press-conference-for
|
|||
import FormDetailPressConference from "@/components/form/schedule/press-conference-detail-form";
|
||||
import { useParams } from "next/navigation";
|
||||
import { id } from "date-fns/locale";
|
||||
import { CalendarPolriAddDetail } from "@/components/form/schedule/form-calendar-polri-detail";
|
||||
|
||||
const CalendarPolriDetailPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormDetailPressConference />
|
||||
<CalendarPolriAddDetail />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,13 +7,14 @@ import FormDetailPressConference from "@/components/form/schedule/press-conferen
|
|||
import { useParams } from "next/navigation";
|
||||
import { id } from "date-fns/locale";
|
||||
import FormUpdatePressConference from "@/components/form/schedule/press-conference-update-form";
|
||||
import { CalendarPolriAddUpdate } from "@/components/form/schedule/form-calendar-polri-update";
|
||||
|
||||
const CalendarPolriUpdatePage = () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormUpdatePressConference />
|
||||
<CalendarPolriAddUpdate />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ export default function FormConvertSPIT() {
|
|||
const [filePlacements, setFilePlacements] = useState<string[][]>([]);
|
||||
const [isUserMabesApprover, setIsUserMabesApprover] = useState(false);
|
||||
const [files, setFiles] = useState<FileType[]>([]);
|
||||
const [selectedWritingStyle, setSelectedWritingStyle] =
|
||||
useState("profesional");
|
||||
|
||||
const options: Option[] = [
|
||||
{ id: "all", label: "SEMUA" },
|
||||
|
|
@ -494,7 +496,7 @@ export default function FormConvertSPIT() {
|
|||
|
||||
const handleRewriteClick = async () => {
|
||||
const request = {
|
||||
style: "friendly",
|
||||
style: selectedWritingStyle,
|
||||
lang: "id",
|
||||
contextType: "text",
|
||||
urlContext: null,
|
||||
|
|
@ -702,6 +704,28 @@ export default function FormConvertSPIT() {
|
|||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2 py-3 w-4/12">
|
||||
<Label>{t("writing-style")}</Label>
|
||||
<Select
|
||||
value={selectedWritingStyle}
|
||||
onValueChange={setSelectedWritingStyle}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="friendly">Friendly</SelectItem>
|
||||
<SelectItem value="profesional">
|
||||
Profesional
|
||||
</SelectItem>
|
||||
<SelectItem value="informational">
|
||||
Informational
|
||||
</SelectItem>
|
||||
<SelectItem value="neutral">Neutral</SelectItem>
|
||||
<SelectItem value="witty">Witty</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="my-2">
|
||||
<Button
|
||||
size="sm"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,482 @@
|
|||
// components/TambahIklanModal.tsx
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogTrigger,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { CalendarIcon, ChevronDown, ChevronUp, Plus } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import DatePicker from "react-datepicker";
|
||||
import { id } from "date-fns/locale";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import router from "next/router";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { date, z } from "zod";
|
||||
import { error } from "@/lib/swal";
|
||||
import { detailCalendar, postCalendar } from "@/service/schedule/schedule";
|
||||
import { DateRange } from "react-day-picker";
|
||||
import Cookies from "js-cookie";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { format, parseISO } from "date-fns";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getUserLevelForAssignments } from "@/service/task";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Link } from "@/i18n/routing";
|
||||
|
||||
const calendarSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
description: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
});
|
||||
|
||||
interface Detail {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export function CalendarPolriAddDetail() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const { id } = useParams() as { id: string };
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const t = useTranslations("Schedule");
|
||||
type CalendarSchema = z.infer<typeof calendarSchema>;
|
||||
const [eventDate, setEventDate] = React.useState<Date | null>(new Date());
|
||||
const [listDest, setListDest] = React.useState([]);
|
||||
const [checkedLevels, setCheckedLevels] = React.useState(new Set());
|
||||
const [expandedPolda, setExpandedPolda] = React.useState([{}]);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const [detail, setDetail] = React.useState<Detail>();
|
||||
const [date, setDate] = React.useState<DateRange | undefined>({
|
||||
from: new Date(2025, 0, 1),
|
||||
});
|
||||
const [refresh, setRefresh] = React.useState(false);
|
||||
|
||||
const [unitSelection, setUnitSelection] = React.useState({
|
||||
semua: false,
|
||||
mabes: false,
|
||||
polda: false,
|
||||
satker: false,
|
||||
internasional: false,
|
||||
});
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<CalendarSchema>({
|
||||
resolver: zodResolver(calendarSchema),
|
||||
defaultValues: {
|
||||
description: "",
|
||||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
async function initState() {
|
||||
if (id) {
|
||||
const response = await detailCalendar(id);
|
||||
const details = response?.data?.data;
|
||||
|
||||
setDetail(details);
|
||||
if (details) {
|
||||
setDate({
|
||||
from: parseISO(details.startDate),
|
||||
to: parseISO(details.endDate),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
initState();
|
||||
}, [refresh, setValue]);
|
||||
|
||||
React.useEffect(() => {
|
||||
async function fetchPoldaPolres() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const response = await getUserLevelForAssignments();
|
||||
setListDest(response?.data?.data.list);
|
||||
console.log("polda", response?.data?.data?.list);
|
||||
const initialExpandedState = response?.data?.data.list.reduce(
|
||||
(acc: any, polda: any) => {
|
||||
acc[polda.id] = false;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
setExpandedPolda(initialExpandedState);
|
||||
console.log("polres", initialExpandedState);
|
||||
} catch (error) {
|
||||
console.error("Error fetching Polda/Polres data:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
fetchPoldaPolres();
|
||||
}, []);
|
||||
|
||||
const handleCheckboxChange = (levelId: number) => {
|
||||
setCheckedLevels((prev) => {
|
||||
const updatedLevels = new Set(prev);
|
||||
if (updatedLevels.has(levelId)) {
|
||||
updatedLevels.delete(levelId);
|
||||
} else {
|
||||
updatedLevels.add(levelId);
|
||||
}
|
||||
return updatedLevels;
|
||||
});
|
||||
};
|
||||
|
||||
const handlePoldaPolresChange = () => {
|
||||
return Array.from(checkedLevels).join(","); // Mengonversi Set ke string
|
||||
};
|
||||
|
||||
const handleUnitChange = (
|
||||
key: keyof typeof unitSelection,
|
||||
value: boolean
|
||||
) => {
|
||||
if (key === "semua") {
|
||||
const newState = {
|
||||
semua: value,
|
||||
mabes: value,
|
||||
polda: value,
|
||||
satker: value,
|
||||
internasional: value,
|
||||
};
|
||||
setUnitSelection(newState);
|
||||
} else {
|
||||
const updatedSelection = {
|
||||
...unitSelection,
|
||||
[key]: value,
|
||||
};
|
||||
|
||||
const allChecked = ["mabes", "polda", "satker", "internasional"].every(
|
||||
(k) => updatedSelection[k as keyof typeof unitSelection]
|
||||
);
|
||||
|
||||
updatedSelection.semua = allChecked;
|
||||
|
||||
setUnitSelection(updatedSelection);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleExpand = (poldaId: any) => {
|
||||
setExpandedPolda((prev: any) => ({
|
||||
...prev,
|
||||
[poldaId]: !prev[poldaId],
|
||||
}));
|
||||
};
|
||||
|
||||
const save = async (data: CalendarSchema) => {
|
||||
const unitMapping = {
|
||||
allUnit: "0",
|
||||
mabes: "1",
|
||||
polda: "2",
|
||||
satker: "4",
|
||||
internasional: "5",
|
||||
};
|
||||
const assignmentToString = Object.keys(unitSelection)
|
||||
.filter((key) => unitSelection[key as keyof typeof unitSelection])
|
||||
.map((key) => unitMapping[key as keyof typeof unitMapping])
|
||||
.join(",");
|
||||
const requestData = {
|
||||
title: data.title,
|
||||
startDate: date?.from ? format(date.from, "yyyy-MM-dd") : null,
|
||||
endDate: date?.to ? format(date.to, "yyyy-MM-dd") : null,
|
||||
description: data.description,
|
||||
assignedTo: assignmentToString,
|
||||
assignedToLevel: handlePoldaPolresChange(),
|
||||
};
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
|
||||
const response = await postCalendar(requestData);
|
||||
if (response?.error) {
|
||||
error(response?.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
Cookies.set("scheduleId", response?.data?.data.id, {
|
||||
expires: 1,
|
||||
});
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
text: "Data berhasil disimpan.",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.reload();
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = (data: CalendarSchema) => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card className="px-3 py-3">
|
||||
{detail !== undefined ? (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<p className="font-medium mb-1">Tanggal Acara</p>
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild className="px-0">
|
||||
<Button
|
||||
size="md"
|
||||
id="date"
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[280px] lg:w-[250px] justify-start text-left font-normal border border-slate-300 px-0 md:px-0 lg:px-4",
|
||||
!date && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
<CalendarIcon size={15} className="mr-3" />
|
||||
{date?.from ? (
|
||||
date.to ? (
|
||||
<>
|
||||
{format(date.from, "LLL dd, y")} -{" "}
|
||||
{format(date.to, "LLL dd, y")}
|
||||
</>
|
||||
) : (
|
||||
format(date.from, "LLL dd, y")
|
||||
)
|
||||
) : (
|
||||
<span>Pick a date</span>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
initialFocus
|
||||
mode="range"
|
||||
defaultMonth={date?.from}
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
numberOfMonths={1}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium">Publish Area</p>
|
||||
<div className="flex flex-row">
|
||||
<div className="flex flex-wrap gap-3 lg:ml-3 ">
|
||||
{Object.keys(unitSelection).map((key) => (
|
||||
<div className="flex items-center gap-2" key={key}>
|
||||
<Checkbox
|
||||
id={key}
|
||||
checked={
|
||||
unitSelection[key as keyof typeof unitSelection]
|
||||
}
|
||||
onCheckedChange={(value) =>
|
||||
handleUnitChange(
|
||||
key as keyof typeof unitSelection,
|
||||
value as boolean
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Label htmlFor={key}>
|
||||
{key.charAt(0).toUpperCase() + key.slice(1)}
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className=" lg:pl-3">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="soft" size="sm" color="primary">
|
||||
[{t("custom")}]
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-[425px] md:max-w-[500px] lg:max-w-[1500px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Daftar Wilayah Polda dan Polres
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
|
||||
{listDest.map((polda: any) => (
|
||||
<div key={polda.id} className="border p-2">
|
||||
<Label className="flex items-center">
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(polda.id)}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChange(polda.id)
|
||||
}
|
||||
className="mr-3"
|
||||
/>
|
||||
{polda.name}
|
||||
<button
|
||||
onClick={() => toggleExpand(polda.id)}
|
||||
className="ml-2 focus:outline-none"
|
||||
>
|
||||
{expandedPolda[polda.id] ? (
|
||||
<ChevronUp size={16} />
|
||||
) : (
|
||||
<ChevronDown size={16} />
|
||||
)}
|
||||
</button>
|
||||
</Label>
|
||||
{expandedPolda[polda.id] && (
|
||||
<div className="ml-6 mt-2">
|
||||
<Label className="block">
|
||||
<Checkbox
|
||||
checked={polda?.subDestination?.every(
|
||||
(polres: any) =>
|
||||
checkedLevels.has(polres.id)
|
||||
)}
|
||||
onCheckedChange={(isChecked) => {
|
||||
const updatedLevels = new Set(
|
||||
checkedLevels
|
||||
);
|
||||
polda?.subDestination?.forEach(
|
||||
(polres: any) => {
|
||||
if (isChecked) {
|
||||
updatedLevels.add(polres.id);
|
||||
} else {
|
||||
updatedLevels.delete(polres.id);
|
||||
}
|
||||
}
|
||||
);
|
||||
setCheckedLevels(updatedLevels);
|
||||
}}
|
||||
className="mr-2"
|
||||
/>
|
||||
Pilih Semua Polres
|
||||
</Label>
|
||||
{polda?.subDestination?.map((polres: any) => (
|
||||
<Label key={polres.id} className="block mt-1">
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(polres.id)}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChange(polres.id)
|
||||
}
|
||||
className="mr-2"
|
||||
/>
|
||||
{polres.name}
|
||||
</Label>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="font-medium">Nama Acara</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size={"md"}
|
||||
type="text"
|
||||
value={detail?.title}
|
||||
onChange={field.onChange}
|
||||
placeholder="Masukan Judul"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="border-2 border-dashed rounded-md p-4 flex flex-col items-center justify-center text-center text-sm text-muted-foreground">
|
||||
<svg
|
||||
className="w-6 h-6 mb-2 text-blue-500"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1M12 12v9m0-9l3 3m-3-3l-3 3m6-11a4 4 0 00-8 0v1H4a2 2 0 00-2 2v4h20v-4a2 2 0 00-2-2h-4v-1z"
|
||||
/>
|
||||
</svg>
|
||||
<div>
|
||||
Drag your file(s) or{" "}
|
||||
<span className="text-blue-500 underline cursor-pointer">
|
||||
browse
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs mt-1">Max 10 MB files are allowed</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="font-medium">Deskripsi</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
rows={3}
|
||||
value={detail?.description}
|
||||
onChange={field.onChange}
|
||||
placeholder="Masukan lokasi"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.description?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.description?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<div className="text-right">
|
||||
<Link href={"contributor/schedule/calendar-polri"}>
|
||||
<Button type="button" variant={"outline"} color="primary">
|
||||
Kembali
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,453 @@
|
|||
// components/TambahIklanModal.tsx
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogTrigger,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { CalendarIcon, ChevronDown, ChevronUp, Plus } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import DatePicker from "react-datepicker";
|
||||
import { id } from "date-fns/locale";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import router from "next/router";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { date, z } from "zod";
|
||||
import { error } from "@/lib/swal";
|
||||
import { postCalendar } from "@/service/schedule/schedule";
|
||||
import { DateRange } from "react-day-picker";
|
||||
import Cookies from "js-cookie";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { format } from "date-fns";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getUserLevelForAssignments } from "@/service/task";
|
||||
import { Card } from "@/components/ui/card";
|
||||
|
||||
const calendarSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
description: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
});
|
||||
|
||||
export function CalendarPolriAddUpdate() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const t = useTranslations("Schedule");
|
||||
type CalendarSchema = z.infer<typeof calendarSchema>;
|
||||
const [eventDate, setEventDate] = React.useState<Date | null>(new Date());
|
||||
const [listDest, setListDest] = React.useState([]);
|
||||
const [checkedLevels, setCheckedLevels] = React.useState(new Set());
|
||||
const [expandedPolda, setExpandedPolda] = React.useState([{}]);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const [date, setDate] = React.useState<DateRange | undefined>({
|
||||
from: new Date(2025, 0, 1),
|
||||
});
|
||||
|
||||
const [unitSelection, setUnitSelection] = React.useState({
|
||||
semua: false,
|
||||
mabes: false,
|
||||
polda: false,
|
||||
satker: false,
|
||||
internasional: false,
|
||||
});
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<CalendarSchema>({
|
||||
resolver: zodResolver(calendarSchema),
|
||||
defaultValues: {
|
||||
description: "",
|
||||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
async function fetchPoldaPolres() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const response = await getUserLevelForAssignments();
|
||||
setListDest(response?.data?.data.list);
|
||||
console.log("polda", response?.data?.data?.list);
|
||||
const initialExpandedState = response?.data?.data.list.reduce(
|
||||
(acc: any, polda: any) => {
|
||||
acc[polda.id] = false;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
setExpandedPolda(initialExpandedState);
|
||||
console.log("polres", initialExpandedState);
|
||||
} catch (error) {
|
||||
console.error("Error fetching Polda/Polres data:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
fetchPoldaPolres();
|
||||
}, []);
|
||||
|
||||
const handleCheckboxChange = (levelId: number) => {
|
||||
setCheckedLevels((prev) => {
|
||||
const updatedLevels = new Set(prev);
|
||||
if (updatedLevels.has(levelId)) {
|
||||
updatedLevels.delete(levelId);
|
||||
} else {
|
||||
updatedLevels.add(levelId);
|
||||
}
|
||||
return updatedLevels;
|
||||
});
|
||||
};
|
||||
|
||||
const handlePoldaPolresChange = () => {
|
||||
return Array.from(checkedLevels).join(","); // Mengonversi Set ke string
|
||||
};
|
||||
|
||||
const handleUnitChange = (
|
||||
key: keyof typeof unitSelection,
|
||||
value: boolean
|
||||
) => {
|
||||
if (key === "semua") {
|
||||
const newState = {
|
||||
semua: value,
|
||||
mabes: value,
|
||||
polda: value,
|
||||
satker: value,
|
||||
internasional: value,
|
||||
};
|
||||
setUnitSelection(newState);
|
||||
} else {
|
||||
const updatedSelection = {
|
||||
...unitSelection,
|
||||
[key]: value,
|
||||
};
|
||||
|
||||
const allChecked = ["mabes", "polda", "satker", "internasional"].every(
|
||||
(k) => updatedSelection[k as keyof typeof unitSelection]
|
||||
);
|
||||
|
||||
updatedSelection.semua = allChecked;
|
||||
|
||||
setUnitSelection(updatedSelection);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleExpand = (poldaId: any) => {
|
||||
setExpandedPolda((prev: any) => ({
|
||||
...prev,
|
||||
[poldaId]: !prev[poldaId],
|
||||
}));
|
||||
};
|
||||
|
||||
const save = async (data: CalendarSchema) => {
|
||||
const unitMapping = {
|
||||
allUnit: "0",
|
||||
mabes: "1",
|
||||
polda: "2",
|
||||
satker: "4",
|
||||
internasional: "5",
|
||||
};
|
||||
const assignmentToString = Object.keys(unitSelection)
|
||||
.filter((key) => unitSelection[key as keyof typeof unitSelection])
|
||||
.map((key) => unitMapping[key as keyof typeof unitMapping])
|
||||
.join(",");
|
||||
const requestData = {
|
||||
title: data.title,
|
||||
startDate: date?.from ? format(date.from, "yyyy-MM-dd") : null,
|
||||
endDate: date?.to ? format(date.to, "yyyy-MM-dd") : null,
|
||||
description: data.description,
|
||||
assignedTo: assignmentToString,
|
||||
assignedToLevel: handlePoldaPolresChange(),
|
||||
};
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
|
||||
const response = await postCalendar(requestData);
|
||||
if (response?.error) {
|
||||
error(response?.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
Cookies.set("scheduleId", response?.data?.data.id, {
|
||||
expires: 1,
|
||||
});
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
text: "Data berhasil disimpan.",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.reload();
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = (data: CalendarSchema) => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card className="px-3 py-3">
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<p className="font-medium mb-1">Tanggal Acara</p>
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild className="px-0">
|
||||
<Button
|
||||
size="md"
|
||||
id="date"
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[280px] lg:w-[250px] justify-start text-left font-normal border border-slate-300 px-0 md:px-0 lg:px-4",
|
||||
!date && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
<CalendarIcon size={15} className="mr-3" />
|
||||
{date?.from ? (
|
||||
date.to ? (
|
||||
<>
|
||||
{format(date.from, "LLL dd, y")} -{" "}
|
||||
{format(date.to, "LLL dd, y")}
|
||||
</>
|
||||
) : (
|
||||
format(date.from, "LLL dd, y")
|
||||
)
|
||||
) : (
|
||||
<span>Pick a date</span>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
initialFocus
|
||||
mode="range"
|
||||
defaultMonth={date?.from}
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
numberOfMonths={1}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium">Publish Area</p>
|
||||
<div className="flex flex-row">
|
||||
<div className="flex flex-wrap gap-3 lg:ml-3 ">
|
||||
{Object.keys(unitSelection).map((key) => (
|
||||
<div className="flex items-center gap-2" key={key}>
|
||||
<Checkbox
|
||||
id={key}
|
||||
checked={
|
||||
unitSelection[key as keyof typeof unitSelection]
|
||||
}
|
||||
onCheckedChange={(value) =>
|
||||
handleUnitChange(
|
||||
key as keyof typeof unitSelection,
|
||||
value as boolean
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Label htmlFor={key}>
|
||||
{key.charAt(0).toUpperCase() + key.slice(1)}
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className=" lg:pl-3">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="soft" size="sm" color="primary">
|
||||
[{t("custom")}]
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-[425px] md:max-w-[500px] lg:max-w-[1500px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Daftar Wilayah Polda dan Polres
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
|
||||
{listDest.map((polda: any) => (
|
||||
<div key={polda.id} className="border p-2">
|
||||
<Label className="flex items-center">
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(polda.id)}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChange(polda.id)
|
||||
}
|
||||
className="mr-3"
|
||||
/>
|
||||
{polda.name}
|
||||
<button
|
||||
onClick={() => toggleExpand(polda.id)}
|
||||
className="ml-2 focus:outline-none"
|
||||
>
|
||||
{expandedPolda[polda.id] ? (
|
||||
<ChevronUp size={16} />
|
||||
) : (
|
||||
<ChevronDown size={16} />
|
||||
)}
|
||||
</button>
|
||||
</Label>
|
||||
{expandedPolda[polda.id] && (
|
||||
<div className="ml-6 mt-2">
|
||||
<Label className="block">
|
||||
<Checkbox
|
||||
checked={polda?.subDestination?.every(
|
||||
(polres: any) =>
|
||||
checkedLevels.has(polres.id)
|
||||
)}
|
||||
onCheckedChange={(isChecked) => {
|
||||
const updatedLevels = new Set(
|
||||
checkedLevels
|
||||
);
|
||||
polda?.subDestination?.forEach(
|
||||
(polres: any) => {
|
||||
if (isChecked) {
|
||||
updatedLevels.add(polres.id);
|
||||
} else {
|
||||
updatedLevels.delete(polres.id);
|
||||
}
|
||||
}
|
||||
);
|
||||
setCheckedLevels(updatedLevels);
|
||||
}}
|
||||
className="mr-2"
|
||||
/>
|
||||
Pilih Semua Polres
|
||||
</Label>
|
||||
{polda?.subDestination?.map((polres: any) => (
|
||||
<Label key={polres.id} className="block mt-1">
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(polres.id)}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChange(polres.id)
|
||||
}
|
||||
className="mr-2"
|
||||
/>
|
||||
{polres.name}
|
||||
</Label>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="font-medium">Nama Acara</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size={"md"}
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Masukan Judul"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="border-2 border-dashed rounded-md p-4 flex flex-col items-center justify-center text-center text-sm text-muted-foreground">
|
||||
<svg
|
||||
className="w-6 h-6 mb-2 text-blue-500"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1M12 12v9m0-9l3 3m-3-3l-3 3m6-11a4 4 0 00-8 0v1H4a2 2 0 00-2 2v4h20v-4a2 2 0 00-2-2h-4v-1z"
|
||||
/>
|
||||
</svg>
|
||||
<div>
|
||||
Drag your file(s) or{" "}
|
||||
<span className="text-blue-500 underline cursor-pointer">
|
||||
browse
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs mt-1">Max 10 MB files are allowed</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="font-medium">Deskripsi</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
rows={3}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Masukan lokasi"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.description?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.description?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="text-right">
|
||||
<Button
|
||||
type="submit"
|
||||
className="bg-blue-600 text-white hover:bg-blue-700"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -13,100 +13,441 @@ import { Button } from "@/components/ui/button";
|
|||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { CalendarIcon, Plus } from "lucide-react";
|
||||
import { CalendarIcon, ChevronDown, ChevronUp, Plus } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import DatePicker from "react-datepicker";
|
||||
import { id } from "date-fns/locale";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import router from "next/router";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { date, z } from "zod";
|
||||
import { error } from "@/lib/swal";
|
||||
import { postCalendar } from "@/service/schedule/schedule";
|
||||
import { DateRange } from "react-day-picker";
|
||||
import Cookies from "js-cookie";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Swal from "sweetalert2";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { format } from "date-fns";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getUserLevelForAssignments } from "@/service/task";
|
||||
import { Card } from "@/components/ui/card";
|
||||
|
||||
const calendarSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
description: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
});
|
||||
|
||||
export function CalendarPolriAdd() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const t = useTranslations("Schedule");
|
||||
type CalendarSchema = z.infer<typeof calendarSchema>;
|
||||
const [eventDate, setEventDate] = React.useState<Date | null>(new Date());
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button onClick={() => setOpen(true)} color="primary" size="md">
|
||||
<Plus className="mr-2 h-4 w-4" /> {t("calendar-polri")}{" "}
|
||||
{t("schedule")}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent size="md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Buat Jadwal Kalender Polri</DialogTitle>
|
||||
</DialogHeader>
|
||||
const [listDest, setListDest] = React.useState([]);
|
||||
const [checkedLevels, setCheckedLevels] = React.useState(new Set());
|
||||
const [expandedPolda, setExpandedPolda] = React.useState([{}]);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const [date, setDate] = React.useState<DateRange | undefined>({
|
||||
from: new Date(2025, 0, 1),
|
||||
});
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<p className="font-medium mb-1">Tanggal Acara</p>
|
||||
<div className="relative">
|
||||
<DatePicker
|
||||
selected={eventDate}
|
||||
onChange={(date) => setEventDate(date)}
|
||||
dateFormat="dd MMMM yyyy"
|
||||
locale={id}
|
||||
className="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
<CalendarIcon className="absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-500 pointer-events-none" />
|
||||
const [unitSelection, setUnitSelection] = React.useState({
|
||||
semua: false,
|
||||
mabes: false,
|
||||
polda: false,
|
||||
satker: false,
|
||||
internasional: false,
|
||||
});
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<CalendarSchema>({
|
||||
resolver: zodResolver(calendarSchema),
|
||||
defaultValues: {
|
||||
description: "",
|
||||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
async function fetchPoldaPolres() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const response = await getUserLevelForAssignments();
|
||||
setListDest(response?.data?.data.list);
|
||||
console.log("polda", response?.data?.data?.list);
|
||||
const initialExpandedState = response?.data?.data.list.reduce(
|
||||
(acc: any, polda: any) => {
|
||||
acc[polda.id] = false;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
setExpandedPolda(initialExpandedState);
|
||||
console.log("polres", initialExpandedState);
|
||||
} catch (error) {
|
||||
console.error("Error fetching Polda/Polres data:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
fetchPoldaPolres();
|
||||
}, []);
|
||||
|
||||
const handleCheckboxChange = (levelId: number) => {
|
||||
setCheckedLevels((prev) => {
|
||||
const updatedLevels = new Set(prev);
|
||||
if (updatedLevels.has(levelId)) {
|
||||
updatedLevels.delete(levelId);
|
||||
} else {
|
||||
updatedLevels.add(levelId);
|
||||
}
|
||||
return updatedLevels;
|
||||
});
|
||||
};
|
||||
|
||||
const handlePoldaPolresChange = () => {
|
||||
return Array.from(checkedLevels).join(","); // Mengonversi Set ke string
|
||||
};
|
||||
|
||||
const handleUnitChange = (
|
||||
key: keyof typeof unitSelection,
|
||||
value: boolean
|
||||
) => {
|
||||
if (key === "semua") {
|
||||
const newState = {
|
||||
semua: value,
|
||||
mabes: value,
|
||||
polda: value,
|
||||
satker: value,
|
||||
internasional: value,
|
||||
};
|
||||
setUnitSelection(newState);
|
||||
} else {
|
||||
const updatedSelection = {
|
||||
...unitSelection,
|
||||
[key]: value,
|
||||
};
|
||||
|
||||
const allChecked = ["mabes", "polda", "satker", "internasional"].every(
|
||||
(k) => updatedSelection[k as keyof typeof unitSelection]
|
||||
);
|
||||
|
||||
updatedSelection.semua = allChecked;
|
||||
|
||||
setUnitSelection(updatedSelection);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleExpand = (poldaId: any) => {
|
||||
setExpandedPolda((prev: any) => ({
|
||||
...prev,
|
||||
[poldaId]: !prev[poldaId],
|
||||
}));
|
||||
};
|
||||
|
||||
const save = async (data: CalendarSchema) => {
|
||||
const unitMapping = {
|
||||
allUnit: "0",
|
||||
mabes: "1",
|
||||
polda: "2",
|
||||
satker: "4",
|
||||
internasional: "5",
|
||||
};
|
||||
const assignmentToString = Object.keys(unitSelection)
|
||||
.filter((key) => unitSelection[key as keyof typeof unitSelection])
|
||||
.map((key) => unitMapping[key as keyof typeof unitMapping])
|
||||
.join(",");
|
||||
const requestData = {
|
||||
title: data.title,
|
||||
startDate: date?.from ? format(date.from, "yyyy-MM-dd") : null,
|
||||
endDate: date?.to ? format(date.to, "yyyy-MM-dd") : null,
|
||||
description: data.description,
|
||||
assignedTo: assignmentToString,
|
||||
assignedToLevel: handlePoldaPolresChange(),
|
||||
};
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
|
||||
const response = await postCalendar(requestData);
|
||||
if (response?.error) {
|
||||
error(response?.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
Cookies.set("scheduleId", response?.data?.data.id, {
|
||||
expires: 1,
|
||||
});
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
text: "Data berhasil disimpan.",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.reload();
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = (data: CalendarSchema) => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card className="px-3 py-3">
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<p className="font-medium mb-1">Tanggal Acara</p>
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild className="px-0">
|
||||
<Button
|
||||
size="md"
|
||||
id="date"
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[280px] lg:w-[250px] justify-start text-left font-normal border border-slate-300 px-0 md:px-0 lg:px-4",
|
||||
!date && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
<CalendarIcon size={15} className="mr-3" />
|
||||
{date?.from ? (
|
||||
date.to ? (
|
||||
<>
|
||||
{format(date.from, "LLL dd, y")} -{" "}
|
||||
{format(date.to, "LLL dd, y")}
|
||||
</>
|
||||
) : (
|
||||
format(date.from, "LLL dd, y")
|
||||
)
|
||||
) : (
|
||||
<span>Pick a date</span>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
initialFocus
|
||||
mode="range"
|
||||
defaultMonth={date?.from}
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
numberOfMonths={1}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium">Publish Area</p>
|
||||
<div className="flex flex-wrap gap-4 mt-2">
|
||||
{["Semua", "Nasional", "Polda", "Satker", "International"].map(
|
||||
(label) => (
|
||||
<label key={label} className="flex items-center gap-2">
|
||||
<Checkbox id={label} />
|
||||
<span>{label}</span>
|
||||
</label>
|
||||
)
|
||||
<div>
|
||||
<p className="font-medium">Publish Area</p>
|
||||
<div className="flex flex-row">
|
||||
<div className="flex flex-wrap gap-3 lg:ml-3 ">
|
||||
{Object.keys(unitSelection).map((key) => (
|
||||
<div className="flex items-center gap-2" key={key}>
|
||||
<Checkbox
|
||||
id={key}
|
||||
checked={
|
||||
unitSelection[key as keyof typeof unitSelection]
|
||||
}
|
||||
onCheckedChange={(value) =>
|
||||
handleUnitChange(
|
||||
key as keyof typeof unitSelection,
|
||||
value as boolean
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Label htmlFor={key}>
|
||||
{key.charAt(0).toUpperCase() + key.slice(1)}
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className=" lg:pl-3">
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="soft" size="sm" color="primary">
|
||||
[{t("custom")}]
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-[425px] md:max-w-[500px] lg:max-w-[1500px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Daftar Wilayah Polda dan Polres
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
|
||||
{listDest.map((polda: any) => (
|
||||
<div key={polda.id} className="border p-2">
|
||||
<Label className="flex items-center">
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(polda.id)}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChange(polda.id)
|
||||
}
|
||||
className="mr-3"
|
||||
/>
|
||||
{polda.name}
|
||||
<button
|
||||
onClick={() => toggleExpand(polda.id)}
|
||||
className="ml-2 focus:outline-none"
|
||||
>
|
||||
{expandedPolda[polda.id] ? (
|
||||
<ChevronUp size={16} />
|
||||
) : (
|
||||
<ChevronDown size={16} />
|
||||
)}
|
||||
</button>
|
||||
</Label>
|
||||
{expandedPolda[polda.id] && (
|
||||
<div className="ml-6 mt-2">
|
||||
<Label className="block">
|
||||
<Checkbox
|
||||
checked={polda?.subDestination?.every(
|
||||
(polres: any) =>
|
||||
checkedLevels.has(polres.id)
|
||||
)}
|
||||
onCheckedChange={(isChecked) => {
|
||||
const updatedLevels = new Set(
|
||||
checkedLevels
|
||||
);
|
||||
polda?.subDestination?.forEach(
|
||||
(polres: any) => {
|
||||
if (isChecked) {
|
||||
updatedLevels.add(polres.id);
|
||||
} else {
|
||||
updatedLevels.delete(polres.id);
|
||||
}
|
||||
}
|
||||
);
|
||||
setCheckedLevels(updatedLevels);
|
||||
}}
|
||||
className="mr-2"
|
||||
/>
|
||||
Pilih Semua Polres
|
||||
</Label>
|
||||
{polda?.subDestination?.map((polres: any) => (
|
||||
<Label key={polres.id} className="block mt-1">
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(polres.id)}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChange(polres.id)
|
||||
}
|
||||
className="mr-2"
|
||||
/>
|
||||
{polres.name}
|
||||
</Label>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="font-medium">Nama Acara</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size={"md"}
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Masukan Judul"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="font-medium">Nama Acara</p>
|
||||
<Input placeholder="Masukkan nama acara" />
|
||||
</div>
|
||||
|
||||
<div className="border-2 border-dashed rounded-md p-4 flex flex-col items-center justify-center text-center text-sm text-muted-foreground">
|
||||
<svg
|
||||
className="w-6 h-6 mb-2 text-blue-500"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1M12 12v9m0-9l3 3m-3-3l-3 3m6-11a4 4 0 00-8 0v1H4a2 2 0 00-2 2v4h20v-4a2 2 0 00-2-2h-4v-1z"
|
||||
/>
|
||||
</svg>
|
||||
<div>
|
||||
Drag your file(s) or{" "}
|
||||
<span className="text-blue-500 underline cursor-pointer">
|
||||
browse
|
||||
</span>
|
||||
<div className="border-2 border-dashed rounded-md p-4 flex flex-col items-center justify-center text-center text-sm text-muted-foreground">
|
||||
<svg
|
||||
className="w-6 h-6 mb-2 text-blue-500"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1M12 12v9m0-9l3 3m-3-3l-3 3m6-11a4 4 0 00-8 0v1H4a2 2 0 00-2 2v4h20v-4a2 2 0 00-2-2h-4v-1z"
|
||||
/>
|
||||
</svg>
|
||||
<div>
|
||||
Drag your file(s) or{" "}
|
||||
<span className="text-blue-500 underline cursor-pointer">
|
||||
browse
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs mt-1">Max 10 MB files are allowed</div>
|
||||
</div>
|
||||
<div className="text-xs mt-1">Max 10 MB files are allowed</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="font-medium">Deskripsi</p>
|
||||
<Textarea placeholder="Masukkan deskripsi acara" rows={4} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium">Deskripsi</p>
|
||||
<Controller
|
||||
control={control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
rows={3}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Masukan lokasi"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.description?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.description?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="text-right">
|
||||
<Button
|
||||
type="submit"
|
||||
className="bg-blue-600 text-white hover:bg-blue-700"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
<div className="text-right">
|
||||
<Button
|
||||
type="submit"
|
||||
className="bg-blue-600 text-white hover:bg-blue-700"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</form>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -602,7 +602,8 @@
|
|||
"create-schedule": "Create Schedule",
|
||||
"event": "event",
|
||||
"live-report": "Live Report",
|
||||
"calendar-polri": "Calendar Polri"
|
||||
"calendar-polri": "Calendar Polri",
|
||||
"custom": "Costum"
|
||||
},
|
||||
"Blog": {
|
||||
"table": "Table",
|
||||
|
|
|
|||
|
|
@ -603,7 +603,8 @@
|
|||
"create-schedule": "Buat Jadwal",
|
||||
"event": "event",
|
||||
"live-report": "Live Report",
|
||||
"calendar-polri": "Kalender Polri"
|
||||
"calendar-polri": "Kalender Polri",
|
||||
"custom": "Kostum"
|
||||
},
|
||||
"Blog": {
|
||||
"table": "Tabel",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,18 @@ export async function listDataMedia(
|
|||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function listDataAdvertisements(
|
||||
page: number,
|
||||
limit: string,
|
||||
search: string,
|
||||
categoryFilter: string,
|
||||
statusFilter: string
|
||||
) {
|
||||
const name = search || "";
|
||||
const url = `advertisements/pagination?title=${name}&enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&typeId=1&categoryId=${categoryFilter}&statusId=${statusFilter}`;
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function listDataMediaBroadCast(
|
||||
page: number,
|
||||
limit: string,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
httpDeleteInterceptor,
|
||||
httpGetInterceptor,
|
||||
httpPostInterceptor,
|
||||
} from "../http-config/http-interceptor-service";
|
||||
|
|
@ -19,6 +20,20 @@ export async function paginationSchedule(
|
|||
);
|
||||
}
|
||||
|
||||
export async function paginationCalendar(
|
||||
size: any,
|
||||
page: number,
|
||||
type: any,
|
||||
title: string = "",
|
||||
statusFilter: number[] = []
|
||||
) {
|
||||
const statusQuery =
|
||||
statusFilter.length > 0 ? `&statusId=${statusFilter.join(",")}` : "";
|
||||
return await httpGetInterceptor(
|
||||
`calendars/pagination?enablePage=1&scheduleTypeId=${type}&page=${page}&size=${size}&title=${title}${statusQuery}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function postSchedule(data: any) {
|
||||
const url = "schedule";
|
||||
return httpPostInterceptor(url, data);
|
||||
|
|
@ -68,3 +83,18 @@ export async function listScheduleNext() {
|
|||
const url = "schedule/next-activity";
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function postCalendar(data: any) {
|
||||
const url = "calendars";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function detailCalendar(id: any) {
|
||||
const url = `calendars?id=${id}`;
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function deleteCalendar(id: any) {
|
||||
const url = `calendars?id=${id}`;
|
||||
return httpDeleteInterceptor(url);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue