diff --git a/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx b/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx index 1861e18b..21443c40 100644 --- a/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx +++ b/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx @@ -1,23 +1,19 @@ "use client"; -import React, { useState, useEffect, act } from "react"; -import FullCalendar from "@fullcalendar/react"; // must go before plugins +import React, { useState, useEffect } from "react"; +import FullCalendar from "@fullcalendar/react"; import dayGridPlugin from "@fullcalendar/daygrid"; import timeGridPlugin from "@fullcalendar/timegrid"; import interactionPlugin, { Draggable } from "@fullcalendar/interaction"; import listPlugin from "@fullcalendar/list"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; -import ExternalDraggingevent from "./dragging-events"; import { Calendar } from "@/components/ui/calendar"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Book, CheckCheck, - CheckSquare2, - CheckSquare2Icon, Plus, Timer, - TimerIcon, } from "lucide-react"; import { Checkbox } from "@/components/ui/checkbox"; import { EventContentArg } from "@fullcalendar/core"; @@ -42,8 +38,8 @@ import { } from "@/components/ui/dialog"; const wait = () => new Promise((resolve) => setTimeout(resolve, 1000)); + interface CalendarViewProps { - // events: CalendarEvent[]; categories: CalendarCategory[]; } @@ -59,12 +55,11 @@ export type CalendarEvent = { extendedProps: { calendar: string; description: string; + isPublish?: boolean; + createdByName?: string; }; }; -const INITIAL_YEAR = dayjs().format("YYYY"); -const INITIAL_MONTH = dayjs().format("M"); - export interface AgendaSettingsAPIResponse { id: number; title: string; @@ -74,24 +69,25 @@ export interface AgendaSettingsAPIResponse { startDate: string; endDate: string; isActive: boolean; + isPublish: boolean; createdAt: string; updatedAt: string; createdById: number | null; } interface YearlyData { - january?: Event[]; - february?: Event[]; - march?: Event[]; - april?: Event[]; - may?: Event[]; - june?: Event[]; - july?: Event[]; - august?: Event[]; - september?: Event[]; - october?: Event[]; - november?: Event[]; - december?: Event[]; + january?: AgendaSettingsAPIResponse[]; + february?: AgendaSettingsAPIResponse[]; + march?: AgendaSettingsAPIResponse[]; + april?: AgendaSettingsAPIResponse[]; + may?: AgendaSettingsAPIResponse[]; + june?: AgendaSettingsAPIResponse[]; + july?: AgendaSettingsAPIResponse[]; + august?: AgendaSettingsAPIResponse[]; + september?: AgendaSettingsAPIResponse[]; + october?: AgendaSettingsAPIResponse[]; + november?: AgendaSettingsAPIResponse[]; + december?: AgendaSettingsAPIResponse[]; } interface MonthCardProps { @@ -100,411 +96,345 @@ interface MonthCardProps { } interface ListItemProps { - item: any; + item: AgendaSettingsAPIResponse; text: string; createdBy: string; isPublish: boolean | null; bgColor: string; + colorList: string[] | null; } interface APIResponse { - error: boolean; - message: any; - data: AgendaSettingsAPIResponse[] | null; + success: boolean; + message: string; + data: YearlyData | null; + errorCode: string | null; } +type EventType = "0" | "1" | "2" | "3" | "4" | "5"; + +const INITIAL_YEAR = dayjs().format("YYYY"); +const INITIAL_MONTH = dayjs().format("M"); + const CalendarView = ({ categories }: CalendarViewProps) => { - const [selectedCategory, setSelectedCategory] = useState( - null - ); + const [selectedCategory, setSelectedCategory] = useState([]); const [selectedEventDate, setSelectedEventDate] = useState(null); const roleId = Number(getCookiesDecrypt("urie")) || 0; const userLevelId = Number(getCookiesDecrypt("ulie")) || 0; - console.log("roleId", roleId); - console.log("userlevel", userLevelId); - const [apiEvents, setApiEvents] = useState([]); - const [Isloading, setLoading] = useState(false); - const [draggableInitialized, setDraggableInitialized] = - useState(false); + const [calendarEvents, setCalendarEvents] = useState([]); + const [isLoading, setIsLoading] = useState(false); const t = useTranslations("CalendarApp"); - // event canvas state + + // Modal states const [sheetOpen, setSheetOpen] = useState(false); - const [date, setDate] = React.useState(new Date()); + const [date, setDate] = useState(new Date()); const [activeView, setActiveView] = useState("listYear"); - const [yearlyData, setYearlyData] = useState(); - - const TODAY = dayjs().format("yyyy-MM-dd"); - const INITIAL_YEAR = dayjs().format("YYYY"); - const INITIAL_MONTH = dayjs().format("M"); + const [yearlyData, setYearlyData] = useState({}); const [open, setOpen] = useState(false); + const [selectedEventData, setSelectedEventData] = useState(null); - const [selectedYear, setSelectedYear] = useState(new Date()); const [selectedMonth, setSelectedMonth] = useState( dayjs(new Date(Number(INITIAL_YEAR), Number(INITIAL_MONTH) - 1, 1)) ); - const [dragEvents] = useState([ - { title: "New Event Planning", id: "101", tag: "business" }, - { title: "Meeting", id: "102", tag: "meeting" }, - { title: "Generating Reports", id: "103", tag: "holiday" }, - { title: "Create New theme", id: "104", tag: "etc" }, - ]); - - const [calendarEvents, setCalendarEvents] = useState([]); - + // Load events when view or month changes useEffect(() => { - if (activeView == "listYear") { + if (activeView === "listYear") { getYearlyEvents(); } else { getCalendarEvents(); } }, [activeView, selectedMonth]); - const getCalendarEvents = async () => { - console.log("View : ", activeView); - const res = await getAgendaSettingsList( - selectedMonth?.format("YYYY") || INITIAL_YEAR, - selectedMonth.format("M") || INITIAL_MONTH, - "" - ); - console.log("View : API Response:", res); - - if (res?.error) { - error(res?.message); - return; + // Initialize selected categories + useEffect(() => { + if (categories?.length > 0) { + setSelectedCategory(categories.map((c) => c.value)); } + }, [categories]); - const data = res?.data?.data; + const getCalendarEvents = async () => { + setIsLoading(true); + try { + const res = await getAgendaSettingsList( + selectedMonth?.format("YYYY") || INITIAL_YEAR, + selectedMonth.format("M") || INITIAL_MONTH, + "" + ); - if (data) { - console.log("Dataaa : ", data); + if (res?.error) { + error(res?.message || "Failed to fetch events"); + return; + } + + // For monthly view, we need to extract events from the specific month + const monthData = res?.data?.data; + if (monthData) { + const allEvents: CalendarEvent[] = []; // Map API data to the calendarEvents structure - const events = res?.data?.data?.map((event: any) => ({ - id: event.id.toString(), - title: event.title, - createBy: event.createdById, - createdByName: event.createdByName, - start: new Date(event.startDate), - end: new Date(event.endDate), - allDay: true, - extendedProps: { - isPublish: event.isPublish, - calendar: event.agendaType, - description: event.description, + const events = monthData?.map((event: any) => ({ + id: event.id.toString(), + title: event.title, + createBy: event.createdById, createdByName: event.createdByName, - }, - })); + start: new Date(event.startDate), + end: new Date(event.endDate), + allDay: true, + extendedProps: { + isPublish: event.isPublish, + calendar: event.agendaType, + description: event.description, + createdByName: event.createdByName, + }, + })); - console.log("Dataaa event : ", events); - - setCalendarEvents(events); + console.log("Event Data : ", events); + setCalendarEvents(events); + } + } catch (err) { + console.error("Failed to fetch calendar events:", err); + error("Failed to fetch calendar events"); + } finally { + setIsLoading(false); } }; const getYearlyEvents = async () => { - const res = await getAgendaSettingsList( - selectedMonth?.format("YYYY") || INITIAL_YEAR, - "", - "" - ); - if (res?.error) { - error(res.message); - return false; + setIsLoading(true); + try { + const res = await getAgendaSettingsList( + selectedMonth?.format("YYYY") || INITIAL_YEAR, + "", + "" + ); + + if (res?.error) { + error(res?.message || "Failed to fetch yearly events"); + return; + } + + // The API already returns data organized by months + const yearlyData = res?.data?.data; + if (yearlyData) { + setYearlyData(yearlyData); + } + } catch (err) { + console.error("Failed to fetch yearly events:", err); + error("Failed to fetch yearly events"); + } finally { + setIsLoading(false); } - setYearlyData(res?.data?.data); }; - useEffect(() => { - setSelectedCategory(categories?.map((c) => c.value)); - }, [categories]); - - const filteredEvents = calendarEvents?.filter((event) => { + // Filter events based on selected categories + 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()); // agar "1, 2" tetap dianggap benar + .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)); return eventCategories?.some((cat: string) => - selectedCategory?.includes(cat) + selectedCategory.includes(cat) || (hasAllCategories && cat == "0") ); }); - const displayedEvents = - filteredEvents?.length > 1 ? filteredEvents : apiEvents; - - useEffect(() => { - setSelectedCategory(categories?.map((c: any) => c.value)); - }, [categories]); - - useEffect(() => { - console.log("Selected categories:", selectedCategory); - }, [selectedCategory]); - - useEffect(() => { - fetchAgendaEvents(); - }, []); - - const fetchAgendaEvents = async (year?: string, month?: string) => { - setLoading(true); - try { - const selectedMonth = new Date(); // Replace with your logic for selected month - const year = selectedMonth.getFullYear().toString(); - const month = (selectedMonth.getMonth() + 1).toString(); - const typeFilter = ""; // Replace with your type filter logic if needed - - const response = await getAgendaSettingsList(year, month, typeFilter); - - if (response?.data && Array.isArray(response?.data)) { - // Transform API data to match CalendarEvent type - const eventsFromAPI: CalendarEvent[] = response?.data?.map((item) => ({ - id: item.id.toString(), - title: item.title, - createBy: "Mabes Polri - Approver", - createdByName: item.createdByName, - isPublish: item.isPublish, - start: new Date(item.startDate), - end: new Date(item.endDate), - allDay: true, - extendedProps: { - calendar: item.agendaType, - description: item.description, - }, - })); - - setApiEvents(eventsFromAPI); - } else { - console.warn("No events found in API response."); - setApiEvents([]); - } - } catch (error) { - console.error("Failed to fetch agenda settings:", error); - setApiEvents([]); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - console.log("Fetched events from API 1:", apiEvents); - }, [apiEvents]); - - useEffect(() => { - console.log("Filtered events based on category 1:", calendarEvents); - }, [filteredEvents, apiEvents]); - - useEffect(() => { - const draggableEl = document.getElementById("external-events"); - - const initDraggable = () => { - if (draggableEl) { - new Draggable(draggableEl, { - itemSelector: ".fc-event", - eventData: function (eventEl) { - let title = eventEl.getAttribute("title"); - let id = eventEl.getAttribute("data"); - let event = dragEvents.find((e) => e.id === id); - let tag = event ? event.tag : ""; - return { - title: title, - id: id, - extendedProps: { - calendar: tag, - }, - }; - }, - }); - } - }; - - if (dragEvents.length > 0) { - initDraggable(); - } - - return () => { - draggableEl?.removeEventListener("mousedown", initDraggable); - }; - }, [dragEvents]); - - // event click + // Event handlers const handleEventClick = (arg: any) => { - console.log("Event Click ", arg); setSelectedEventDate(null); + setSelectedEventData(arg); setSheetOpen(true); - setApiEvents(arg); wait().then(() => (document.body.style.pointerEvents = "auto")); }; - // handle close modal const handleCloseModal = () => { setSheetOpen(false); - setApiEvents([]); + setSelectedEventData(null); setSelectedEventDate(null); }; + const handleDateClick = (arg: any) => { setSheetOpen(true); - console.log("Date :", arg); setSelectedEventDate(arg); - setApiEvents([]); + setSelectedEventData(null); wait().then(() => (document.body.style.pointerEvents = "auto")); }; const handleCategorySelection = (category: string) => { - if (selectedCategory && selectedCategory.includes(category)) { - setSelectedCategory(selectedCategory.filter((c) => c !== category)); - } else { - setSelectedCategory([...(selectedCategory || []), category]); - } - }; - - const renderEventContent = (eventInfo: any) => { - const { title } = eventInfo.event; - const { createdByName, isPublish } = eventInfo.event.extendedProps; - - return ( - <> -
- {" "} - {isPublish === true ? : } -

{title}

-
- -

- Created By : {createdByName} -

- - ); - }; - - const handleClassName = (arg: EventContentArg) => { - if (arg.event.extendedProps.calendar === "1") { - return "bg-yellow-500 border-none"; - } else if (arg.event.extendedProps.calendar === "2") { - return "bg-blue-400 border-none"; - } else if (arg.event.extendedProps.calendar === "3") { - return "bg-slate-400 border-none"; - } else if (arg.event.extendedProps.calendar === "4") { - return "bg-orange-500 border-none"; - } else if (arg.event.extendedProps.calendar === "5") { - return "bg-green-400 border-none"; - } else { - return "primary"; - } + setSelectedCategory(prev => { + if (prev.includes(category)) { + return prev.filter((c) => c !== category); + } else { + return [...prev, category]; + } + }); }; const handleDateChange = (startDate: string, endDate: string) => { const startDateOfDate = new Date(startDate); - const endDateOfDate = new Date(endDate); - - console.log("Change Date : ", startDateOfDate); - setSelectedMonth(dayjs(startDateOfDate)); }; const handleViewChange = (viewType: string) => { - console.log("Change view : ", viewType); setActiveView(viewType); }; - const months: Array<{ id: keyof YearlyData; label: string }> = [ - { id: "january", label: "Januari" }, - { id: "february", label: "Februari" }, - { id: "march", label: "Maret" }, - { id: "april", label: "April" }, - { id: "may", label: "Mei" }, - { id: "june", label: "Juni" }, - { id: "july", label: "Juli" }, - { id: "august", label: "Agustus" }, - { id: "september", label: "September" }, - { id: "october", label: "Oktober" }, - { id: "november", label: "November" }, - { id: "december", label: "Desember" }, - ]; - - const getEventColor = (type: Event["type"]): string => { - const colors: Record = { - 1: "bg-yellow-500", - 2: "bg-blue-400", - 3: "bg-slate-400", - 4: "bg-orange-500", - 5: "bg-green-400", - }; - return colors[type]; - }; - - const handleClickListItem = (item: any) => { + const handleClickListItem = (item: AgendaSettingsAPIResponse) => { const formattedEvent: CalendarEvent = { id: item.id.toString(), title: item.title, start: new Date(item.startDate), end: new Date(item.endDate), - createBy: "Mabes Polri - Approver", // Sesuaikan dengan data yang sebenarnya jika ada + createBy: item.createdById?.toString() || "", createdByName: item.createdByName, isPublish: item.isPublish, allDay: true, extendedProps: { calendar: item.agendaType, description: item.description, + isPublish: item.isPublish, + createdByName: item.createdByName, }, }; - const finalEvent: any = { - event: formattedEvent, - }; - - console.log("Event click custom : ", finalEvent); + const eventArg = { event: formattedEvent }; setSelectedEventDate(null); + setSelectedEventData(eventArg); setSheetOpen(true); - setApiEvents(finalEvent); wait().then(() => (document.body.style.pointerEvents = "auto")); }; + // Utility functions + 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", + "2": "bg-blue-400", + "3": "bg-slate-400", + "4": "bg-orange-500", + "5": "bg-green-400", + }; + + return colors[firstType] || "bg-gray-400"; + }; + + const getEventColorList = (type: EventType): string[] | null => { + const typeSplit = type.split(","); + const typeList = typeSplit.slice(1); + + if (typeList.length === 0) return null; + + const colors: Record = { + "0": "bg-black", + "1": "bg-yellow-500", + "2": "bg-blue-400", + "3": "bg-slate-400", + "4": "bg-orange-500", + "5": "bg-green-400", + }; + + return typeList.map((item) => colors[item as EventType] || "bg-gray-200"); + }; + + const renderEventContent = (eventInfo: any) => { + const { title } = eventInfo.event; + const { createdByName, isPublish, calendar } = eventInfo.event.extendedProps; + const bgColor = getEventColor(calendar); + const colorList = getEventColorList(calendar); + + return ( +
+
+
+ {isPublish === true ? : } +

{title}

+
+

+ Created By: {createdByName} +

+
+ {colorList && colorList.length > 0 && ( +
+ {colorList.map((color: string, index: number) => ( +
+ ))} +
+ )} +
+ ); + }; + + const handleClassName = (arg: EventContentArg) => { + const eventColor = getEventColor(arg.event.extendedProps.calendar); + return eventColor || "primary"; + }; + + // Components const ListItem: React.FC = ({ item, text, createdBy, isPublish, bgColor, + colorList, }) => ( -
handleClickListItem(item)} > -
- {isPublish ? : } -

{text}

+
+
+ {isPublish ? : } +

{text}

+
+

Created By: {createdBy}

-

Created By: {createdBy}

+ {colorList && colorList.length > 0 && ( +
+ {colorList.map((color: string, index: number) => ( +
+ ))} +
+ )}
); - const MonthCard: React.FC = (props: any) => { - const { monthId, label } = props; - const events: any = yearlyData?.[monthId]; - const displayedEvents = events?.slice(0, 3); - const hasMoreEvents = events?.length > 3; + const MonthCard: React.FC = ({ monthId, label }) => { + const events = yearlyData[monthId] || []; + const displayedEvents = events.slice(0, 3); + const hasMoreEvents = events.length > 3; + return (

{label}

-
- {events?.length === 0 ? ( + {events.length === 0 ? (

{t("no-data-yet")}

) : ( <> - {displayedEvents?.map((event: any, index: number) => ( + {displayedEvents.map((event, index) => ( ))} - {hasMoreEvents && ( @@ -524,14 +454,15 @@ const CalendarView = ({ categories }: CalendarViewProps) => {
- {events.map((event: any, index: number) => ( + {events.map((event, index) => ( ))}
@@ -547,9 +478,24 @@ const CalendarView = ({ categories }: CalendarViewProps) => { ); }; - const getModalContent = (type: "terkirim" | "diterima") => ( -
- {Isloading ? ( + const months: Array<{ id: keyof YearlyData; label: string }> = [ + { id: "january", label: "Januari" }, + { id: "february", label: "Februari" }, + { id: "march", label: "Maret" }, + { id: "april", label: "April" }, + { id: "may", label: "Mei" }, + { id: "june", label: "Juni" }, + { id: "july", label: "Juli" }, + { id: "august", label: "Agustus" }, + { id: "september", label: "September" }, + { id: "october", label: "Oktober" }, + { id: "november", label: "November" }, + { id: "december", label: "Desember" }, + ]; + + const getModalContent = () => ( +
+ {isLoading ? (

Loading...

) : ( @@ -563,14 +509,12 @@ const CalendarView = ({ categories }: CalendarViewProps) => { - - - - - - + + + + + +
{"1"}{"MIA - 001"}{"23/01/2025 13:00"}{"Daily Issue 25 Januari 2025 "} - {type === "terkirim" ? "Completed" : "Completed"} -
1MIA - 00123/01/2025 13:00Daily Issue 25 Januari 2025Completed
@@ -580,11 +524,11 @@ const CalendarView = ({ categories }: CalendarViewProps) => { return ( <> -
- +
+ - - {roleId == 3 || roleId == 11 || roleId == 2 || roleId == 12 ? ( + + {[3, 11, 2, 12].includes(roleId) && ( - ) : ( - "" )} -
+ + {roleId === 3 && userLevelId === 216 && ( - {roleId === 3 && userLevelId === 216 ? ( - - ) : null} + {t("monitoring-results")} - {getModalContent("terkirim")} + {getModalContent()} -
+ )}
{ - handleDateClick(s); + onSelect={(selectedDate) => { + if (selectedDate) { + setDate(selectedDate); + handleDateClick(selectedDate); + } }} className="rounded-md border w-full p-0 border-none" />
- {/*
-

- {t("shortDesc")} -

- {dragEvents.map((event) => ( - - ))} -
*/} -
+
{t("filter")}
    -
  • +
  • { - if (selectedCategory?.length === categories?.length) { + checked={selectedCategory.length === categories.length} + onCheckedChange={() => { + if (selectedCategory.length === categories.length) { setSelectedCategory([]); } else { - setSelectedCategory(categories?.map((c) => c.value)); + setSelectedCategory(categories.map((c) => c.value)); } }} />
  • - {categories?.map((category) => ( -
  • + {categories.map((category) => ( +
  • handleCategorySelection(category.value)} + checked={selectedCategory.includes(category.value)} + onCheckedChange={() => handleCategorySelection(category.value)} />
  • @@ -666,15 +602,10 @@ const CalendarView = ({ categories }: CalendarViewProps) => { - + { buttonText: "Year", }, }} - events={displayedEvents} + events={filteredEvents} editable={true} rerenderDelay={10} eventDurationEditable={false} @@ -702,70 +633,40 @@ const CalendarView = ({ categories }: CalendarViewProps) => { eventContent={renderEventContent} viewDidMount={(info) => handleViewChange(info.view.type)} datesSet={(info: any) => { - console.log(info); 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" && (
    -
    - {months.slice(0, 3).map((month) => ( - - ))} -
    - -
    - {months.slice(3, 6).map((month) => ( - - ))} -
    - -
    - {months.slice(6, 9).map((month) => ( - - ))} -
    - -
    - {months.slice(9, 12).map((month) => ( - - ))} -
    + {[0, 3, 6, 9].map((startIndex) => ( +
    + {months.slice(startIndex, startIndex + 3).map((month) => ( + + ))} +
    + ))}
    )}
+ ); }; -export default CalendarView; +export default CalendarView; \ No newline at end of file diff --git a/app/[locale]/(protected)/contributor/agenda-setting/page.tsx b/app/[locale]/(protected)/contributor/agenda-setting/page.tsx index 010f3ead..9bbbcd75 100644 --- a/app/[locale]/(protected)/contributor/agenda-setting/page.tsx +++ b/app/[locale]/(protected)/contributor/agenda-setting/page.tsx @@ -21,7 +21,7 @@ const CalenderPage = () => { const categories = await getCategories(); let valueShowed: string[] = []; if (userLevelNumber == 1) { - valueShowed = ["1", "2", "3", "4", "5"]; + valueShowed = ["0", "1", "2", "3", "4", "5"]; } else if (userLevelNumber == 2 && userLevelId != 761) { valueShowed = ["2", "3"]; } else if ( diff --git a/components/landing-page/area-coverage-and-work-units.tsx b/components/landing-page/area-coverage-and-work-units.tsx index 35d02d95..788d9e41 100644 --- a/components/landing-page/area-coverage-and-work-units.tsx +++ b/components/landing-page/area-coverage-and-work-units.tsx @@ -35,7 +35,7 @@ const AreaCoverageWorkUnits = () => {

Polda Jajaran

- +

Polda Jajaran

@@ -63,7 +63,7 @@ const AreaCoverageWorkUnits = () => {

Satuan Kerja Polri

- +

Satuan Kerja Polri

diff --git a/components/landing-page/coverage.tsx b/components/landing-page/coverage.tsx index 9f3f9165..3fc75c5c 100644 --- a/components/landing-page/coverage.tsx +++ b/components/landing-page/coverage.tsx @@ -54,22 +54,22 @@ const regions = [ { name: "Polda Kalimantan Barat", slug: "kalimantan-barat", - logo: "/logo/polda/polda-kalbar.png", + logo: "/logo/polda/polda-kalimantan-barat.png", }, { name: "Polda Kalimantan Selatan", slug: "kalimantan-selatan", - logo: "/logo/polda/polda-kalsel.png", + logo: "/logo/polda/polda-kalimantan-selatan.png", }, { name: "Polda Kalimantan Tengah", slug: "kalimantan-tengah", - logo: "/logo/polda/polda-kalteng.png", + logo: "/logo/polda/polda-kalimantan-tengah.png", }, { name: "Polda Kalimantan Timur", slug: "kalimantan-timur", - logo: "/logo/polda/polda-kaltim.png", + logo: "/logo/polda/polda-kalimantan-timur.png", }, { name: "Polda Kalimantan Utara", @@ -117,6 +117,16 @@ const regions = [ slug: "papua-barat", logo: "/logo/polda/polda-papua-barat.png", }, + { + name: "Polda Papua Barat Daya", + slug: "papua-barat-daya", + logo: "/logo/polda/polda-papua-barat-daya.png", + }, + { + name: "Polda Papua Tengah", + slug: "papua-tengah", + logo: "/logo/polda/polda-papua-tengah.png", + }, { name: "Polda Riau", slug: "riau", logo: "/logo/polda/polda-riau.png" }, { name: "Polda Sulawesi Barat", @@ -173,14 +183,18 @@ const regions = [ const Coverage: React.FC = () => { const [seeAllValue, setSeeAllValue] = useState(false); const [searchTerm, setSearchTerm] = useState(""); - const [filteredList, setFilteredList] = useState(regions); + const [filteredList, setFilteredList] = useState( + regions + ); const pathname = usePathname(); const t = useTranslations("LandingPage"); const handleSearch = () => { const value = searchTerm.toLowerCase(); - const filtered = regions.filter((polda) => polda.name.toLowerCase().includes(value)); + const filtered = regions.filter((polda) => + polda.name.toLowerCase().includes(value) + ); setFilteredList(filtered); }; @@ -198,16 +212,32 @@ const Coverage: React.FC = () => { `; - const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str)); + const toBase64 = (str: string) => + typeof window === "undefined" + ? Buffer.from(str).toString("base64") + : window.btoa(str); return (
{filteredList?.map((region: any) => ( - +
- {region.name} + {region.name}

{region.name}

diff --git a/components/landing-page/division.tsx b/components/landing-page/division.tsx index 6b4dab18..e6713943 100644 --- a/components/landing-page/division.tsx +++ b/components/landing-page/division.tsx @@ -9,48 +9,172 @@ import Image from "next/image"; const regions = [ { name: "ITWASUM POLRI", slug: "itwasum", logo: "/logo/satker/ITWASUM.png" }, - { name: "BAINTELKAM POLRI", slug: "baintelkam", logo: "/logo/satker/BAINTELKAM.png" }, - { name: "BAHARKAM POLRI", slug: "baharkam", logo: "/logo/satker/BAHARKAM.png" }, - { name: "BARESKRIM POLRI", slug: "bareskrim", logo: "/logo/satker/BARESKRIM.png" }, - { name: "LEMDIKLAT POLRI", slug: "lemdiklat", logo: "/logo/satker/LEMDIKLAT.png" }, + { + name: "BAINTELKAM POLRI", + slug: "baintelkam", + logo: "/logo/satker/BAINTELKAM.png", + }, + { + name: "BAHARKAM POLRI", + slug: "baharkam", + logo: "/logo/satker/BAHARKAM.png", + }, + { + name: "BARESKRIM POLRI", + slug: "bareskrim", + logo: "/logo/satker/BARESKRIM.png", + }, + { + name: "LEMDIKLAT POLRI", + slug: "lemdiklat", + logo: "/logo/satker/LEMDIKLAT.png", + }, { name: "KORBRIMOB POLRI", slug: "brimob", logo: "/logo/satker/BRIMOB.png" }, { name: "STAMAOPS POLRI", slug: "sops", logo: "/logo/satker/SOPS.png" }, { name: "STAMARENA POLRI", slug: "srena", logo: "/logo/satker/SRENA.png" }, { name: "SSDM POLRI", slug: "ssdm", logo: "/logo/satker/SSDM.png" }, { name: "SLOG POLRI", slug: "slog", logo: "/logo/satker/SLOG.png" }, - { name: "SAHLI KAPOLRI", slug: "stafahli", logo: "/logo/satker/STAFAHLI.png" }, - { name: "DIVPROPRAM POLRI", slug: "divpropram", logo: "/logo/satker/DIVPROPAM.png" }, - { name: "DIVKUM", slug: "divkum", logo: "/assets/satker/divkum.png" }, - { name: "DIVHUBINTER POLRI", slug: "divhubinter", logo: "/logo/satker/DIVHUBINTER.png" }, + { + name: "SAHLI KAPOLRI", + slug: "stafahli", + logo: "/logo/satker/STAFAHLI.png", + }, + { + name: "DIVPROPRAM POLRI", + slug: "divpropram", + logo: "/logo/satker/DIVPROPAM.png", + }, + { name: "DIVKUM", slug: "divkum", logo: "/logo/satker/DIVKUM.png" }, + { + name: "DIVHUBINTER POLRI", + slug: "divhubinter", + logo: "/logo/satker/DIVHUBINTER.png", + }, { name: "DIVTIK POLRI", slug: "div-tik", logo: "/logo/satker/DIV-TIK.png" }, - { name: "KORLANTAS POLRI", slug: "korlantas", logo: "/logo/satker/KORLANTAS.png" }, - { name: "DENSUS 88 POLRI", slug: "densus-88", logo: "/logo/satker/DENSUS-88.png" }, - { name: "PUSDOKKES POLRI", slug: "pusdokkes", logo: "/logo/satker/PUSDOKKES.png" }, - { name: "PUSLITBANG POLRI", slug: "puslitbang", logo: "/logo/satker/PUSLITBANG.png" }, + { + name: "KORLANTAS POLRI", + slug: "korlantas", + logo: "/logo/satker/KORLANTAS.png", + }, + { + name: "DENSUS 88 POLRI", + slug: "densus-88", + logo: "/logo/satker/DENSUS-88.png", + }, + { + name: "PUSDOKKES POLRI", + slug: "pusdokkes", + logo: "/logo/satker/PUSDOKKES.png", + }, + { + name: "PUSLITBANG POLRI", + slug: "puslitbang", + logo: "/logo/satker/PUSLITBANG.png", + }, { name: "PUSKEU POLRI", slug: "puskeu", logo: "/logo/satker/PUSKEU.png" }, - { name: "PUSJARAH POLRI", slug: "pusjarah", logo: "/logo/satker/PUSJARAH.png" }, + { + name: "PUSJARAH POLRI", + slug: "pusjarah", + logo: "/logo/satker/PUSJARAH.png", + }, { name: "SETUM POLRI", slug: "setum", logo: "/logo/satker/SETUM.png" }, { name: "YANMA POLRI", slug: "yanma", logo: "/logo/satker/YANMA.png" }, { name: "SPRIPIM POLRI", slug: "spripim", logo: "/logo/satker/SPRIPIM.png" }, - { name: "KORPOLAIRUD BAHARKAM POLRI", slug: "polairud", logo: "/logo/satker/POLAIRUD.png" }, - { name: "KORSABHARA BAHARKAM POLRI", slug: "korps-sabhara-baharkam", logo: "/logo/satker/KORPS-SABHARA-BAHARKAM.png" }, - { name: "KORBINMAS BAHARKAM POLRI", slug: "binmas", logo: "/logo/satker/BINMAS.png" }, - { name: "DITTIPIDUM BARESKRIM POLRI", slug: "dittipidum", logo: "/logo/satker/DITTIPIDUM.png" }, - { name: "DITTIPIDEKSUS BARESKRIM POLRI", slug: "dittipideksus", logo: "/logo/satker/DITTIPIDEKSUS.png" }, - { name: "DITTIPIDKOR BARESKRIM POLRI", slug: "dittipidkor", logo: "/logo/satker/DITTIPIDKOR.png" }, - { name: "DITTIPIDNARKOBA BARESKRIM POLRI", slug: "dittipidnarkoba", logo: "/logo/satker/DITTIPIDNARKOBA.png" }, - { name: "DITTIPIDTER BARESKRIM POLRI", slug: "dittipidter", logo: "/logo/satker/DITTIPIDTER.png" }, - { name: "DITTIPIDSIBER BARESKRIM POLRI", slug: "dittipidsiber", logo: "/logo/satker/DITTIPIDSIBER.png" }, - { name: "DIT PPA-PPO BARESKRIM POLRI", slug: "dit-ppa-ppo", logo: "/logo/satker/DITPPAPPO.png" }, - { name: "PUSLABFOR BARESKRIM POLRI", slug: "puslabfor", logo: "/assets/satker/puslabfor.png" }, - { name: "PUSIKNAS BARESKRIM POLRI", slug: "pusiknas", logo: "/logo/satker/PUSKINAS.png" }, - { name: "STIK LEMDIKLAT POLRI", slug: "stik-ptik", logo: "/logo/satker/STIK-PTIK.png" }, - { name: "AKPOL LEMDIKLAT POLRI", slug: "akpol", logo: "/logo/satker/AKPOL.png" }, - { name: "SESPIM LEMDIKLAT POLRI", slug: "sespim-polri", logo: "/logo/satker/SESPIM-POLRI.png" }, - { name: "SETUKPA LEMDIKLAT POLRI", slug: "setupa-polri", logo: "/logo/satker/SETUPA-POLRI.png" }, - { name: "SEPOLWAN LEMDIKLAT POLRI", slug: "sepolwan-polri", logo: "/logo/satker/SEPOLWAN-POLRI.png" }, - { name: "SEBASA LEMDIKLAT POLRI", slug: "sebasa-polri", logo: "/logo/satker/SEBASA-POLRI.png" }, - { name: "RUMKIT BHAYANGKARA TK I", slug: "rumkit-bhayangkara", logo: "/logo/satker/RUMKIT-BHAYANGKARA.png" }, + { + name: "KORPOLAIRUD BAHARKAM POLRI", + slug: "polairud", + logo: "/logo/satker/POLAIRUD.png", + }, + { + name: "KORSABHARA BAHARKAM POLRI", + slug: "korps-sabhara-baharkam", + logo: "/logo/satker/KORPS-SABHARA-BAHARKAM.png", + }, + { + name: "KORBINMAS BAHARKAM POLRI", + slug: "binmas", + logo: "/logo/satker/BINMAS.png", + }, + { + name: "DITTIPIDUM BARESKRIM POLRI", + slug: "dittipidum", + logo: "/logo/satker/DITTIPIDUM.png", + }, + { + name: "DITTIPIDEKSUS BARESKRIM POLRI", + slug: "dittipideksus", + logo: "/logo/satker/DITTIPIDEKSUS.png", + }, + { + name: "DITTIPIDKOR BARESKRIM POLRI", + slug: "dittipidkor", + logo: "/logo/satker/DITTIPIDKOR.png", + }, + { + name: "DITTIPIDNARKOBA BARESKRIM POLRI", + slug: "dittipidnarkoba", + logo: "/logo/satker/DITTIPIDNARKOBA.png", + }, + { + name: "DITTIPIDTER BARESKRIM POLRI", + slug: "dittipidter", + logo: "/logo/satker/DITTIPIDTER.png", + }, + { + name: "DITTIPIDSIBER BARESKRIM POLRI", + slug: "dittipidsiber", + logo: "/logo/satker/DITTIPIDSIBER.png", + }, + { + name: "DIT PPA-PPO BARESKRIM POLRI", + slug: "dit-ppa-ppo", + logo: "/logo/satker/DITPPAPPO.png", + }, + { + name: "PUSLABFOR BARESKRIM POLRI", + slug: "puslabfor", + logo: "/assets/satker/puslabfor.png", + }, + { + name: "PUSIKNAS BARESKRIM POLRI", + slug: "pusiknas", + logo: "/logo/satker/PUSKINAS.png", + }, + { + name: "STIK LEMDIKLAT POLRI", + slug: "stik-ptik", + logo: "/logo/satker/STIK-PTIK.png", + }, + { + name: "AKPOL LEMDIKLAT POLRI", + slug: "akpol", + logo: "/logo/satker/AKPOL.png", + }, + { + name: "SESPIM LEMDIKLAT POLRI", + slug: "sespim-polri", + logo: "/logo/satker/SESPIM-POLRI.png", + }, + { + name: "SETUKPA LEMDIKLAT POLRI", + slug: "setupa-polri", + logo: "/logo/satker/SETUPA-POLRI.png", + }, + { + name: "SEPOLWAN LEMDIKLAT POLRI", + slug: "sepolwan-polri", + logo: "/logo/satker/SEPOLWAN-POLRI.png", + }, + { + name: "SEBASA LEMDIKLAT POLRI", + slug: "sebasa-polri", + logo: "/logo/satker/SEBASA-POLRI.png", + }, + { + name: "RUMKIT BHAYANGKARA TK I", + slug: "rumkit-bhayangkara", + logo: "/logo/satker/RUMKIT-BHAYANGKARA.png", + }, { name: "POLAIR", slug: "polair", logo: "/logo/satker/POLAIR.png" }, { name: "POLUDARA", slug: "poludara", logo: "/logo/satker/POLUDARA.png" }, { name: "PUSINAFIS", slug: "pusinafis", logo: "/logo/satker/PUSINAFIS.png" }, @@ -62,14 +186,18 @@ const regions = [ const Division = () => { const [searchTerm, setSearchTerm] = useState(""); const [seeAllValue, setSeeAllValue] = useState(false); - const [filteredList, setFilteredList] = useState(regions); + const [filteredList, setFilteredList] = useState( + regions + ); const pathname = usePathname(); const t = useTranslations("LandingPage"); const handleSearch = () => { const value = searchTerm.toLowerCase(); - const filtered = regions.filter((satker) => satker.name.toLowerCase().includes(value)); + const filtered = regions.filter((satker) => + satker.name.toLowerCase().includes(value) + ); setFilteredList(filtered); }; @@ -87,7 +215,10 @@ const Division = () => { `; - const toBase64 = (str: string) => (typeof window === "undefined" ? Buffer.from(str).toString("base64") : window.btoa(str)); + const toBase64 = (str: string) => + typeof window === "undefined" + ? Buffer.from(str).toString("base64") + : window.btoa(str); return (
@@ -118,9 +249,21 @@ const Division = () => { {/* Grid Wilayah */}
{filteredList?.map((region: any) => ( - +
- {region.name} + {region.name}

{region.name}

diff --git a/components/landing-page/footer.tsx b/components/landing-page/footer.tsx index 17d6c1f0..ebfaa49b 100644 --- a/components/landing-page/footer.tsx +++ b/components/landing-page/footer.tsx @@ -68,6 +68,7 @@ const Footer = () => {
Privacy diff --git a/components/landing-page/survey-box.tsx b/components/landing-page/survey-box.tsx index bde4e8f8..c6693c9d 100644 --- a/components/landing-page/survey-box.tsx +++ b/components/landing-page/survey-box.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "../ui/dialog"; import FormSurvey from "./survey"; import { Controller, useForm } from "react-hook-form"; @@ -83,6 +83,7 @@ const UserSurveyBox = () => { const response = await createSurveyData(data); console.log("API Response:", response); setShowSurvey(false); + setOpenPolda(false); } catch (error) { console.error("Error submitting survey:", error); } finally { @@ -114,7 +115,7 @@ const UserSurveyBox = () => { SURVEY SEKARANG - + SURVEI KEPUASAN PENGGUNA MEDIAHUB POLRI Kami menghargai pendapat Anda! Survei ini bertujuan untuk meningkatkan kualitas layanan MediaHub Polri. @@ -148,7 +149,7 @@ const UserSurveyBox = () => {
-