diff --git a/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx b/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx index 21443c40..d880aefb 100644 --- a/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx +++ b/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx @@ -9,12 +9,7 @@ import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Calendar } from "@/components/ui/calendar"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { - Book, - CheckCheck, - Plus, - Timer, -} from "lucide-react"; +import { Book, CheckCheck, Plus, Timer } from "lucide-react"; import { Checkbox } from "@/components/ui/checkbox"; import { EventContentArg } from "@fullcalendar/core"; import EventModal from "./event-modal"; @@ -124,7 +119,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { const [calendarEvents, setCalendarEvents] = useState([]); const [isLoading, setIsLoading] = useState(false); const t = useTranslations("CalendarApp"); - + // Modal states const [sheetOpen, setSheetOpen] = useState(false); const [date, setDate] = useState(new Date()); @@ -171,7 +166,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { const monthData = res?.data?.data; if (monthData) { const allEvents: CalendarEvent[] = []; - // Map API data to the calendarEvents structure + // Map API data to the calendarEvents structure const events = monthData?.map((event: any) => ({ id: event.id.toString(), title: event.title, @@ -207,7 +202,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { "", "" ); - + if (res?.error) { error(res?.message || "Failed to fetch yearly events"); return; @@ -230,17 +225,20 @@ const CalendarView = ({ categories }: CalendarViewProps) => { const filteredEvents = calendarEvents.filter((event) => { if (!selectedCategory.length) return false; console.log("Event category : ", selectedCategory); - + const eventCategories = event.extendedProps.calendar ?.split(",") .map((val: string) => val.trim()); const allCategoryId = ["1", "2", "3", "4", "5"]; // Cek apakah SEMUA validTypeIds ada di typeIdsInData - const hasAllCategories = allCategoryId.every(categoryId => selectedCategory.includes(categoryId)); + const hasAllCategories = allCategoryId.every((categoryId) => + selectedCategory.includes(categoryId) + ); - return eventCategories?.some((cat: string) => - selectedCategory.includes(cat) || (hasAllCategories && cat == "0") + return eventCategories?.some( + (cat: string) => + selectedCategory.includes(cat) || (hasAllCategories && cat == "0") ); }); @@ -266,7 +264,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { }; const handleCategorySelection = (category: string) => { - setSelectedCategory(prev => { + setSelectedCategory((prev) => { if (prev.includes(category)) { return prev.filter((c) => c !== category); } else { @@ -313,7 +311,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { const getEventColor = (type: EventType): string => { const typeSplit = type.split(","); const firstType = typeSplit[0] as EventType; - + const colors: Record = { "0": "bg-black", "1": "bg-yellow-500", @@ -322,7 +320,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { "4": "bg-orange-500", "5": "bg-green-400", }; - + return colors[firstType] || "bg-gray-400"; }; @@ -346,15 +344,22 @@ const CalendarView = ({ categories }: CalendarViewProps) => { const renderEventContent = (eventInfo: any) => { const { title } = eventInfo.event; - const { createdByName, isPublish, calendar } = eventInfo.event.extendedProps; + const { createdByName, isPublish, calendar } = + eventInfo.event.extendedProps; const bgColor = getEventColor(calendar); const colorList = getEventColorList(calendar); return ( -
+
- {isPublish === true ? : } + {isPublish === true ? ( + + ) : ( + + )}

{title}

@@ -386,7 +391,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { bgColor, colorList, }) => ( -

handleClickListItem(item)} > @@ -461,8 +466,12 @@ const CalendarView = ({ categories }: CalendarViewProps) => { text={event.title} createdBy={event.createdByName} isPublish={event.isPublish} - bgColor={getEventColor(event.agendaType as EventType)} - colorList={getEventColorList(event.agendaType as EventType)} + bgColor={getEventColor( + event.agendaType as EventType + )} + colorList={getEventColorList( + event.agendaType as EventType + )} /> ))}
@@ -537,7 +546,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { {t("addEvent")} )} - + {roleId === 3 && userLevelId === 216 && ( @@ -593,7 +602,9 @@ const CalendarView = ({ categories }: CalendarViewProps) => { className={category.className} id={category.label} checked={selectedCategory.includes(category.value)} - onCheckedChange={() => handleCategorySelection(category.value)} + onCheckedChange={() => + handleCategorySelection(category.value) + } /> @@ -605,7 +616,12 @@ const CalendarView = ({ categories }: CalendarViewProps) => { { handleDateChange(info.view.currentStart, info.view.currentEnd); handleViewChange(info.view.type); }} - viewClassNames={activeView === "listYear" ? "hide-calendar-grid" : ""} + viewClassNames={ + activeView === "listYear" ? "hide-calendar-grid" : "" + } /> {activeView === "listYear" && ( @@ -657,7 +675,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => {
- + { ); }; -export default CalendarView; \ No newline at end of file +export default CalendarView; diff --git a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx index 89b2fb3b..83c0bdbe 100644 --- a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx +++ b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx @@ -148,10 +148,12 @@ const EventModal = ({ satker: false, international: false, }); + const [agendaType, setAgendaType] = React.useState(""); // State untuk agendaType - const [selectedPolda, setSelectedPolda] = React.useState([]); // Untuk data Polda - const [selectedSatker, setSelectedSatker] = React.useState([]); - const [selectedPolres, setSelectedPolres] = React.useState([]); + const [selectedPolda, setSelectedPolda] = useState([]); + const [selectedPolres, setSelectedPolres] = useState([]); + const [selectedSatker, setSelectedSatker] = useState([]); + const isDetailMode = true; const [wavesurfer, setWavesurfer] = useState(); const [isPlaying, setIsPlaying] = useState(false); const [isPublishing, setIsPublishing] = useState(false); @@ -174,10 +176,7 @@ const EventModal = ({ const detail = res?.data?.data; setDetailData(detail); - const description = res?.data?.data?.description; - console.log("description", res?.data?.data?.description); - - // Set nilai awal description ke form control + const description = detail?.description; if (description) { setValue("description", description); } @@ -196,17 +195,56 @@ const EventModal = ({ attachments?.filter((file: any) => file.fileTypeId == 4) ); - const agendaType = detail?.agendaType; - setWilayahPublish({ - semua: agendaType === "all", - nasional: agendaType === "mabes", - polda: agendaType === "polda", - polres: agendaType === "polres", - satker: agendaType === "satker", - international: agendaType === "international", - }); - } + const rawAgendaTypes = detail?.agendaType?.split(",") || []; // ["0","1","2","3","4","5"] + const assignedToLevel = detail?.assignedToLevel?.split(",") || []; + const wilayahState = { + semua: false, + nasional: false, + polda: false, + polres: false, + satker: false, + international: false, + }; + + rawAgendaTypes.forEach((type: any) => { + switch (type) { + case "0": + wilayahState.semua = true; + break; + case "1": + wilayahState.nasional = true; + break; + case "2": + wilayahState.polda = true; + break; + case "3": + wilayahState.polres = true; + break; + case "4": + wilayahState.satker = true; + break; + case "5": + wilayahState.international = true; + break; + default: + break; + } + }); + + setWilayahPublish(wilayahState); + + // Atur unit berdasarkan agendaType + if (rawAgendaTypes.includes("2")) { + setSelectedPolda(assignedToLevel); + } + if (rawAgendaTypes.includes("3")) { + setSelectedPolres(assignedToLevel); + } + if (rawAgendaTypes.includes("4")) { + setSelectedSatker(assignedToLevel); + } + } fetchDetailData(); }, [event, setValue]); @@ -233,33 +271,39 @@ const EventModal = ({ const toggleWilayah = (key: string) => { setWilayahPublish((prev: any) => { - const newState = { ...prev, [key]: !prev[key] }; + let newState = { ...prev }; - // Handle "semua" logic to check all options - if (key === "semua" && newState.semua) { - setAgendaType("all"); - return { - semua: true, - nasional: true, - polda: true, - polres: true, - satker: true, - international: true, + // Jika key === semua dan sebelumnya belum aktif, aktifkan semua + if (key === "semua") { + const newChecked = !prev.semua; + newState = { + semua: newChecked, + nasional: newChecked, + polda: newChecked, + polres: newChecked, + satker: newChecked, + international: newChecked, }; + + if (newChecked) { + setAgendaType("0,1,2,3,4,5"); + } else { + setAgendaType(""); + } + + return newState; } - // Uncheck "semua" if any other option is selected - if (key !== "semua") { - newState.semua = false; - } + // Jika key bukan "semua" + newState[key] = !prev[key]; + newState.semua = false; // Uncheck "semua" jika yang dipilih adalah individu - // Set agendaType based on the selected checkbox - if (newState.nasional) setAgendaType("mabes"); - else if (newState.polda) setAgendaType("polda"); - else if (newState.polres) setAgendaType("polres"); - else if (newState.satker) setAgendaType("satker"); - else if (newState.international) setAgendaType("international"); - else setAgendaType(""); // Reset if no checkbox is selected + // Hitung ulang agendaType berdasarkan pilihan + const selectedKeys = Object.entries(newState) + .filter(([k, v]) => v && k !== "semua") + .map(([k]) => wilayahValueMap[k]); + + setAgendaType(selectedKeys.join(",")); return newState; }); @@ -269,12 +313,25 @@ const EventModal = ({ const agendaTypeList: string[] = []; const assignedToLevelList: string[] = []; - // Mapping dari checkbox wilayah ke agendaType - Object.keys(wilayahPublish).forEach((key) => { - if (wilayahPublish[key as keyof typeof wilayahPublish]) { - agendaTypeList.push(wilayahValueMap[key]); - } - }); + // // Mapping dari checkbox wilayah ke agendaType + // Object.keys(wilayahPublish).forEach((key) => { + // if (wilayahPublish[key as keyof typeof wilayahPublish]) { + // agendaTypeList.push(wilayahValueMap[key]); + // } + // }); + + if (wilayahPublish.semua) { + agendaTypeList.push("0", "1", "2", "3", "4", "5"); + } else { + Object.keys(wilayahPublish).forEach((key) => { + if ( + wilayahPublish[key as keyof typeof wilayahPublish] && + key !== "semua" + ) { + agendaTypeList.push(wilayahValueMap[key]); + } + }); + } // Unit-unit berdasarkan wilayah yang aktif if (wilayahPublish.polda && selectedPolda.length > 0) { @@ -558,6 +615,7 @@ const EventModal = ({ confirmButtonText: "OK", }).then(() => { router.push(redirect); + window.location.reload(); }); }; @@ -784,7 +842,8 @@ const EventModal = ({ {wilayahPublish.polda && ( setSelectedPolda(data) } @@ -802,8 +861,9 @@ const EventModal = ({ {wilayahPublish.polres && ( setSelectedPolres(data) } @@ -821,8 +881,9 @@ const EventModal = ({ {wilayahPublish.satker && ( setSelectedSatker(data) } diff --git a/components/form/shared/ask-expert-form.tsx b/components/form/shared/ask-expert-form.tsx index f5685e02..16b553a5 100644 --- a/components/form/shared/ask-expert-form.tsx +++ b/components/form/shared/ask-expert-form.tsx @@ -202,6 +202,23 @@ export default function FormAskExpert() { const details = response?.data?.data; setDetail(details); + + if (details?.assignedToLevel) { + const levels: Set = new Set( + details.assignedToLevel.split(",").map((x: any) => Number(x)) + ); + setCheckedLevels(levels); + } + + if (details?.assignedToUsers) { + const userIds = details.assignedToUsers.split(",").map(Number); + setCheckedLevels(new Set(userIds)); + } + + if (details?.expertCompetencies) { + const compIds = details.expertCompetencies.split(",").map(Number); + setSelectedCompetencies(new Set(compIds)); + } } } initState(); @@ -515,7 +532,7 @@ export default function FormAskExpert() { return (
-

{t("form-task")}

+

{t("form-task-ta")}

{detail !== undefined ? (
@@ -617,7 +634,14 @@ export default function FormAskExpert() { } className="mr-3" /> - {expert.fullname} +
+
+ {expert.fullname} +
+
+ ({expert.username}) +
+
))} @@ -625,6 +649,46 @@ export default function FormAskExpert() {
+ {checkedLevels.size > 0 && ( +
+ +
+ {Array.from(checkedLevels).map((expertId) => { + const expert = listExpert?.find( + (exp: any) => exp.id === expertId + ); + return expert ? ( +
+ {expert.fullname} + +
+ ) : null; + })} +
+
+ )}
diff --git a/components/form/shared/do-it-yourself-form.tsx b/components/form/shared/do-it-yourself-form.tsx index 12473463..49f9d88c 100644 --- a/components/form/shared/do-it-yourself-form.tsx +++ b/components/form/shared/do-it-yourself-form.tsx @@ -636,7 +636,7 @@ export default function FormDoItYourself() { return (
-

{t("form-task")}

+

{t("form-task-ta-do")}

{detail !== undefined ? (
diff --git a/components/form/task-ta/task-ta-detail-form.tsx b/components/form/task-ta/task-ta-detail-form.tsx index e667b7b8..62f3b493 100644 --- a/components/form/task-ta/task-ta-detail-form.tsx +++ b/components/form/task-ta/task-ta-detail-form.tsx @@ -10,42 +10,23 @@ import * as z from "zod"; import Swal from "sweetalert2"; import withReactContent from "sweetalert2-react-content"; import { useParams, useRouter } from "next/navigation"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; import { Checkbox } from "@/components/ui/checkbox"; -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; -import JoditEditor from "jodit-react"; import { - acceptAssignment, + acceptAssignmentTa, createAssignmentResponse, - createTask, deleteAssignmentResponse, deleteTask, - finishTask, + finishTaskTa, getAcceptance, getAcceptanceAssignmentStatus, getAssignmentResponseList, getMediaUpload, getMediaUploadTa, - getTask, getTaskTa, getUserLevelForAssignments, + getUserLevelForExpert, } from "@/service/task"; import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import { - ChevronDown, - ChevronUp, Dock, DotSquare, ImageIcon, @@ -61,14 +42,20 @@ import { close, error, loading } from "@/lib/swal"; import { getCookiesDecrypt } from "@/lib/utils"; import { Avatar, AvatarImage } from "@/components/ui/avatar"; import { successCallback } from "@/config/swal"; -import FileUploader from "../shared/file-uploader"; -import { AudioRecorder } from "react-audio-voice-recorder"; import Image from "next/image"; import { Icon } from "@iconify/react/dist/iconify.js"; import WavesurferPlayer from "@wavesurfer/react"; import WaveSurfer from "wavesurfer.js"; import { InputGroup, InputGroupText } from "@/components/ui/input-group"; import { useTranslations } from "next-intl"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { getListCompetencies } from "@/service/management-user/management-user"; const taskSchema = z.object({ uniqueCode: z.string().min(1, { message: "Judul diperlukan" }), @@ -252,7 +239,11 @@ export default function FormTaskTaDetail() { const [acceptAcceptance, setAcceptAcceptance] = useState( [] ); - + const [listExpert, setListExpert] = useState([]); + const [userCompetencies, setUserCompetencies] = useState([]); + const [selectedCompetencies, setSelectedCompetencies] = useState>( + new Set() + ); const [totalPage, setTotalPage] = React.useState(1); const [dataTable, setDataTable] = React.useState([]); const [totalData, setTotalData] = React.useState(1); @@ -327,37 +318,37 @@ 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 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] - ); + // const allChecked = ["video", "audio", "image", "text"].every( + // (k) => updated[k as keyof typeof expertise] + // ); - updated.semua = allChecked; - setExpertiseOutput(updated); - } - }; + // updated.semua = allChecked; + // setExpertiseOutput(updated); + // } + // }; const handleExpertOutputChange = ( key: keyof typeof expert, @@ -383,6 +374,68 @@ export default function FormTaskTaDetail() { } }; + useEffect(() => { + getDataAdditional(); + }, []); + + async function getDataAdditional() { + const resCompetencies = await getListCompetencies(); + console.log("competency", resCompetencies); + setUserCompetencies(resCompetencies?.data?.data); + } + + useEffect(() => { + async function fetchListExpert() { + setIsLoading(true); + try { + const response = await getUserLevelForExpert(id); + setListExpert(response?.data?.data); + console.log("tenaga ahli", response?.data?.data); + } catch (error) { + console.error("Error fetching Polda/Polres data:", error); + } finally { + setIsLoading(false); + } + } + fetchListExpert(); + }, []); + + useEffect(() => { + const fetchExpertsForCompetencies = async () => { + const allExperts: any[] = []; + + for (const compId of Array.from(selectedCompetencies)) { + const response = await getUserLevelForExpert(compId); + const experts = response?.data?.data || []; + allExperts.push(...experts); + } + + const uniqueExperts = Array.from( + new Map(allExperts.map((e) => [e.id, e])).values() + ); + + setListExpert(uniqueExperts); + }; + + if (selectedCompetencies.size > 0) { + fetchExpertsForCompetencies(); + } else { + setListExpert([]); + } + }, [selectedCompetencies]); + + const handleCompetencyChange = async (competencyId: number) => { + setSelectedCompetencies((prev) => { + const updated = new Set(prev); + if (updated.has(competencyId)) { + updated.delete(competencyId); + } else { + updated.add(competencyId); + } + return updated; + }); + }; + useEffect(() => { async function fetchPoldaPolres() { setIsLoading(true); @@ -458,6 +511,16 @@ export default function FormTaskTaDetail() { setCheckedLevels(levels); } + if (details?.assignedToUsers) { + const userIds = details.assignedToUsers.split(",").map(Number); + setCheckedLevels(new Set(userIds)); + } + + if (details?.expertCompetencies) { + const compIds = details.expertCompetencies.split(",").map(Number); + setSelectedCompetencies(new Set(compIds)); + } + const attachment = details?.files; setImageUploadedFiles( attachment?.filter((file: any) => file.fileTypeId == 1) @@ -542,7 +605,7 @@ export default function FormTaskTaDetail() { confirmButtonText: "OK", }).then((result) => { if (result.isConfirmed) { - router.push("/en/contributor/task"); + router.push("/en/contributor/task-ta"); } }); }; @@ -682,7 +745,7 @@ export default function FormTaskTaDetail() { const handleAcceptAcceptance = async () => { loading(); console.log("Id user :", userId); - const response = await acceptAssignment(id); + const response = await acceptAssignmentTa(id); if (response?.error) { error(response?.message); @@ -773,7 +836,7 @@ export default function FormTaskTaDetail() { ); async function finishAssignment() { - const response = finishTask(id); + const response = finishTaskTa(id); // if (response.error) { // error(response.message); @@ -1011,48 +1074,98 @@ export default function FormTaskTaDetail() {
- {Object.keys(expertise).map((key) => ( -
+ {userCompetencies?.map((item: any) => ( +
- handleExpertiseOutputChange( - key as keyof typeof expertise, - value as boolean - ) - } + id={`comp-${item.id}`} + checked={selectedCompetencies.has(item.id)} + onCheckedChange={() => handleCompetencyChange(item.id)} disabled /> - +
))}
-
- + {/*
- {Object.keys(expert).map((key) => ( -
- - handleExpertOutputChange( - key as keyof typeof expert, - value as boolean - ) - } - /> - + + + + + + + Daftar Tenaga Ahli + +
+ {listExpert?.map((expert: any) => ( +
+ +
+ ))} +
+
+
+
*/} + {checkedLevels.size > 0 && ( +
+ +
+ {Array.from(checkedLevels).map((expertId) => { + const expert = listExpert?.find( + (exp: any) => exp.id === expertId + ); + return expert ? ( +
+ {expert.fullname} + +
+ ) : null; + })}
- ))} -
+
+ )}
diff --git a/components/form/task-ta/task-ta-edit-form.tsx b/components/form/task-ta/task-ta-edit-form.tsx index 2d06e489..3b6211de 100644 --- a/components/form/task-ta/task-ta-edit-form.tsx +++ b/components/form/task-ta/task-ta-edit-form.tsx @@ -26,6 +26,7 @@ import { getTask, getTaskTa, getUserLevelForAssignments, + getUserLevelForExpert, } from "@/service/task"; import { Dialog, @@ -40,6 +41,7 @@ import { Dock, ImageIcon, Music, + Trash2, VideoIcon, } from "lucide-react"; import FileUploader from "../shared/file-uploader"; @@ -52,6 +54,7 @@ import { Upload } from "tus-js-client"; import { error, loading } from "@/lib/swal"; import dynamic from "next/dynamic"; import { useTranslations } from "next-intl"; +import { getListCompetencies } from "@/service/management-user/management-user"; const taskSchema = z.object({ // uniqueCode: z.string().min(1, { message: "Judul diperlukan" }), @@ -148,11 +151,18 @@ export default function FormTaskTaEdit() { const [broadcastType, setBroadcastType] = useState(""); // untuk Tipe Penugasan const [type, setType] = useState("1"); const [selectedTarget, setSelectedTarget] = useState("3,4"); + + const [listExpert, setListExpert] = useState([]); + const [userCompetencies, setUserCompetencies] = useState([]); + const [selectedCompetencies, setSelectedCompetencies] = useState>( + new Set() + ); + const [detail, setDetail] = useState(); const [urlInputs, setUrlInputs] = useState([]); const [refresh] = useState(false); const [listDest, setListDest] = useState([]); // Data Polda dan Polres - const [checkedLevels, setCheckedLevels] = useState(new Set()); + const [checkedLevels, setCheckedLevels] = useState>(new Set()); const [expandedPolda, setExpandedPolda] = useState([{}]); const [isLoading, setIsLoading] = useState(false); const [audioFile, setAudioFile] = useState(null); @@ -247,6 +257,68 @@ export default function FormTaskTaEdit() { } }; + useEffect(() => { + getDataAdditional(); + }, []); + + async function getDataAdditional() { + const resCompetencies = await getListCompetencies(); + console.log("competency", resCompetencies); + setUserCompetencies(resCompetencies?.data?.data); + } + + useEffect(() => { + async function fetchListExpert() { + setIsLoading(true); + try { + const response = await getUserLevelForExpert(id); + setListExpert(response?.data?.data); + console.log("tenaga ahli", response?.data?.data); + } catch (error) { + console.error("Error fetching Polda/Polres data:", error); + } finally { + setIsLoading(false); + } + } + fetchListExpert(); + }, []); + + useEffect(() => { + const fetchExpertsForCompetencies = async () => { + const allExperts: any[] = []; + + for (const compId of Array.from(selectedCompetencies)) { + const response = await getUserLevelForExpert(compId); + const experts = response?.data?.data || []; + allExperts.push(...experts); + } + + const uniqueExperts = Array.from( + new Map(allExperts.map((e) => [e.id, e])).values() + ); + + setListExpert(uniqueExperts); + }; + + if (selectedCompetencies.size > 0) { + fetchExpertsForCompetencies(); + } else { + setListExpert([]); + } + }, [selectedCompetencies]); + + const handleCompetencyChange = async (competencyId: number) => { + setSelectedCompetencies((prev) => { + const updated = new Set(prev); + if (updated.has(competencyId)) { + updated.delete(competencyId); + } else { + updated.add(competencyId); + } + return updated; + }); + }; + useEffect(() => { async function fetchPoldaPolres() { setIsLoading(true); @@ -285,12 +357,22 @@ export default function FormTaskTaEdit() { } if (details?.assignedToLevel) { - const levels = new Set( - details.assignedToLevel.split(",").map(Number) + const levels: Set = new Set( + details.assignedToLevel.split(",").map((x: any) => Number(x)) ); setCheckedLevels(levels); } + if (details?.assignedToUsers) { + const userIds = details.assignedToUsers.split(",").map(Number); + setCheckedLevels(new Set(userIds)); + } + + if (details?.expertCompetencies) { + const compIds = details.expertCompetencies.split(",").map(Number); + setSelectedCompetencies(new Set(compIds)); + } + const attachment = details?.files; setImageUploadedFiles( attachment?.filter((file: any) => file.fileTypeId == 1) @@ -376,7 +458,7 @@ export default function FormTaskTaEdit() { confirmButtonText: "OK", }).then((result) => { if (result.isConfirmed) { - router.push("/en/contributor/task"); + router.push("/en/contributor/task-ta"); } }); }; @@ -393,9 +475,9 @@ export default function FormTaskTaEdit() { }); }; - const handlePoldaPolresChange = () => { - return Array.from(checkedLevels).join(","); // Mengonversi Set ke string - }; + // const handlePoldaPolresChange = () => { + // return Array.from(checkedLevels).join(","); // Mengonversi Set ke string + // }; const handleUnitChange = ( key: keyof typeof unitSelection, @@ -454,6 +536,10 @@ export default function FormTaskTaEdit() { } }; + const handleExpertChange = () => { + return Array.from(checkedLevels).join(","); + }; + const save = async (data: TaskSchema) => { const fileTypeMapping = { all: "1", @@ -483,16 +569,11 @@ export default function FormTaskTaEdit() { const requestData: { id?: any; title: string; - assignedToLevel: any; assignedToUsers: any; assignmentTypeId: string; - fileTypeOutput: string; narration: string; - platformType: string | null; - assignmentMainTypeId: any; assignmentType: string; assignedToRole: string; - broadcastType: string; expertCompetencies: string; attachmentUrl: string[]; } = { @@ -500,17 +581,12 @@ export default function FormTaskTaEdit() { // assignmentType, // assignmentCategory, id: detail?.id || null, - assignedToLevel: handlePoldaPolresChange(), - assignedToUsers: assignmentPurposeString, + assignedToUsers: handleExpertChange(), assignedToRole: selectedTarget, assignmentType: taskType, - broadcastType: broadcastType, - assignmentMainTypeId: mainType, assignmentTypeId: type, - fileTypeOutput: selectedOutputs, narration: data.naration, - platformType: "", - expertCompetencies: "1,2,3", + expertCompetencies: Array.from(selectedCompetencies).join(","), title: data.title, attachmentUrl: links, }; @@ -808,47 +884,97 @@ export default function FormTaskTaEdit() {
- {Object.keys(expertise).map((key) => ( -
+ {userCompetencies?.map((item: any) => ( +
- handleExpertiseOutputChange( - key as keyof typeof expertise, - value as boolean - ) - } + id={`comp-${item.id}`} + checked={selectedCompetencies.has(item.id)} + onCheckedChange={() => handleCompetencyChange(item.id)} /> - +
))}
-
- {Object.keys(expert).map((key) => ( -
- - handleExpertOutputChange( - key as keyof typeof expert, - value as boolean - ) - } - /> - -
- ))} + + + + + + + Daftar Tenaga Ahli + +
+ {listExpert?.map((expert: any) => ( +
+ +
+ ))} +
+
+
+ {checkedLevels.size > 0 && ( +
+ +
+ {Array.from(checkedLevels).map((expertId) => { + const expert = listExpert?.find( + (exp: any) => exp.id === expertId + ); + return expert ? ( +
+ {expert.fullname} + +
+ ) : null; + })} +
+
+ )}
@@ -1079,13 +1205,42 @@ export default function FormTaskTaEdit() { />
))} - +
+ + {links.map((link, index) => ( +
+ + handleLinkChange(index, e.target.value) + } + /> + {links.length > 1 && ( + + )} +
+ ))} + +
diff --git a/messages/en.json b/messages/en.json index 88c4ba53..72448dfe 100644 --- a/messages/en.json +++ b/messages/en.json @@ -784,6 +784,8 @@ "assignment-type": "Assignment Type", "description-task": "Description Task", "form-task": "Form Task", + "form-task-ta": "Form Ask the Expert", + "form-task-ta-do": "Form Do it yourself", "assignment-selection": "Assignment Recipient", "custom": "Costum", "assigment-type": "Assigment Type", diff --git a/messages/in.json b/messages/in.json index 4aba77fa..659c85ce 100644 --- a/messages/in.json +++ b/messages/in.json @@ -571,47 +571,33 @@ "divisionNews": "Berita Satker", "areaCoverage": "Liputan Wilayah & Satker", "calendar": "KALENDER ACARA", - "january": "Januari", - "february": "February", - "march": "March", - "may": "May", - "june": "Juni", - "july": "Juli", - "august": "Agustus", - "october": "Oktober", - "december": "Desember", - "eventList": "Daftar Acara", - "noEvent": "Tidak ada acara yang tersedia", - "eventDetails": "Detail Acara", - "date": "Tanggal:", - "selectEvent": "Pilih acara untuk melihat detail", - "regionalPolice": "Polda Jajaran", - "policeDivision": "Satuan Kerja Polri", - "close": "Tutup", - "survey1": "SURVEI KEPUASAN PENGGUNA MEDIAHUB POLRI", - "survey2": "Kami menghargai pendapat Anda! Survei ini bertujuan untuk meningkatkan kualitas layanan MediaHub Polri. Mohon luangkan waktu beberapa menit untuk mengisi survei ini.", - "survey3": "SURVEY SEKARANG", - "survey4": "SURVEI KEPUASAN PENGGUNA MEDIAHUB POLRI", - "survey5": "Kami menghargai pendapat Anda! Survei ini bertujuan untuk meningkatkan kualitas layanan MediaHub Polri.", - "survey6": "1. Seberapa sering Anda mengakses MediaHub Polri?", - "survey7": "2. Bagaimana pengalaman Anda dalam mengakses website ini?", - "survey8": "3. Seberapa puas Anda dengan informasi yang tersedia di MediaHub Polri?", - "survey9": "4. Apakah Anda merasa website ini membantu dalam mendapatkan informasi terkait Polri?", - "survey10": "5. Apa saran atau masukan Anda?" - - - - - - - - - - - - - - + "january": "Januari", + "february": "February", + "march": "March", + "may": "May", + "june": "Juni", + "july": "Juli", + "august": "Agustus", + "october": "Oktober", + "december": "Desember", + "eventList": "Daftar Acara", + "noEvent": "Tidak ada acara yang tersedia", + "eventDetails": "Detail Acara", + "date": "Tanggal:", + "selectEvent": "Pilih acara untuk melihat detail", + "regionalPolice": "Polda Jajaran", + "policeDivision": "Satuan Kerja Polri", + "close": "Tutup", + "survey1": "SURVEI KEPUASAN PENGGUNA MEDIAHUB POLRI", + "survey2": "Kami menghargai pendapat Anda! Survei ini bertujuan untuk meningkatkan kualitas layanan MediaHub Polri. Mohon luangkan waktu beberapa menit untuk mengisi survei ini.", + "survey3": "SURVEY SEKARANG", + "survey4": "SURVEI KEPUASAN PENGGUNA MEDIAHUB POLRI", + "survey5": "Kami menghargai pendapat Anda! Survei ini bertujuan untuk meningkatkan kualitas layanan MediaHub Polri.", + "survey6": "1. Seberapa sering Anda mengakses MediaHub Polri?", + "survey7": "2. Bagaimana pengalaman Anda dalam mengakses website ini?", + "survey8": "3. Seberapa puas Anda dengan informasi yang tersedia di MediaHub Polri?", + "survey9": "4. Apakah Anda merasa website ini membantu dalam mendapatkan informasi terkait Polri?", + "survey10": "5. Apa saran atau masukan Anda?" }, "FilterPage": { "image": "Foto", @@ -798,6 +784,8 @@ "assignment-type": "Jenis Penugasan", "description-task": "Narasi Penugasan", "form-task": "Form Penugasan", + "form-task-ta": "Form Tanya Tenaga Ahli", + "form-task-ta-do": "Form Tenaga Ahli Kurasi", "assignment-selection": "Penerima Tugas", "custom": "Kostum", "assigment-type": "Jenis Tugas", diff --git a/service/task.ts b/service/task.ts index 8c853a34..ef86fff2 100644 --- a/service/task.ts +++ b/service/task.ts @@ -108,6 +108,11 @@ export async function acceptAssignment(id: any) { return httpPostInterceptor(url, id); } +export async function acceptAssignmentTa(id: any) { + const url = `assignment-expert/acceptance?id=${id}`; + return httpPostInterceptor(url, id); +} + export async function postFinishAcceptance(id: any) { const url = `assignment/finish-acceptance?id=${id}`; return httpPostInterceptor(url, id); @@ -128,6 +133,11 @@ export async function finishTask(id: any) { return httpPostInterceptor(url); } +export async function finishTaskTa(id: any) { + const url = `assignment-expert/finish?id=${id}`; + return httpPostInterceptor(url); +} + export async function listTaskTa( page: any, title: string = "",