feat:update create,edit,detail task ta, download report

This commit is contained in:
Anang Yusman 2025-04-22 13:22:08 +08:00
parent df90fc0906
commit 4e71b4525e
11 changed files with 528 additions and 158 deletions

View File

@ -25,8 +25,13 @@ import withReactContent from "sweetalert2-react-content";
import { deleteBlog } from "@/service/blog/blog";
import { error, loading } from "@/lib/swal";
import { useTranslations } from "next-intl";
import axios from "axios";
const useTableColumns = () => {
const useTableColumns = ({
handlePreview,
}: {
handlePreview: (id: string) => void;
}) => {
const t = useTranslations("Table"); // Panggil di dalam hook
const columns: ColumnDef<any>[] = [
@ -112,6 +117,33 @@ const useTableColumns = () => {
}
});
};
const handleDownload = async (id: string) => {
try {
const response = await axios.get(
`https://netidhub.com/api/media/report/download?id=${id}`,
{
responseType: "blob",
}
);
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", `report-${id}.pdf`);
document.body.appendChild(link);
link.click();
link.remove();
} catch (error) {
console.error("Download failed", error);
MySwal.fire({
title: "Gagal",
text: "Terjadi kesalahan saat mengunduh file.",
icon: "error",
});
}
};
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
@ -124,18 +156,22 @@ const useTableColumns = () => {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<Link href={`/contributor/blog/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" />
Preview
</DropdownMenuItem>
</Link>
<Link href={`/contributor/blog/update/${row.original.id}`}>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Upload className="w-4 h-4 me-1.5" />
Download
</DropdownMenuItem>
</Link>
<DropdownMenuItem
onClick={() => handlePreview(row.original.id)}
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" />
Preview
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleDownload(row.original.id)}
className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none"
>
<Upload className="w-4 h-4 me-1.5" />
Download
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleDeleteBlog(row.original.id)}
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"

View File

@ -43,14 +43,40 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Label } from "@/components/ui/label";
import Swal from "sweetalert2";
import { listEnableCategory } from "@/service/content/content";
import { useTranslations } from "next-intl";
import { CardHeader, CardTitle } from "@/components/ui/card";
import { Link } from "@/i18n/routing";
import useTableColumns from "./columns";
import {
getPreviewById,
paginationReport,
saveReport,
} from "@/service/report/report";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { format } from "date-fns";
import withReactContent from "sweetalert2-react-content";
type PreviewApiResponse = {
error: boolean;
message: string;
data: {
id: number;
title: string;
filePath: string;
version: number;
} | null;
};
const ReportTable = () => {
const router = useRouter();
const MySwal = withReactContent(Swal);
const searchParams = useSearchParams();
const t = useTranslations("Report");
const [dataTable, setDataTable] = React.useState<any[]>([]);
@ -78,7 +104,16 @@ const ReportTable = () => {
const [categoryFilter, setCategoryFilter] = React.useState<string>("");
const [dateFilter, setDateFilter] = React.useState("");
const [statusFilter, setStatusFilter] = React.useState<any[]>([]);
const columns = useTableColumns();
const [openPreview, setOpenPreview] = React.useState(false);
const [previewData, setPreviewData] = React.useState<any>(null);
const handlePreview = (id: string) => {
const url = `https://netidhub.com/api/media/report/view?id=${id}`;
setPreviewData({ url });
setOpenPreview(true);
};
const columns = useTableColumns({ handlePreview });
const table = useReactTable({
data: dataTable,
columns,
@ -114,7 +149,7 @@ const ReportTable = () => {
async function fetchData() {
try {
const res = await paginationBlog(
const res = await paginationReport(
showData,
page - 1,
search,
@ -144,11 +179,10 @@ const ReportTable = () => {
}
const handleCheckboxChange = (categoryId: number) => {
setSelectedCategories(
(prev: any) =>
prev.includes(categoryId)
? prev.filter((id: any) => id !== categoryId) // Hapus jika sudah dipilih
: [...prev, categoryId] // Tambahkan jika belum dipilih
setSelectedCategories((prev: any) =>
prev.includes(categoryId)
? prev.filter((id: any) => id !== categoryId)
: [...prev, categoryId]
);
// Perbarui filter kategori
@ -176,8 +210,61 @@ const ReportTable = () => {
table.getColumn("judul")?.setFilterValue(e.target.value); // Set filter tabel
};
const handleGenerateReport = async () => {
const today = new Date();
const formattedDate = format(today, "dd-MM-yyyy"); // Hasil: 22-04-2025
const title = `Report ${formattedDate}`;
const requestData = {
title,
};
try {
const response = await saveReport(requestData);
if (response?.error) {
MySwal.fire(
"Error",
response?.message || "Gagal menyimpan laporan",
"error"
);
return;
}
MySwal.fire({
title: "Sukses",
text: "Laporan berhasil dibuat.",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then(() => {
fetchData(); // Refresh tabel setelah generate
});
} catch (error) {
console.error("Generate report error:", error);
MySwal.fire("Error", "Terjadi kesalahan saat membuat laporan", "error");
}
};
return (
<div>
<Dialog open={openPreview} onOpenChange={setOpenPreview}>
<DialogContent className="min-w-max h-[500px] p-0 overflow-hidden">
<DialogHeader className="p-4 border-b">
<DialogTitle>Preview Laporan</DialogTitle>
</DialogHeader>
<div className="h-full w-[1000px] overflow-auto">
{previewData ? (
<iframe
src={previewData.url}
className="w-full h-[calc(100vh-100px)]"
/>
) : (
<div className="p-4">Loading preview...</div>
)}
</div>
</DialogContent>
</Dialog>
<CardHeader className="border-b border-solid border-default-200 mb-6">
<CardTitle>
<div className="flex items-center">
@ -185,17 +272,14 @@ const ReportTable = () => {
{t("table")} {t("report")}
</div>
<div className="flex-none">
<Link href={"#"}>
<Button fullWidth color="primary">
<Plus size={18} className=" me-1.5" />
{t("generate-report")}
</Button>
</Link>
<Button fullWidth color="primary" onClick={handleGenerateReport}>
<Plus size={18} className=" me-1.5" />
{t("generate-report")}
</Button>
</div>
</div>
</CardTitle>
</CardHeader>
<div className="w-full overflow-x-auto">
<div className="flex flex-col md:flex-row lg:flex-row md:justify-between lg:justify-between items-center md:px-5 lg:px-5">
<div className="w-full md:w-[200px] lg:w-[200px] px-2">

View File

@ -158,13 +158,13 @@ const useTableColumns = () => {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<Link href={`/contributor/task/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">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
</Link>
<Link href={`/contributor/task/update/${row.original.id}`}>
<Link href={`/contributor/task-ta/update/${row.original.id}`}>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit

View File

@ -54,7 +54,7 @@ import { Badge } from "@/components/ui/badge";
import { useRouter, useSearchParams } from "next/navigation";
import TablePagination from "@/components/table/table-pagination";
import columns from "./columns";
import { listTask } from "@/service/task";
import { listTask, listTaskTa } from "@/service/task";
import { Label } from "@/components/ui/label";
import { format } from "date-fns";
import { useTranslations } from "next-intl";
@ -133,7 +133,7 @@ const TaskTaTable = () => {
? format(new Date(dateFilter), "yyyy-MM-dd")
: "";
try {
const res = await listTask(
const res = await listTaskTa(
page - 1,
search,
showData,

View File

@ -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 FormTaskDetail from "@/components/form/task/task-detail-form";
import FormTaskTaDetail from "@/components/form/task-ta/task-ta-detail-form";
const TaskTaDetailPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<FormTaskDetail />
<FormTaskTaDetail />
</div>
</div>
);

View File

@ -3,13 +3,14 @@ import SiteBreadcrumb from "@/components/site-breadcrumb";
import FormTask from "@/components/form/task/task-form";
import FormTaskDetail from "@/components/form/task/task-detail-form";
import FormTaskEdit from "@/components/form/task/task-edit-form";
import FormTaskTaEdit from "@/components/form/task-ta/task-ta-edit-form";
const TaskTaDetailPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<FormTaskEdit />
<FormTaskTaEdit />
</div>
</div>
);

View File

@ -32,6 +32,7 @@ import {
getAssignmentResponseList,
getMediaUpload,
getTask,
getTaskTa,
getUserLevelForAssignments,
} from "@/service/task";
import {
@ -82,11 +83,11 @@ export type taskDetail = {
title: string;
fileTypeOutput: string;
assignedToRole: string;
assignedToTopLevel: string;
assignmentType: {
id: number;
name: string;
};
assignedToUsers: string;
// assignmentType: {
// id: number;
// name: string;
// };
assignmentMainType: {
id: number;
name: string;
@ -106,7 +107,8 @@ export type taskDetail = {
userGroupId: number;
};
};
taskType: string;
assignmentType: string;
expertCompetencies: string;
broadcastType: string;
narration: string;
is_active: string;
@ -198,6 +200,22 @@ export default function FormTaskTaDetail() {
const userId = getCookiesDecrypt("uie");
const userLevelId = "";
const [expertise, setExpertiseOutput] = useState({
semua: false,
komunikasi: false,
hukum: false,
bahasa: false,
ekonomi: false,
politik: false,
sosiologi: false,
ilmuadministrasipemerintah: false,
ti: false,
});
const [expert, setExpertOutput] = useState({
semua: false,
});
// State for various form fields
const [taskOutput, setTaskOutput] = useState({
all: false,
@ -307,6 +325,62 @@ export default function FormTaskTaDetail() {
// setPlatformTypeVisible(selectedValue === 2);
// };
const handleExpertiseOutputChange = (
key: keyof typeof expertise,
value: boolean
) => {
if (key === "semua") {
const newState = {
semua: value,
komunikasi: value,
hukum: value,
bahasa: value,
ekonomi: value,
politik: value,
sosiologi: value,
ilmuadministrasipemerintah: value,
ti: value,
};
setExpertiseOutput(newState);
} else {
const updated = {
...expertise,
[key]: value,
};
const allChecked = ["video", "audio", "image", "text"].every(
(k) => updated[k as keyof typeof expertise]
);
updated.semua = allChecked;
setExpertiseOutput(updated);
}
};
const handleExpertOutputChange = (
key: keyof typeof expert,
value: boolean
) => {
if (key === "semua") {
const newState = {
semua: value,
};
setExpertOutput(newState);
} else {
const updated = {
...expert,
[key]: value,
};
const allChecked = ["video", "audio", "image", "text"].every(
(k) => updated[k as keyof typeof expert]
);
updated.semua = allChecked;
setExpertOutput(updated);
}
};
useEffect(() => {
async function fetchPoldaPolres() {
setIsLoading(true);
@ -358,7 +432,7 @@ export default function FormTaskTaDetail() {
useEffect(() => {
async function initState() {
if (id) {
const response = await getTask(id);
const response = await getTaskTa(id);
const details = response?.data?.data;
setDetail(details);
@ -427,19 +501,36 @@ export default function FormTaskTaDetail() {
}, [detail?.fileTypeOutput]);
useEffect(() => {
if (detail?.assignedToTopLevel) {
if (detail?.expertCompetencies) {
const outputSet = new Set(
detail.assignedToTopLevel.split(",").map(Number)
detail.expertCompetencies.split(",").map(String)
);
setUnitSelection({
allUnit: outputSet.has(0),
mabes: outputSet.has(1),
polda: outputSet.has(2),
polres: outputSet.has(3),
satker: outputSet.has(4),
setExpertiseOutput({
semua: outputSet.has("0"),
komunikasi: outputSet.has("1"),
hukum: outputSet.has("2"),
bahasa: outputSet.has("3"),
ekonomi: outputSet.has("4"),
politik: outputSet.has("5"),
sosiologi: outputSet.has("6"),
ilmuadministrasipemerintah: outputSet.has("7"),
ti: outputSet.has("8"),
});
}
}, [detail?.fileTypeOutput]);
}, [detail?.expertCompetencies]);
useEffect(() => {
if (detail?.assignedToUsers) {
const outputSet = new Set(detail.assignedToUsers.split(",").map(String));
setUnitSelection({
allUnit: outputSet.has("0"),
mabes: outputSet.has("1"),
polda: outputSet.has("2"),
polres: outputSet.has("3"),
satker: outputSet.has("4"),
});
}
}, [detail?.assignedToUsers]);
const successConfirm = () => {
MySwal.fire({
@ -1022,7 +1113,7 @@ export default function FormTaskTaDetail() {
</Dialog>
</div>
</div>
<div className="mt-6 space-y-2">
{/* <div className="mt-6 space-y-2">
<Label>{t("type-task")}</Label>
<RadioGroup
value={detail.assignmentMainType.id.toString()}
@ -1036,11 +1127,11 @@ export default function FormTaskTaDetail() {
<RadioGroupItem value="2" id="medsos-mediahub" />
<Label htmlFor="medsos-mediahub">Medsos Mediahub</Label>
</RadioGroup>
</div>
</div> */}
<div className="mt-6 space-y-2">
<Label>{t("assigment-type")} </Label>
<RadioGroup
value={detail.taskType.toString()}
value={detail?.assignmentType}
onValueChange={(value) => setTaskType(String(value))}
className="flex flex-wrap gap-3"
>
@ -1050,40 +1141,21 @@ export default function FormTaskTaDetail() {
<Label htmlFor="tugas-harian">Tugas Harian</Label>
</RadioGroup>
</div>
{/* RadioGroup Assignment Category */}
<div className="mt-6 space-y-2">
<Label>{t("type-of-task")}</Label>
<RadioGroup
value={detail.assignmentType.id.toString()}
onValueChange={(value) => setType(value)}
className="flex flex-wrap gap-3"
>
<div className="flex items-center gap-2">
<RadioGroupItem value="1" id="publication" />
<Label htmlFor="publication">Publikasi</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="2" id="amplification" />
<Label htmlFor="amplification">Amplifikasi</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="3" id="contra" />
<Label htmlFor="contra">Kontra</Label>
</div>
</RadioGroup>
</div>
<div className="mt-6 space-y-2">
<Label>{t("output-task")}</Label>
<div className="flex flex-wrap gap-3">
{Object.keys(taskOutput).map((key) => (
<div className="mt-5 space-y-2">
<Label>{t("areas-expertise")}</Label>
<div className="flex flex-wrap gap-4">
{Object.keys(expertise).map((key) => (
<div className="flex items-center gap-2" key={key}>
<Checkbox
id={key}
disabled
checked={taskOutput[key as keyof typeof taskOutput]}
checked={expertise[key as keyof typeof expertise]}
onCheckedChange={(value) =>
setTaskOutput({ ...taskOutput, [key]: value })
handleExpertiseOutputChange(
key as keyof typeof expertise,
value as boolean
)
}
disabled
/>
<Label htmlFor={key}>
{key.charAt(0).toUpperCase() + key.slice(1)}
@ -1093,6 +1165,28 @@ export default function FormTaskTaDetail() {
</div>
</div>
<div className="mt-5 space-y-2">
<Label>{t("choose-expert")}</Label>
<div className="flex flex-wrap gap-4">
{Object.keys(expert).map((key) => (
<div className="flex items-center gap-2" key={key}>
<Checkbox
id={key}
checked={expert[key as keyof typeof expert]}
onCheckedChange={(value) =>
handleExpertOutputChange(
key as keyof typeof expert,
value as boolean
)
}
/>
<Label htmlFor={key}>
{key.charAt(0).toUpperCase() + key.slice(1)}
</Label>
</div>
))}
</div>
</div>
<div className="mt-6 space-y-2">
<Label>{t("description")}</Label>
<Controller

View File

@ -22,7 +22,9 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import JoditEditor from "jodit-react";
import {
createTask,
createTaskTa,
getTask,
getTaskTa,
getUserLevelForAssignments,
} from "@/service/task";
import {
@ -65,16 +67,13 @@ export type taskDetail = {
title: string;
fileTypeOutput: string;
assignedToRole: string;
assignedToTopLevel: string;
assignmentType: {
id: number;
name: string;
};
assignedToUsers: string;
assignmentMainType: {
id: number;
name: string;
};
taskType: string;
assignmentType: string;
expertCompetencies: string;
broadcastType: string;
narration: string;
attachmentUrl: string;
@ -110,7 +109,22 @@ export default function FormTaskTaEdit() {
const { id } = useParams() as { id: string };
console.log(id);
// State for various form fields
const [expertise, setExpertiseOutput] = useState({
semua: false,
komunikasi: false,
hukum: false,
bahasa: false,
ekonomi: false,
politik: false,
sosiologi: false,
ilmuadministrasipemerintah: false,
ti: false,
});
const [expert, setExpertOutput] = useState({
semua: false,
});
const [taskOutput, setTaskOutput] = useState({
all: false,
video: false,
@ -177,12 +191,61 @@ export default function FormTaskTaEdit() {
resolver: zodResolver(taskSchema),
});
// const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
// const selectedValue = Number(event.target.value);
// setMainType(selectedValue);
const handleExpertiseOutputChange = (
key: keyof typeof expertise,
value: boolean
) => {
if (key === "semua") {
const newState = {
semua: value,
komunikasi: value,
hukum: value,
bahasa: value,
ekonomi: value,
politik: value,
sosiologi: value,
ilmuadministrasipemerintah: value,
ti: value,
};
setExpertiseOutput(newState);
} else {
const updated = {
...expertise,
[key]: value,
};
// setPlatformTypeVisible(selectedValue === 2);
// };
const allChecked = ["video", "audio", "image", "text"].every(
(k) => updated[k as keyof typeof expertise]
);
updated.semua = allChecked;
setExpertiseOutput(updated);
}
};
const handleExpertOutputChange = (
key: keyof typeof expert,
value: boolean
) => {
if (key === "semua") {
const newState = {
semua: value,
};
setExpertOutput(newState);
} else {
const updated = {
...expert,
[key]: value,
};
const allChecked = ["video", "audio", "image", "text"].every(
(k) => updated[k as keyof typeof expert]
);
updated.semua = allChecked;
setExpertOutput(updated);
}
};
useEffect(() => {
async function fetchPoldaPolres() {
@ -211,7 +274,7 @@ export default function FormTaskTaEdit() {
useEffect(() => {
async function initState() {
if (id) {
const response = await getTask(id);
const response = await getTaskTa(id);
const details = response?.data?.data;
setDetail(details);
@ -274,19 +337,49 @@ export default function FormTaskTaEdit() {
}, [detail?.fileTypeOutput]);
useEffect(() => {
if (detail?.assignedToTopLevel) {
if (detail?.expertCompetencies) {
const outputSet = new Set(
detail.assignedToTopLevel.split(",").map(Number)
detail.expertCompetencies.split(",").map(String)
);
setUnitSelection({
allUnit: outputSet.has(0),
mabes: outputSet.has(1),
polda: outputSet.has(2),
polres: outputSet.has(3),
satker: outputSet.has(4),
setExpertiseOutput({
semua: outputSet.has("0"),
komunikasi: outputSet.has("1"),
hukum: outputSet.has("2"),
bahasa: outputSet.has("3"),
ekonomi: outputSet.has("4"),
politik: outputSet.has("5"),
sosiologi: outputSet.has("6"),
ilmuadministrasipemerintah: outputSet.has("7"),
ti: outputSet.has("8"),
});
}
}, [detail?.fileTypeOutput]);
}, [detail?.expertCompetencies]);
useEffect(() => {
if (detail?.assignedToUsers) {
const outputSet = new Set(detail.assignedToUsers.split(",").map(String));
setUnitSelection({
allUnit: outputSet.has("0"),
mabes: outputSet.has("1"),
polda: outputSet.has("2"),
polres: outputSet.has("3"),
satker: outputSet.has("4"),
});
}
}, [detail?.assignedToUsers]);
const successConfirm = () => {
MySwal.fire({
title: "Sukses",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then((result) => {
if (result.isConfirmed) {
router.push("/en/contributor/task");
}
});
};
const handleCheckboxChange = (levelId: number) => {
setCheckedLevels((prev) => {
@ -391,15 +484,16 @@ export default function FormTaskTaEdit() {
id?: any;
title: string;
assignedToLevel: any;
assignmentPurpose: any;
assignedToUsers: any;
assignmentTypeId: string;
fileTypeOutput: string;
narration: string;
platformType: string | null;
assignmentMainTypeId: any;
taskType: string;
assignmentType: string;
assignedToRole: string;
broadcastType: string;
expertCompetencies: string;
attachmentUrl: string[];
} = {
...data,
@ -407,20 +501,21 @@ export default function FormTaskTaEdit() {
// assignmentCategory,
id: detail?.id || null,
assignedToLevel: handlePoldaPolresChange(),
assignmentPurpose: assignmentPurposeString,
assignedToUsers: assignmentPurposeString,
assignedToRole: selectedTarget,
taskType: taskType,
assignmentType: taskType,
broadcastType: broadcastType,
assignmentMainTypeId: mainType,
assignmentTypeId: type,
fileTypeOutput: selectedOutputs,
narration: data.naration,
platformType: "",
expertCompetencies: "1,2,3",
title: data.title,
attachmentUrl: links,
};
const response = await createTask(requestData);
const response = await createTaskTa(requestData);
console.log("Form Data Submitted:", requestData);
console.log("response", response);
@ -832,25 +927,10 @@ export default function FormTaskTaEdit() {
</Dialog>
</div>
</div>
<div className="mt-5 space-y-2">
<Label>{t("type-task")}</Label>
<RadioGroup
defaultValue={detail.assignmentMainType.id.toString()} // State yang dipetakan ke value RadioGroup
onValueChange={(value) => setMainType(value)}
// value={String(mainType)}
// onValueChange={(value) => setMainType(Number(value))}
className="flex flex-wrap gap-3"
>
<RadioGroupItem value="1" id="mediahub" />
<Label htmlFor="mediahub">Mediahub</Label>
<RadioGroupItem value="2" id="medsos-mediahub" />
<Label htmlFor="medsos-mediahub">Medsos Mediahub</Label>
</RadioGroup>
</div>
<div className="mt-5 space-y-2">
<div className="mt-6 space-y-2">
<Label>{t("assigment-type")} </Label>
<RadioGroup
defaultValue={detail.taskType.toString()}
defaultValue={detail?.assignmentType}
onValueChange={(value) => setTaskType(String(value))}
className="flex flex-wrap gap-3"
>
@ -860,39 +940,17 @@ export default function FormTaskTaEdit() {
<Label htmlFor="tugas-harian">Tugas Harian</Label>
</RadioGroup>
</div>
{/* RadioGroup Assignment Category */}
<div className="mt-5 space-y-2">
<Label>{t("type-of-task")}</Label>
<RadioGroup
defaultValue={detail.assignmentType.id.toString()} // State yang dipetakan ke value RadioGroup
onValueChange={(value) => setType(value)} // Mengubah nilai state ketika pilihan berubah
className="flex flex-wrap gap-3"
>
<div className="flex items-center gap-2">
<RadioGroupItem value="1" id="publication" />
<Label htmlFor="publication">Publikasi</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="2" id="amplification" />
<Label htmlFor="amplification">Amplifikasi</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="3" id="contra" />
<Label htmlFor="contra">Kontra</Label>
</div>
</RadioGroup>
</div>
<div className="mt-5 space-y-2">
<Label>{t("output-task")}</Label>
<Label>{t("areas-expertise")}</Label>
<div className="flex flex-wrap gap-4">
{Object.keys(taskOutput).map((key) => (
{Object.keys(expertise).map((key) => (
<div className="flex items-center gap-2" key={key}>
<Checkbox
id={key}
checked={taskOutput[key as keyof typeof taskOutput]}
checked={expertise[key as keyof typeof expertise]}
onCheckedChange={(value) =>
handleTaskOutputChange(
key as keyof typeof taskOutput,
handleExpertiseOutputChange(
key as keyof typeof expertise,
value as boolean
)
}
@ -904,6 +962,30 @@ export default function FormTaskTaEdit() {
))}
</div>
</div>
<div className="mt-5 space-y-2">
<Label>{t("choose-expert")}</Label>
<div className="flex flex-wrap gap-4">
{Object.keys(expert).map((key) => (
<div className="flex items-center gap-2" key={key}>
<Checkbox
id={key}
checked={expert[key as keyof typeof expert]}
onCheckedChange={(value) =>
handleExpertOutputChange(
key as keyof typeof expert,
value as boolean
)
}
/>
<Label htmlFor={key}>
{key.charAt(0).toUpperCase() + key.slice(1)}
</Label>
</div>
))}
</div>
</div>
<div className="mt-5 space-y-2">
<Label>{t("description")}</Label>
<Controller

View File

@ -22,6 +22,7 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import JoditEditor from "jodit-react";
import {
createTask,
createTaskTa,
getTask,
getUserLevelForAssignments,
} from "@/service/task";
@ -318,35 +319,37 @@ export default function FormTaskTa() {
id?: number;
title: string;
assignedToLevel: any;
assignmentPurpose: any;
assignedToUsers: any;
assignmentTypeId: string;
fileTypeOutput: string;
narration: string;
platformType: string | null;
assignmentMainTypeId: any;
taskType: string;
assignmentType: string;
assignedToRole: string;
broadcastType: string;
expertCompetencies: string;
attachmentUrl: string[];
} = {
...data,
// assignmentType,
// assignmentCategory,
assignedToLevel: handlePoldaPolresChange(),
assignmentPurpose: assignmentPurposeString,
assignedToUsers: assignmentPurposeString,
assignedToRole: selectedTarget,
taskType: taskType,
assignmentType: taskType,
broadcastType: broadcastType,
assignmentMainTypeId: mainType,
assignmentTypeId: type,
fileTypeOutput: selectedOutputs,
narration: data.naration,
platformType: "",
expertCompetencies: "1,2,3",
title: data.title,
attachmentUrl: links,
};
const response = await createTask(requestData);
const response = await createTaskTa(requestData);
console.log("Form Data Submitted:", requestData);
console.log("response", response);
@ -719,7 +722,19 @@ export default function FormTaskTa() {
</Dialog>
</div>
</div>
<div className="mt-5 space-y-2">
<Label>{t("assigment-type")} </Label>
<RadioGroup
value={taskType}
onValueChange={(value) => setTaskType(String(value))}
className="flex flex-wrap gap-3"
>
<RadioGroupItem value="atensi-khusus" id="khusus" />
<Label htmlFor="atensi-khusus">Atensi Khusus</Label>
<RadioGroupItem value="tugas-harian" id="harian" />
<Label htmlFor="tugas-harian">Tugas Harian</Label>
</RadioGroup>
</div>
<div className="mt-5 space-y-2">
<Label>{t("areas-expertise")}</Label>
<div className="flex flex-wrap gap-4">

25
service/report/report.ts Normal file
View File

@ -0,0 +1,25 @@
import {
httpGetInterceptor,
httpPostInterceptor,
} from "../http-config/http-interceptor-service";
export async function paginationReport(
size: any,
page: number,
title: string = "",
categoryFilter: any,
statusFilter: any
) {
return await httpGetInterceptor(
`/media/report/list?enablePage=1&page=${page}&size=${size}&title=${title}&categoryId=${categoryFilter}&statusId=${statusFilter}`
);
}
export async function getPreviewById(id: any) {
return await httpGetInterceptor(`/media/report/view?id=${id}`);
}
export async function saveReport(data: any) {
const url = "/media/report";
return httpPostInterceptor(url, data);
}

View File

@ -112,3 +112,35 @@ export async function finishTask(id: any) {
const url = `assignment/finish?id=${id}`;
return httpPostInterceptor(url);
}
export async function listTaskTa(
page: any,
title: string = "",
size: any,
code: any,
createdAt: any,
taskType: string,
status: number[]
) {
let statusQuery = "";
if (status.includes(1)) {
statusQuery = "&isDone=true";
} else if (status.includes(2)) {
statusQuery = "&isDone=false";
}
return httpGetInterceptor(
`assignment-expert/pagination?enablePage=1&size=${size}&page=${page}&title=${title}&taskType=${taskType}&uniqueCode=${code}&createdAt=${createdAt}${statusQuery}`
);
}
export async function createTaskTa(data: any) {
const pathUrl = "assignment-expert";
return httpPostInterceptor(pathUrl, data);
}
export async function getTaskTa(id: any) {
const url = `/assignment-expert?id=${id}`;
return httpGetInterceptor(url);
}