From 6dcdeacf0817034cab4a21983a9eec76259f9846 Mon Sep 17 00:00:00 2001 From: hanif salafi Date: Sun, 12 Jan 2025 20:54:18 +0700 Subject: [PATCH] feat: update agenda settings --- .../agenda-setting/calender-view.tsx | 264 ++++++++++++++++-- .../agenda-setting/event-modal.tsx | 3 + app/[locale]/globals.css | 7 +- 3 files changed, 256 insertions(+), 18 deletions(-) diff --git a/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx b/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx index 00ba5260..e3312a26 100644 --- a/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx +++ b/app/[locale]/(protected)/contributor/agenda-setting/calender-view.tsx @@ -9,7 +9,7 @@ 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 } from "@/components/ui/card"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Plus } from "lucide-react"; import { Checkbox } from "@/components/ui/checkbox"; import { EventContentArg } from "@fullcalendar/core"; @@ -19,6 +19,12 @@ import { getAgendaSettingsList } from "@/service/agenda-setting/agenda-setting"; import dayjs from "dayjs"; import { getCookiesDecrypt } from "@/lib/utils"; import { CalendarCategory } from "./data"; +import { error } from "@/config/swal"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; const wait = () => new Promise((resolve) => setTimeout(resolve, 1000)); interface CalendarViewProps { @@ -26,6 +32,21 @@ interface CalendarViewProps { categories: CalendarCategory[]; } +export type CalendarEvent = { + id: string; + title: string; + start: Date; + end: Date; + createBy: string; + createdByName: string; + allDay: boolean; + extendedProps: { + calendar: string; + description: string; + }; +}; + + const INITIAL_YEAR = dayjs().format("YYYY"); const INITIAL_MONTH = dayjs().format("M"); @@ -42,6 +63,33 @@ export interface AgendaSettingsAPIResponse { 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[]; +} + +interface MonthCardProps { + monthId: keyof YearlyData; + label: string; +} + +interface ListItemProps { + item: any; + text: string + createdBy: string; + bgColor: string; +} interface APIResponse { error: boolean; @@ -63,6 +111,8 @@ const CalendarView = ({ categories }: CalendarViewProps) => { // event canvas state const [sheetOpen, setSheetOpen] = useState(false); const [date, setDate] = React.useState(new Date()); + const [activeView, setActiveView] = useState("dayGridMonth"); + const [yearlyData, setYearlyData] = useState(); const [dragEvents] = useState([ { title: "New Event Planning", id: "101", tag: "business" }, @@ -75,6 +125,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { useEffect(() => { getCalendarEvents(); + getYearlyEvents(); }, []); const getCalendarEvents = async () => { @@ -82,6 +133,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { console.log("API Response:", res); if (res?.error) { + error(res?.message); return; } @@ -105,6 +157,15 @@ const CalendarView = ({ categories }: CalendarViewProps) => { console.log("event", events); }; + const getYearlyEvents = async () => { + const res = await getAgendaSettingsList(INITIAL_YEAR, '', ''); + if (res?.error) { + error(res.message); + return false; + } + setYearlyData(res?.data?.data); + } + useEffect(() => { setSelectedCategory(categories?.map((c) => c.value)); }, [categories]); @@ -212,11 +273,13 @@ const CalendarView = ({ categories }: CalendarViewProps) => { // event click const handleEventClick = (arg: any) => { + console.log("Event Click ", arg); setSelectedEventDate(null); setSheetOpen(true); setApiEvents(arg); wait().then(() => (document.body.style.pointerEvents = "auto")); }; + // handle close modal const handleCloseModal = () => { setSheetOpen(false); @@ -225,6 +288,7 @@ const CalendarView = ({ categories }: CalendarViewProps) => { }; const handleDateClick = (arg: any) => { setSheetOpen(true); + console.log("Date :", arg); setSelectedEventDate(arg); setApiEvents([]); wait().then(() => (document.body.style.pointerEvents = "auto")); @@ -266,6 +330,142 @@ const CalendarView = ({ categories }: CalendarViewProps) => { } }; + const handleDateChange = (startDate: string, endDate: string) => { + console.log(startDate + " - " + endDate); + }; + + const handleViewChange = (viewType: string) => { + console.log(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 = { + mabes: 'bg-yellow-500', + polda: 'bg-blue-400', + polres: 'bg-slate-400', + international: 'bg-green-400' + }; + return colors[type]; + }; + + const handleClickListItem = (item: any) => { + 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 + createdByName: item.createdByName, + allDay: true, + extendedProps: { + calendar: item.agendaType, + description: item.description + } + }; + const finalEvent: any = { + event: formattedEvent + } + + console.log("Event click custom : ", finalEvent); + + setSelectedEventDate(null); + setSheetOpen(true); + setApiEvents(finalEvent); + wait().then(() => (document.body.style.pointerEvents = "auto")); + } + + const ListItem: React.FC = ({ item, text, createdBy, bgColor }) => ( +
handleClickListItem(item)}> +

{text}

+

+ Create By: {createdBy} +

+
+ ); + + 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; + return ( +
+
+

{label}

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

Belum ada data

+
+ ) : ( + <> + {displayedEvents?.map((event: any, index: number) => ( + + ))} + + {hasMoreEvents && ( + + + + + + + + {label} + + +
+ {events.map((event: any, index: number) => ( + + ))} +
+
+
+
+
+ )} + + )} +
+
+ ); + }; + return ( <>
@@ -344,7 +544,13 @@ const CalendarView = ({ categories }: CalendarViewProps) => { headerToolbar={{ left: "prev,next today", center: "title", - right: "dayGridMonth,listWeek,", + right: "listYear,dayGridMonth,listMonth", + }} + views={{ + listYear: { + type: "dayGridMonth", + buttonText: "Year", + }, }} events={displayedEvents} editable={true} @@ -358,9 +564,47 @@ const CalendarView = ({ categories }: CalendarViewProps) => { eventClassNames={handleClassName} dateClick={handleDateClick} eventClick={handleEventClick} - initialView="dayGridMonth" + initialView="listYear" 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" : ""} /> + + {activeView === "listYear" && ( +
+
+ {months.slice(0, 3).map(month => ( + + ))} +
+ + {/* Second Row */} +
+ {months.slice(3, 6).map(month => ( + + ))} +
+ + {/* Third Row */} +
+ {months.slice(6, 9).map(month => ( + + ))} +
+ + {/* Fourth Row */} +
+ {months.slice(9, 12).map(month => ( + + ))} +
+
+ )}
@@ -376,17 +620,3 @@ const CalendarView = ({ categories }: CalendarViewProps) => { }; export default CalendarView; - -export type CalendarEvent = { - id: string; - title: string; - start: Date; - end: Date; - createBy: string; - createdByName: string; - allDay: boolean; - extendedProps: { - calendar: string; - description: string; - }; -}; diff --git a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx index 00e002c8..3b7a5036 100644 --- a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx +++ b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx @@ -147,6 +147,8 @@ const EventModal = ({ } fetchPoldaPolres(); console.log("Event", event); + + console.log("Event click modal : ", event); }, [agendaType]); const handleCheckboxChange = (levelId: number) => { @@ -299,6 +301,7 @@ const EventModal = ({ const file = new File([blob], "voiceNote.webm", { type: "audio/webm" }); setAudioFile(file); }; + const handleDeleteAudio = () => { // Remove the audio file by setting state to null setAudioFile(null); diff --git a/app/[locale]/globals.css b/app/[locale]/globals.css index a23bf3b4..18ad9f8a 100644 --- a/app/[locale]/globals.css +++ b/app/[locale]/globals.css @@ -577,4 +577,9 @@ html[dir="rtl"] .react-select .select__loading-indicator { .ck-editor__editable_inline { min-height: 200px; -} \ No newline at end of file +} + +/* Hide FullCalendar grid elements */ +.fc-view-harness:has(.hide-calendar-grid) { + display: none; +}