From ead5912044916a6860f694e8038e92f254495570 Mon Sep 17 00:00:00 2001 From: Anang Yusman Date: Wed, 27 Nov 2024 11:14:10 +0700 Subject: [PATCH] feat:change sidebar --- .../agenda-setting/calender-view.tsx | 243 +++++++++++++++ .../(protected)/agenda-setting/data.ts | 155 ++++++++++ .../agenda-setting/dragging-events.tsx | 23 ++ .../agenda-setting/event-modal.tsx | 277 +++++++++++++++++ .../(protected)/agenda-setting/layout.tsx | 9 + .../(protected)/agenda-setting/page.tsx | 21 ++ .../(protected)/agenda-setting/utils.ts | 11 + app/[locale]/(protected)/blog/layout.tsx | 9 + app/[locale]/(protected)/blog/page.tsx | 5 + .../(protected)/communication/layout.tsx | 9 + .../(protected)/communication/page.tsx | 5 + .../content/audio-visual/layout.tsx | 9 + .../(protected)/content/audio-visual/page.tsx | 5 + .../content/audio/calender-view.tsx | 243 +++++++++++++++ .../(protected)/content/audio/data.ts | 155 ++++++++++ .../content/audio/dragging-events.tsx | 23 ++ .../(protected)/content/audio/event-modal.tsx | 277 +++++++++++++++++ .../(protected)/content/audio/layout.tsx | 9 + .../(protected)/content/audio/page.tsx | 21 ++ .../(protected)/content/audio/utils.ts | 11 + .../(protected)/content/image/layout.tsx | 9 + .../(protected)/content/image/page.tsx | 5 + .../(protected)/content/image/utils.ts | 11 + .../(protected)/content/nulis-ai/layout.tsx | 9 + .../(protected)/content/nulis-ai/page.tsx | 5 + .../(protected)/content/spit/layout.tsx | 9 + .../(protected)/content/spit/page.tsx | 5 + .../(protected)/content/teks/layout.tsx | 9 + .../(protected)/content/teks/page.tsx | 5 + app/[locale]/(protected)/contest/layout.tsx | 9 + app/[locale]/(protected)/contest/page.tsx | 5 + .../(protected)/curated-content/layout.tsx | 9 + .../(protected)/curated-content/page.tsx | 5 + .../(protected)/dashboard/analytics/page.tsx | 292 +++++++++--------- .../(protected)/planning/mediahub/layout.tsx | 9 + .../(protected)/planning/mediahub/page.tsx | 5 + .../planning/medsos-mediahub/layout.tsx | 9 + .../planning/medsos-mediahub/page.tsx | 5 + .../(protected)/schedule/event/layout.tsx | 9 + .../(protected)/schedule/event/page.tsx | 5 + .../schedule/press-conference/layout.tsx | 9 + .../schedule/press-conference/page.tsx | 5 + .../schedule/press-release/layout.tsx | 9 + .../schedule/press-release/page.tsx | 5 + app/[locale]/(protected)/task/layout.tsx | 9 + app/[locale]/(protected)/task/page.tsx | 5 + lib/menus.ts | 225 +++++++++++--- 47 files changed, 2033 insertions(+), 183 deletions(-) create mode 100644 app/[locale]/(protected)/agenda-setting/calender-view.tsx create mode 100644 app/[locale]/(protected)/agenda-setting/data.ts create mode 100644 app/[locale]/(protected)/agenda-setting/dragging-events.tsx create mode 100644 app/[locale]/(protected)/agenda-setting/event-modal.tsx create mode 100644 app/[locale]/(protected)/agenda-setting/layout.tsx create mode 100644 app/[locale]/(protected)/agenda-setting/page.tsx create mode 100644 app/[locale]/(protected)/agenda-setting/utils.ts create mode 100644 app/[locale]/(protected)/blog/layout.tsx create mode 100644 app/[locale]/(protected)/blog/page.tsx create mode 100644 app/[locale]/(protected)/communication/layout.tsx create mode 100644 app/[locale]/(protected)/communication/page.tsx create mode 100644 app/[locale]/(protected)/content/audio-visual/layout.tsx create mode 100644 app/[locale]/(protected)/content/audio-visual/page.tsx create mode 100644 app/[locale]/(protected)/content/audio/calender-view.tsx create mode 100644 app/[locale]/(protected)/content/audio/data.ts create mode 100644 app/[locale]/(protected)/content/audio/dragging-events.tsx create mode 100644 app/[locale]/(protected)/content/audio/event-modal.tsx create mode 100644 app/[locale]/(protected)/content/audio/layout.tsx create mode 100644 app/[locale]/(protected)/content/audio/page.tsx create mode 100644 app/[locale]/(protected)/content/audio/utils.ts create mode 100644 app/[locale]/(protected)/content/image/layout.tsx create mode 100644 app/[locale]/(protected)/content/image/page.tsx create mode 100644 app/[locale]/(protected)/content/image/utils.ts create mode 100644 app/[locale]/(protected)/content/nulis-ai/layout.tsx create mode 100644 app/[locale]/(protected)/content/nulis-ai/page.tsx create mode 100644 app/[locale]/(protected)/content/spit/layout.tsx create mode 100644 app/[locale]/(protected)/content/spit/page.tsx create mode 100644 app/[locale]/(protected)/content/teks/layout.tsx create mode 100644 app/[locale]/(protected)/content/teks/page.tsx create mode 100644 app/[locale]/(protected)/contest/layout.tsx create mode 100644 app/[locale]/(protected)/contest/page.tsx create mode 100644 app/[locale]/(protected)/curated-content/layout.tsx create mode 100644 app/[locale]/(protected)/curated-content/page.tsx create mode 100644 app/[locale]/(protected)/planning/mediahub/layout.tsx create mode 100644 app/[locale]/(protected)/planning/mediahub/page.tsx create mode 100644 app/[locale]/(protected)/planning/medsos-mediahub/layout.tsx create mode 100644 app/[locale]/(protected)/planning/medsos-mediahub/page.tsx create mode 100644 app/[locale]/(protected)/schedule/event/layout.tsx create mode 100644 app/[locale]/(protected)/schedule/event/page.tsx create mode 100644 app/[locale]/(protected)/schedule/press-conference/layout.tsx create mode 100644 app/[locale]/(protected)/schedule/press-conference/page.tsx create mode 100644 app/[locale]/(protected)/schedule/press-release/layout.tsx create mode 100644 app/[locale]/(protected)/schedule/press-release/page.tsx create mode 100644 app/[locale]/(protected)/task/layout.tsx create mode 100644 app/[locale]/(protected)/task/page.tsx diff --git a/app/[locale]/(protected)/agenda-setting/calender-view.tsx b/app/[locale]/(protected)/agenda-setting/calender-view.tsx new file mode 100644 index 00000000..2f707e0f --- /dev/null +++ b/app/[locale]/(protected)/agenda-setting/calender-view.tsx @@ -0,0 +1,243 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import FullCalendar from "@fullcalendar/react"; // must go before plugins +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 } from "@/components/ui/card"; +import { Plus } from "lucide-react"; +import { Checkbox } from "@/components/ui/checkbox"; +import { CalendarEvent, CalendarCategory } from "./data" +import { + EventContentArg, +} from '@fullcalendar/core' +import EventModal from "./event-modal"; +import { useTranslations } from "next-intl"; +const wait = () => new Promise((resolve) => setTimeout(resolve, 1000)); +interface CalendarViewProps { + events: CalendarEvent[]; + categories: CalendarCategory[]; + + +} + +const CalendarView = ({ events, categories }: CalendarViewProps) => { + const [selectedCategory, setSelectedCategory] = useState(null); + const [selectedEventDate, setSelectedEventDate] = useState(null); + const [selectedEvent, setSelectedEvent] = useState(null); + const [draggableInitialized, setDraggableInitialized] = useState(false); +const t = useTranslations("CalendarApp") + // event canvas state + const [sheetOpen, setSheetOpen] = useState(false); + const [date, setDate] = React.useState(new Date()); + + 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" }, + ]); + + useEffect(() => { + setSelectedCategory(categories?.map((c) => c.value)); + }, [events, categories]); + + 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 + const handleEventClick = (arg: any) => { + setSelectedEventDate(null); + setSheetOpen(true); + setSelectedEvent(arg); + wait().then(() => (document.body.style.pointerEvents = "auto")); + }; + // handle close modal + const handleCloseModal = () => { + setSheetOpen(false); + setSelectedEvent(null); + setSelectedEventDate(null); + }; + const handleDateClick = (arg: any) => { + setSheetOpen(true); + setSelectedEventDate(arg); + setSelectedEvent(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 handleClassName = (arg: EventContentArg) => { + + if (arg.event.extendedProps.calendar === "holiday") { + return "destructive"; + } + else if (arg.event.extendedProps.calendar === "business") { + return "primary"; + } else if (arg.event.extendedProps.calendar === "personal") { + return "success"; + } else if (arg.event.extendedProps.calendar === "family") { + return "info"; + } else if (arg.event.extendedProps.calendar === "etc") { + return "info"; + } else if (arg.event.extendedProps.calendar === "meeting") { + return "warning"; + } + else { + return "primary"; + } + + }; + + const filteredEvents = events?.filter((event) => + selectedCategory?.includes(event.extendedProps.calendar) + ); + + return ( + <> +
+ + + + + +
+ { + handleDateClick(s); + }} + className="rounded-md border w-full p-0 border-none" + /> +
+ +
+

+ {t("shortDesc")} +

+ {dragEvents.map((event) => ( + + ))} +
+
+ {t("filter")} +
+
    +
  • + { + if (selectedCategory?.length === categories?.length) { + setSelectedCategory([]); + } else { + setSelectedCategory(categories.map((c) => c.value)); + } + }} + /> + +
  • + {categories?.map((category) => ( +
  • + handleCategorySelection(category.value)} + /> + +
  • + ))} +
+
+
+ + + + + + +
+ + + ); +}; + +export default CalendarView; diff --git a/app/[locale]/(protected)/agenda-setting/data.ts b/app/[locale]/(protected)/agenda-setting/data.ts new file mode 100644 index 00000000..8f4716c9 --- /dev/null +++ b/app/[locale]/(protected)/agenda-setting/data.ts @@ -0,0 +1,155 @@ +import { faker } from "@faker-js/faker"; + +const date = new Date(); +const prevDay = new Date().getDate() - 1; +const nextDay = new Date(new Date().getTime() + 24 * 60 * 60 * 1000); + +// prettier-ignore +const nextMonth = date.getMonth() === 11 ? new Date(date.getFullYear() + 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() + 1, 1) +// prettier-ignore +const prevMonth = date.getMonth() === 11 ? new Date(date.getFullYear() - 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() - 1, 1) +export const calendarEvents = [ + { + id: faker.string.uuid() , + title: "All Day Event", + start: date, + end: nextDay, + allDay: false, + //className: "warning", + extendedProps: { + calendar: "business", + }, + }, + { + id: faker.string.uuid(), + title: "Meeting With Client", + start: new Date(date.getFullYear(), date.getMonth() + 1, -11), + end: new Date(date.getFullYear(), date.getMonth() + 1, -10), + allDay: true, + //className: "success", + extendedProps: { + calendar: "personal", + }, + }, + { + id: faker.string.uuid(), + title: "Lunch", + allDay: true, + start: new Date(date.getFullYear(), date.getMonth() + 1, -9), + end: new Date(date.getFullYear(), date.getMonth() + 1, -7), + // className: "info", + extendedProps: { + calendar: "family", + }, + }, + { + id: faker.string.uuid(), + title: "Birthday Party", + start: new Date(date.getFullYear(), date.getMonth() + 1, -11), + end: new Date(date.getFullYear(), date.getMonth() + 1, -10), + allDay: true, + //className: "primary", + extendedProps: { + calendar: "meeting", + }, + }, + { + id: faker.string.uuid(), + title: "Birthday Party", + start: new Date(date.getFullYear(), date.getMonth() + 1, -13), + end: new Date(date.getFullYear(), date.getMonth() + 1, -12), + allDay: true, + // className: "danger", + extendedProps: { + calendar: "holiday", + }, + }, + { + id: faker.string.uuid(), + title: "Monthly Meeting", + start: nextMonth, + end: nextMonth, + allDay: true, + //className: "primary", + extendedProps: { + calendar: "business", + }, + }, +]; + +export const calendarCategories = [ + { + label: "Business", + value: "business", + activeClass: "ring-primary-500 bg-primary-500", + className: "group-hover:border-blue-500", + }, + { + label: "Personal", + value: "personal", + activeClass: "ring-success-500 bg-success-500", + className: " group-hover:border-green-500", + }, + { + label: "Holiday", + value: "holiday", + activeClass: "ring-danger-500 bg-danger-500", + className: " group-hover:border-red-500", + }, + { + label: "Family", + value: "family", + activeClass: "ring-info-500 bg-info-500", + className: " group-hover:border-cyan-500", + }, + { + label: "Meeting", + value: "meeting", + activeClass: "ring-warning-500 bg-warning-500", + className: " group-hover:border-yellow-500", + }, + { + label: "Etc", + value: "etc", + activeClass: "ring-info-500 bg-info-500", + className: " group-hover:border-cyan-500", + } +]; + +export const categories = [ + { + label: "Business", + value: "business", + className: "data-[state=checked]:bg-primary data-[state=checked]:ring-primary", + }, + { + label: "Personal", + value: "personal", + + className: "data-[state=checked]:bg-success data-[state=checked]:ring-success", + }, + { + label: "Holiday", + value: "holiday", + className: "data-[state=checked]:bg-destructive data-[state=checked]:ring-destructive ", + }, + { + label: "Family", + value: "family", + className: "data-[state=checked]:bg-info data-[state=checked]:ring-info ", + }, + { + label: "Meeting", + value: "meeting", + className: "data-[state=checked]:bg-warning data-[state=checked]:ring-warning", + }, + { + label: "Etc", + value: "etc", + className: "data-[state=checked]:bg-info data-[state=checked]:ring-info", + } +]; + +export type CalendarEvent = (typeof calendarEvents)[number] +export type CalendarCategory = (typeof calendarCategories)[number] +export type Category = (typeof categories)[number] \ No newline at end of file diff --git a/app/[locale]/(protected)/agenda-setting/dragging-events.tsx b/app/[locale]/(protected)/agenda-setting/dragging-events.tsx new file mode 100644 index 00000000..56683eaa --- /dev/null +++ b/app/[locale]/(protected)/agenda-setting/dragging-events.tsx @@ -0,0 +1,23 @@ +import { cn } from "@/lib/utils"; +const ExternalDraggingevent = ({ event }: any) => { + const { title, id, tag } = event; + + return ( +
+ + {title} +
+ ); +}; + +export default ExternalDraggingevent; diff --git a/app/[locale]/(protected)/agenda-setting/event-modal.tsx b/app/[locale]/(protected)/agenda-setting/event-modal.tsx new file mode 100644 index 00000000..4d698df7 --- /dev/null +++ b/app/[locale]/(protected)/agenda-setting/event-modal.tsx @@ -0,0 +1,277 @@ +"use client" +import React, { useState, useEffect } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { useForm, Controller } from "react-hook-form"; +import { cn, } from "@/lib/utils"; +import { format } from "date-fns" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Calendar } from "@/components/ui/calendar"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; +import { Loader2, CalendarIcon } from "lucide-react"; +import DeleteConfirmationDialog from "@/components/delete-confirmation-dialog"; +import { CalendarCategory } from "./data"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; + +const schema = z.object({ + title: z.string().min(3, { message: "Required" }), +}); + +const EventModal = ({ open, onClose, categories, event, selectedDate }: { + open: boolean; + onClose: () => void; + categories: any; + event: any; + selectedDate: any +}) => { + const [startDate, setStartDate] = useState(new Date()); + const [endDate, setEndDate] = useState(new Date()); + const [isPending, startTransition] = React.useTransition(); + const [calendarProps, setCalendarProps] = React.useState(categories[0].value); + // delete modal state + const [deleteModalOpen, setDeleteModalOpen] = useState(false); + const [eventIdToDelete, setEventIdToDelete] = useState(null); + + const { + register, + control, + reset, + setValue, + formState: { errors }, + handleSubmit, + } = useForm({ + resolver: zodResolver(schema), + mode: "all", + }); + + const onSubmit = (data: any) => { + startTransition(async () => { + if (!event) { + data.start = startDate; + data.end = endDate; + data.allDay = false; + data.extendedProps = { + calendar: calendarProps, + }; + } + if (event) { + } + }); + }; + useEffect(() => { + if (selectedDate) { + setStartDate(selectedDate.date); + setEndDate(selectedDate.date); + } + if (event) { + setStartDate(event?.event?.start); + setEndDate(event?.event?.end); + const eventCalendar = event?.event?.extendedProps?.calendar; + if (eventCalendar) { + setCalendarProps(eventCalendar); + } else { + setCalendarProps(categories[0].value); + } + } + setValue("title", event?.event?.title || ""); + }, [event, selectedDate, open, categories, setValue]); + + const onDeleteEventAction = async () => { + try { + + } catch (error) { + + } + }; + + const handleOpenDeleteModal = (eventId: string) => { + setEventIdToDelete(eventId); + setDeleteModalOpen(true); + onClose(); + }; + + return ( + <> + setDeleteModalOpen(false)} + onConfirm={onDeleteEventAction} + defaultToast={false} + /> + + + + + {event ? "Edit Event" : "Create Event"} {event?.title} + + +
+
+
+
+ + + {errors?.title?.message && ( +
+ {typeof errors?.title?.message === 'string' + ? errors?.title?.message + : JSON.stringify(errors?.title?.message)} +
+ )} +
+ +
+ + + + + + + ( + setStartDate(date as Date)} + initialFocus + /> + )} + /> + + +
+
+ + + + + + + ( + setEndDate(date as Date)} + initialFocus + /> + )} + /> + + +
+ +
+ + ( + + )} + /> +
+
+ +
+ + {event && ( + + )} +
+
+
+
+
+ + ); +}; + +export default EventModal; diff --git a/app/[locale]/(protected)/agenda-setting/layout.tsx b/app/[locale]/(protected)/agenda-setting/layout.tsx new file mode 100644 index 00000000..dae6bbc9 --- /dev/null +++ b/app/[locale]/(protected)/agenda-setting/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Calender", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/agenda-setting/page.tsx b/app/[locale]/(protected)/agenda-setting/page.tsx new file mode 100644 index 00000000..266a6f7b --- /dev/null +++ b/app/[locale]/(protected)/agenda-setting/page.tsx @@ -0,0 +1,21 @@ +import { getEvents, getCategories } from "./utils"; +import { Category } from "./data" +import CalendarView from "./calender-view"; + + + +const CalenderPage = async () => { + const events = await getEvents(); + const categories = await getCategories(); + const formattedCategories = categories.map((category: Category) => ({ + ...category, + activeClass: "", + })); + return ( +
+ +
+ ); +}; + +export default CalenderPage; diff --git a/app/[locale]/(protected)/agenda-setting/utils.ts b/app/[locale]/(protected)/agenda-setting/utils.ts new file mode 100644 index 00000000..e4862dd2 --- /dev/null +++ b/app/[locale]/(protected)/agenda-setting/utils.ts @@ -0,0 +1,11 @@ +import { calendarEvents, categories } from "./data"; + +// get events +export const getEvents = async () => { + return calendarEvents; +}; + +// get categories +export const getCategories = async () => { + return categories; +} \ No newline at end of file diff --git a/app/[locale]/(protected)/blog/layout.tsx b/app/[locale]/(protected)/blog/layout.tsx new file mode 100644 index 00000000..47e2f324 --- /dev/null +++ b/app/[locale]/(protected)/blog/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Blog", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/blog/page.tsx b/app/[locale]/(protected)/blog/page.tsx new file mode 100644 index 00000000..72862e58 --- /dev/null +++ b/app/[locale]/(protected)/blog/page.tsx @@ -0,0 +1,5 @@ +const BlogPage = async () => { + return
; +}; + +export default BlogPage; diff --git a/app/[locale]/(protected)/communication/layout.tsx b/app/[locale]/(protected)/communication/layout.tsx new file mode 100644 index 00000000..a7b52e6b --- /dev/null +++ b/app/[locale]/(protected)/communication/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Communication", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/communication/page.tsx b/app/[locale]/(protected)/communication/page.tsx new file mode 100644 index 00000000..986b8f24 --- /dev/null +++ b/app/[locale]/(protected)/communication/page.tsx @@ -0,0 +1,5 @@ +const CommunicationPage = async () => { + return
; +}; + +export default CommunicationPage; diff --git a/app/[locale]/(protected)/content/audio-visual/layout.tsx b/app/[locale]/(protected)/content/audio-visual/layout.tsx new file mode 100644 index 00000000..4f668f32 --- /dev/null +++ b/app/[locale]/(protected)/content/audio-visual/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Video", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/content/audio-visual/page.tsx b/app/[locale]/(protected)/content/audio-visual/page.tsx new file mode 100644 index 00000000..b0c08f7b --- /dev/null +++ b/app/[locale]/(protected)/content/audio-visual/page.tsx @@ -0,0 +1,5 @@ +const VideoPage = async () => { + return
; +}; + +export default VideoPage; diff --git a/app/[locale]/(protected)/content/audio/calender-view.tsx b/app/[locale]/(protected)/content/audio/calender-view.tsx new file mode 100644 index 00000000..2f707e0f --- /dev/null +++ b/app/[locale]/(protected)/content/audio/calender-view.tsx @@ -0,0 +1,243 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import FullCalendar from "@fullcalendar/react"; // must go before plugins +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 } from "@/components/ui/card"; +import { Plus } from "lucide-react"; +import { Checkbox } from "@/components/ui/checkbox"; +import { CalendarEvent, CalendarCategory } from "./data" +import { + EventContentArg, +} from '@fullcalendar/core' +import EventModal from "./event-modal"; +import { useTranslations } from "next-intl"; +const wait = () => new Promise((resolve) => setTimeout(resolve, 1000)); +interface CalendarViewProps { + events: CalendarEvent[]; + categories: CalendarCategory[]; + + +} + +const CalendarView = ({ events, categories }: CalendarViewProps) => { + const [selectedCategory, setSelectedCategory] = useState(null); + const [selectedEventDate, setSelectedEventDate] = useState(null); + const [selectedEvent, setSelectedEvent] = useState(null); + const [draggableInitialized, setDraggableInitialized] = useState(false); +const t = useTranslations("CalendarApp") + // event canvas state + const [sheetOpen, setSheetOpen] = useState(false); + const [date, setDate] = React.useState(new Date()); + + 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" }, + ]); + + useEffect(() => { + setSelectedCategory(categories?.map((c) => c.value)); + }, [events, categories]); + + 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 + const handleEventClick = (arg: any) => { + setSelectedEventDate(null); + setSheetOpen(true); + setSelectedEvent(arg); + wait().then(() => (document.body.style.pointerEvents = "auto")); + }; + // handle close modal + const handleCloseModal = () => { + setSheetOpen(false); + setSelectedEvent(null); + setSelectedEventDate(null); + }; + const handleDateClick = (arg: any) => { + setSheetOpen(true); + setSelectedEventDate(arg); + setSelectedEvent(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 handleClassName = (arg: EventContentArg) => { + + if (arg.event.extendedProps.calendar === "holiday") { + return "destructive"; + } + else if (arg.event.extendedProps.calendar === "business") { + return "primary"; + } else if (arg.event.extendedProps.calendar === "personal") { + return "success"; + } else if (arg.event.extendedProps.calendar === "family") { + return "info"; + } else if (arg.event.extendedProps.calendar === "etc") { + return "info"; + } else if (arg.event.extendedProps.calendar === "meeting") { + return "warning"; + } + else { + return "primary"; + } + + }; + + const filteredEvents = events?.filter((event) => + selectedCategory?.includes(event.extendedProps.calendar) + ); + + return ( + <> +
+ + + + + +
+ { + handleDateClick(s); + }} + className="rounded-md border w-full p-0 border-none" + /> +
+ +
+

+ {t("shortDesc")} +

+ {dragEvents.map((event) => ( + + ))} +
+
+ {t("filter")} +
+
    +
  • + { + if (selectedCategory?.length === categories?.length) { + setSelectedCategory([]); + } else { + setSelectedCategory(categories.map((c) => c.value)); + } + }} + /> + +
  • + {categories?.map((category) => ( +
  • + handleCategorySelection(category.value)} + /> + +
  • + ))} +
+
+
+ + + + + + +
+ + + ); +}; + +export default CalendarView; diff --git a/app/[locale]/(protected)/content/audio/data.ts b/app/[locale]/(protected)/content/audio/data.ts new file mode 100644 index 00000000..8f4716c9 --- /dev/null +++ b/app/[locale]/(protected)/content/audio/data.ts @@ -0,0 +1,155 @@ +import { faker } from "@faker-js/faker"; + +const date = new Date(); +const prevDay = new Date().getDate() - 1; +const nextDay = new Date(new Date().getTime() + 24 * 60 * 60 * 1000); + +// prettier-ignore +const nextMonth = date.getMonth() === 11 ? new Date(date.getFullYear() + 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() + 1, 1) +// prettier-ignore +const prevMonth = date.getMonth() === 11 ? new Date(date.getFullYear() - 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() - 1, 1) +export const calendarEvents = [ + { + id: faker.string.uuid() , + title: "All Day Event", + start: date, + end: nextDay, + allDay: false, + //className: "warning", + extendedProps: { + calendar: "business", + }, + }, + { + id: faker.string.uuid(), + title: "Meeting With Client", + start: new Date(date.getFullYear(), date.getMonth() + 1, -11), + end: new Date(date.getFullYear(), date.getMonth() + 1, -10), + allDay: true, + //className: "success", + extendedProps: { + calendar: "personal", + }, + }, + { + id: faker.string.uuid(), + title: "Lunch", + allDay: true, + start: new Date(date.getFullYear(), date.getMonth() + 1, -9), + end: new Date(date.getFullYear(), date.getMonth() + 1, -7), + // className: "info", + extendedProps: { + calendar: "family", + }, + }, + { + id: faker.string.uuid(), + title: "Birthday Party", + start: new Date(date.getFullYear(), date.getMonth() + 1, -11), + end: new Date(date.getFullYear(), date.getMonth() + 1, -10), + allDay: true, + //className: "primary", + extendedProps: { + calendar: "meeting", + }, + }, + { + id: faker.string.uuid(), + title: "Birthday Party", + start: new Date(date.getFullYear(), date.getMonth() + 1, -13), + end: new Date(date.getFullYear(), date.getMonth() + 1, -12), + allDay: true, + // className: "danger", + extendedProps: { + calendar: "holiday", + }, + }, + { + id: faker.string.uuid(), + title: "Monthly Meeting", + start: nextMonth, + end: nextMonth, + allDay: true, + //className: "primary", + extendedProps: { + calendar: "business", + }, + }, +]; + +export const calendarCategories = [ + { + label: "Business", + value: "business", + activeClass: "ring-primary-500 bg-primary-500", + className: "group-hover:border-blue-500", + }, + { + label: "Personal", + value: "personal", + activeClass: "ring-success-500 bg-success-500", + className: " group-hover:border-green-500", + }, + { + label: "Holiday", + value: "holiday", + activeClass: "ring-danger-500 bg-danger-500", + className: " group-hover:border-red-500", + }, + { + label: "Family", + value: "family", + activeClass: "ring-info-500 bg-info-500", + className: " group-hover:border-cyan-500", + }, + { + label: "Meeting", + value: "meeting", + activeClass: "ring-warning-500 bg-warning-500", + className: " group-hover:border-yellow-500", + }, + { + label: "Etc", + value: "etc", + activeClass: "ring-info-500 bg-info-500", + className: " group-hover:border-cyan-500", + } +]; + +export const categories = [ + { + label: "Business", + value: "business", + className: "data-[state=checked]:bg-primary data-[state=checked]:ring-primary", + }, + { + label: "Personal", + value: "personal", + + className: "data-[state=checked]:bg-success data-[state=checked]:ring-success", + }, + { + label: "Holiday", + value: "holiday", + className: "data-[state=checked]:bg-destructive data-[state=checked]:ring-destructive ", + }, + { + label: "Family", + value: "family", + className: "data-[state=checked]:bg-info data-[state=checked]:ring-info ", + }, + { + label: "Meeting", + value: "meeting", + className: "data-[state=checked]:bg-warning data-[state=checked]:ring-warning", + }, + { + label: "Etc", + value: "etc", + className: "data-[state=checked]:bg-info data-[state=checked]:ring-info", + } +]; + +export type CalendarEvent = (typeof calendarEvents)[number] +export type CalendarCategory = (typeof calendarCategories)[number] +export type Category = (typeof categories)[number] \ No newline at end of file diff --git a/app/[locale]/(protected)/content/audio/dragging-events.tsx b/app/[locale]/(protected)/content/audio/dragging-events.tsx new file mode 100644 index 00000000..56683eaa --- /dev/null +++ b/app/[locale]/(protected)/content/audio/dragging-events.tsx @@ -0,0 +1,23 @@ +import { cn } from "@/lib/utils"; +const ExternalDraggingevent = ({ event }: any) => { + const { title, id, tag } = event; + + return ( +
+ + {title} +
+ ); +}; + +export default ExternalDraggingevent; diff --git a/app/[locale]/(protected)/content/audio/event-modal.tsx b/app/[locale]/(protected)/content/audio/event-modal.tsx new file mode 100644 index 00000000..4d698df7 --- /dev/null +++ b/app/[locale]/(protected)/content/audio/event-modal.tsx @@ -0,0 +1,277 @@ +"use client" +import React, { useState, useEffect } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { useForm, Controller } from "react-hook-form"; +import { cn, } from "@/lib/utils"; +import { format } from "date-fns" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Calendar } from "@/components/ui/calendar"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; +import { Loader2, CalendarIcon } from "lucide-react"; +import DeleteConfirmationDialog from "@/components/delete-confirmation-dialog"; +import { CalendarCategory } from "./data"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; + +const schema = z.object({ + title: z.string().min(3, { message: "Required" }), +}); + +const EventModal = ({ open, onClose, categories, event, selectedDate }: { + open: boolean; + onClose: () => void; + categories: any; + event: any; + selectedDate: any +}) => { + const [startDate, setStartDate] = useState(new Date()); + const [endDate, setEndDate] = useState(new Date()); + const [isPending, startTransition] = React.useTransition(); + const [calendarProps, setCalendarProps] = React.useState(categories[0].value); + // delete modal state + const [deleteModalOpen, setDeleteModalOpen] = useState(false); + const [eventIdToDelete, setEventIdToDelete] = useState(null); + + const { + register, + control, + reset, + setValue, + formState: { errors }, + handleSubmit, + } = useForm({ + resolver: zodResolver(schema), + mode: "all", + }); + + const onSubmit = (data: any) => { + startTransition(async () => { + if (!event) { + data.start = startDate; + data.end = endDate; + data.allDay = false; + data.extendedProps = { + calendar: calendarProps, + }; + } + if (event) { + } + }); + }; + useEffect(() => { + if (selectedDate) { + setStartDate(selectedDate.date); + setEndDate(selectedDate.date); + } + if (event) { + setStartDate(event?.event?.start); + setEndDate(event?.event?.end); + const eventCalendar = event?.event?.extendedProps?.calendar; + if (eventCalendar) { + setCalendarProps(eventCalendar); + } else { + setCalendarProps(categories[0].value); + } + } + setValue("title", event?.event?.title || ""); + }, [event, selectedDate, open, categories, setValue]); + + const onDeleteEventAction = async () => { + try { + + } catch (error) { + + } + }; + + const handleOpenDeleteModal = (eventId: string) => { + setEventIdToDelete(eventId); + setDeleteModalOpen(true); + onClose(); + }; + + return ( + <> + setDeleteModalOpen(false)} + onConfirm={onDeleteEventAction} + defaultToast={false} + /> + + + + + {event ? "Edit Event" : "Create Event"} {event?.title} + + +
+
+
+
+ + + {errors?.title?.message && ( +
+ {typeof errors?.title?.message === 'string' + ? errors?.title?.message + : JSON.stringify(errors?.title?.message)} +
+ )} +
+ +
+ + + + + + + ( + setStartDate(date as Date)} + initialFocus + /> + )} + /> + + +
+
+ + + + + + + ( + setEndDate(date as Date)} + initialFocus + /> + )} + /> + + +
+ +
+ + ( + + )} + /> +
+
+ +
+ + {event && ( + + )} +
+
+
+
+
+ + ); +}; + +export default EventModal; diff --git a/app/[locale]/(protected)/content/audio/layout.tsx b/app/[locale]/(protected)/content/audio/layout.tsx new file mode 100644 index 00000000..482ca21a --- /dev/null +++ b/app/[locale]/(protected)/content/audio/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Audio", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/content/audio/page.tsx b/app/[locale]/(protected)/content/audio/page.tsx new file mode 100644 index 00000000..266a6f7b --- /dev/null +++ b/app/[locale]/(protected)/content/audio/page.tsx @@ -0,0 +1,21 @@ +import { getEvents, getCategories } from "./utils"; +import { Category } from "./data" +import CalendarView from "./calender-view"; + + + +const CalenderPage = async () => { + const events = await getEvents(); + const categories = await getCategories(); + const formattedCategories = categories.map((category: Category) => ({ + ...category, + activeClass: "", + })); + return ( +
+ +
+ ); +}; + +export default CalenderPage; diff --git a/app/[locale]/(protected)/content/audio/utils.ts b/app/[locale]/(protected)/content/audio/utils.ts new file mode 100644 index 00000000..e4862dd2 --- /dev/null +++ b/app/[locale]/(protected)/content/audio/utils.ts @@ -0,0 +1,11 @@ +import { calendarEvents, categories } from "./data"; + +// get events +export const getEvents = async () => { + return calendarEvents; +}; + +// get categories +export const getCategories = async () => { + return categories; +} \ No newline at end of file diff --git a/app/[locale]/(protected)/content/image/layout.tsx b/app/[locale]/(protected)/content/image/layout.tsx new file mode 100644 index 00000000..4d71e12e --- /dev/null +++ b/app/[locale]/(protected)/content/image/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Image", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/content/image/page.tsx b/app/[locale]/(protected)/content/image/page.tsx new file mode 100644 index 00000000..4a80b838 --- /dev/null +++ b/app/[locale]/(protected)/content/image/page.tsx @@ -0,0 +1,5 @@ +const ImagePage = async () => { + return
; +}; + +export default ImagePage; diff --git a/app/[locale]/(protected)/content/image/utils.ts b/app/[locale]/(protected)/content/image/utils.ts new file mode 100644 index 00000000..e4862dd2 --- /dev/null +++ b/app/[locale]/(protected)/content/image/utils.ts @@ -0,0 +1,11 @@ +import { calendarEvents, categories } from "./data"; + +// get events +export const getEvents = async () => { + return calendarEvents; +}; + +// get categories +export const getCategories = async () => { + return categories; +} \ No newline at end of file diff --git a/app/[locale]/(protected)/content/nulis-ai/layout.tsx b/app/[locale]/(protected)/content/nulis-ai/layout.tsx new file mode 100644 index 00000000..22c2ae57 --- /dev/null +++ b/app/[locale]/(protected)/content/nulis-ai/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Nulis", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/content/nulis-ai/page.tsx b/app/[locale]/(protected)/content/nulis-ai/page.tsx new file mode 100644 index 00000000..47035108 --- /dev/null +++ b/app/[locale]/(protected)/content/nulis-ai/page.tsx @@ -0,0 +1,5 @@ +const CalenderPage = async () => { + return
; +}; + +export default CalenderPage; diff --git a/app/[locale]/(protected)/content/spit/layout.tsx b/app/[locale]/(protected)/content/spit/layout.tsx new file mode 100644 index 00000000..cd1b0419 --- /dev/null +++ b/app/[locale]/(protected)/content/spit/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Spit", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/content/spit/page.tsx b/app/[locale]/(protected)/content/spit/page.tsx new file mode 100644 index 00000000..47035108 --- /dev/null +++ b/app/[locale]/(protected)/content/spit/page.tsx @@ -0,0 +1,5 @@ +const CalenderPage = async () => { + return
; +}; + +export default CalenderPage; diff --git a/app/[locale]/(protected)/content/teks/layout.tsx b/app/[locale]/(protected)/content/teks/layout.tsx new file mode 100644 index 00000000..8ab8d383 --- /dev/null +++ b/app/[locale]/(protected)/content/teks/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Teks", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/content/teks/page.tsx b/app/[locale]/(protected)/content/teks/page.tsx new file mode 100644 index 00000000..9ccb9ea8 --- /dev/null +++ b/app/[locale]/(protected)/content/teks/page.tsx @@ -0,0 +1,5 @@ +const TeksPage = async () => { + return
; +}; + +export default TeksPage; diff --git a/app/[locale]/(protected)/contest/layout.tsx b/app/[locale]/(protected)/contest/layout.tsx new file mode 100644 index 00000000..8c52e5dd --- /dev/null +++ b/app/[locale]/(protected)/contest/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Contest", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/contest/page.tsx b/app/[locale]/(protected)/contest/page.tsx new file mode 100644 index 00000000..45164169 --- /dev/null +++ b/app/[locale]/(protected)/contest/page.tsx @@ -0,0 +1,5 @@ +const ContestPage = async () => { + return
; +}; + +export default ContestPage; diff --git a/app/[locale]/(protected)/curated-content/layout.tsx b/app/[locale]/(protected)/curated-content/layout.tsx new file mode 100644 index 00000000..fb504943 --- /dev/null +++ b/app/[locale]/(protected)/curated-content/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Kurasi Konten", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/curated-content/page.tsx b/app/[locale]/(protected)/curated-content/page.tsx new file mode 100644 index 00000000..6099b771 --- /dev/null +++ b/app/[locale]/(protected)/curated-content/page.tsx @@ -0,0 +1,5 @@ +const CuratedContentPage = async () => { + return
; +}; + +export default CuratedContentPage; diff --git a/app/[locale]/(protected)/dashboard/analytics/page.tsx b/app/[locale]/(protected)/dashboard/analytics/page.tsx index b79488f5..c9946631 100644 --- a/app/[locale]/(protected)/dashboard/analytics/page.tsx +++ b/app/[locale]/(protected)/dashboard/analytics/page.tsx @@ -11,154 +11,154 @@ import MostSales from "./components/most-sales"; import OverviewRadialChart from "./components/overview-radial"; import { useTranslations } from "next-intl"; const DashboardPage = () => { - const t = useTranslations("AnalyticsDashboard"); - return ( -
-
-
- -
-
- {t("widget_title")} -
-

- {t("widget_desc")} -

+ const t = useTranslations("AnalyticsDashboard"); + return ( +
+
+
+ +
+
+ {t("widget_title")}
- {t("widget_badge")} - Description of the image - -
-
- - -
- - - -
-
-
-
+

+ {t("widget_desc")} +

+
+ {t("widget_badge")} + Description of the image +
-
-
- - - - - -
-
- - - - {t("overview_circle_chart_title")} - - - - - - - -
-
- - - - {t("company_table_title")} - - - - - - - -
-
- - - - {t("recent_activity_table_title")} - - - - - - - -
-
- -
-
- - - - {t("overview_circle_chart_title")} - - - - - -
-
-

- {t("invested_amount")} -

-
- $8264.35 -
-
- +0.001.23 (0.2%) -
-
- -
-

- {t("invested_amount")} -

-
- $8264.35 -
-
- -
-

- {t("invested_amount")} -

-
- $8264.35 -
-
-
-
-
-
+
+ + +
+ + + +
+
+
- ); -} +
+
+ + + + + +
+
+ + + + {t("overview_circle_chart_title")} + + + + + + + +
+
+ + + + {t("company_table_title")} + + + + + + + +
+
+ + + + {t("recent_activity_table_title")} + + + + + + + +
+
+ +
+
+ + + + {t("overview_circle_chart_title")} + + + + + +
+
+

+ {t("invested_amount")} +

+
+ $8264.35 +
+
+ +0.001.23 (0.2%) +
+
-export default DashboardPage; \ No newline at end of file +
+

+ {t("invested_amount")} +

+
+ $8264.35 +
+
+ +
+

+ {t("invested_amount")} +

+
+ $8264.35 +
+
+
+
+
+
+
+
+ ); +}; + +export default DashboardPage; diff --git a/app/[locale]/(protected)/planning/mediahub/layout.tsx b/app/[locale]/(protected)/planning/mediahub/layout.tsx new file mode 100644 index 00000000..8ba3fc82 --- /dev/null +++ b/app/[locale]/(protected)/planning/mediahub/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Mediahub", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/planning/mediahub/page.tsx b/app/[locale]/(protected)/planning/mediahub/page.tsx new file mode 100644 index 00000000..a0a67684 --- /dev/null +++ b/app/[locale]/(protected)/planning/mediahub/page.tsx @@ -0,0 +1,5 @@ +const MediahubPage = async () => { + return
; +}; + +export default MediahubPage; diff --git a/app/[locale]/(protected)/planning/medsos-mediahub/layout.tsx b/app/[locale]/(protected)/planning/medsos-mediahub/layout.tsx new file mode 100644 index 00000000..3f658e5f --- /dev/null +++ b/app/[locale]/(protected)/planning/medsos-mediahub/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Medsos Mediahub", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/planning/medsos-mediahub/page.tsx b/app/[locale]/(protected)/planning/medsos-mediahub/page.tsx new file mode 100644 index 00000000..ba9349e2 --- /dev/null +++ b/app/[locale]/(protected)/planning/medsos-mediahub/page.tsx @@ -0,0 +1,5 @@ +const MedsosMediahubPage = async () => { + return
; +}; + +export default MedsosMediahubPage; diff --git a/app/[locale]/(protected)/schedule/event/layout.tsx b/app/[locale]/(protected)/schedule/event/layout.tsx new file mode 100644 index 00000000..b71cbc17 --- /dev/null +++ b/app/[locale]/(protected)/schedule/event/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Event", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/schedule/event/page.tsx b/app/[locale]/(protected)/schedule/event/page.tsx new file mode 100644 index 00000000..8986f0a1 --- /dev/null +++ b/app/[locale]/(protected)/schedule/event/page.tsx @@ -0,0 +1,5 @@ +const EventPage = async () => { + return
; +}; + +export default EventPage; diff --git a/app/[locale]/(protected)/schedule/press-conference/layout.tsx b/app/[locale]/(protected)/schedule/press-conference/layout.tsx new file mode 100644 index 00000000..051b27cb --- /dev/null +++ b/app/[locale]/(protected)/schedule/press-conference/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Press Conference", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/schedule/press-conference/page.tsx b/app/[locale]/(protected)/schedule/press-conference/page.tsx new file mode 100644 index 00000000..5fd3a029 --- /dev/null +++ b/app/[locale]/(protected)/schedule/press-conference/page.tsx @@ -0,0 +1,5 @@ +const PressConferencePage = async () => { + return
; +}; + +export default PressConferencePage; diff --git a/app/[locale]/(protected)/schedule/press-release/layout.tsx b/app/[locale]/(protected)/schedule/press-release/layout.tsx new file mode 100644 index 00000000..58d933ed --- /dev/null +++ b/app/[locale]/(protected)/schedule/press-release/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Press Release", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/schedule/press-release/page.tsx b/app/[locale]/(protected)/schedule/press-release/page.tsx new file mode 100644 index 00000000..96aeea78 --- /dev/null +++ b/app/[locale]/(protected)/schedule/press-release/page.tsx @@ -0,0 +1,5 @@ +const PressReleasePage = async () => { + return
; +}; + +export default PressReleasePage; diff --git a/app/[locale]/(protected)/task/layout.tsx b/app/[locale]/(protected)/task/layout.tsx new file mode 100644 index 00000000..56d3004f --- /dev/null +++ b/app/[locale]/(protected)/task/layout.tsx @@ -0,0 +1,9 @@ +export const metadata = { + title: "Task", +}; + +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/task/page.tsx b/app/[locale]/(protected)/task/page.tsx new file mode 100644 index 00000000..cebd5d62 --- /dev/null +++ b/app/[locale]/(protected)/task/page.tsx @@ -0,0 +1,5 @@ +const TaskPage = async () => { + return
; +}; + +export default TaskPage; diff --git a/lib/menus.ts b/lib/menus.ts index 2efb9ebc..8050507a 100644 --- a/lib/menus.ts +++ b/lib/menus.ts @@ -1,5 +1,3 @@ - - export type SubChildren = { href: string; label: string; @@ -31,7 +29,6 @@ export type Group = { }; export function getMenuList(pathname: string, t: any): Group[] { - return [ { groupLabel: t("dashboard"), @@ -42,40 +39,61 @@ export function getMenuList(pathname: string, t: any): Group[] { href: "/dashboard/analytics", label: t("dashboard"), active: pathname.includes("/dashboard"), - icon: "heroicons-outline:home", + icon: "material-symbols:dashboard", + submenus: [], + }, + ], + }, + { + groupLabel: "", + id: "content", + menus: [ + { + id: "content", + href: "/content/image", + label: t("konten"), + active: pathname.includes("/content"), + icon: "line-md:youtube", submenus: [ { - href: "/dashboard/analytics", - label: t("analytics"), - active: pathname === "/dashboard/analytics", - icon: "heroicons:arrow-trending-up", + href: "/content/image", + label: t("image"), + active: pathname === "/content/image", + icon: "ic:outline-image", children: [], }, { - href: "/dashboard/dash-ecom", - label: t("ecommerce"), - active: pathname === "/dashboard/dash-ecom", - icon: "heroicons:shopping-cart", + href: "/content/audio-visual", + label: t("audio visual"), + active: pathname === "/content/audio-visual", + icon: "line-md:youtube", children: [], }, { - href: "/dashboard/project", - label: t("project"), - active: pathname === "/dashboard/project", + href: "/content/teks", + label: t("text"), + active: pathname === "/content/teks", icon: "heroicons:document", children: [], }, { - href: "/dashboard/crm", - label: t("crm"), - active: pathname === "/dashboard/crm", + href: "/content/audio", + label: t("audio"), + active: pathname === "/content/audio", icon: "heroicons:share", children: [], }, { - href: "/dashboard/banking", - label: t("banking"), - active: pathname === "/dashboard/banking", + href: "/content/spit", + label: t("spit"), + active: pathname === "/content/spit", + icon: "heroicons:credit-card", + children: [], + }, + { + href: "/content/nulis-ai", + label: t("nulis ai"), + active: pathname === "/content/nulisai", icon: "heroicons:credit-card", children: [], }, @@ -85,14 +103,149 @@ export function getMenuList(pathname: string, t: any): Group[] { }, { groupLabel: "", - id: "changelog", + id: "agenda-setting", menus: [ { - id: "changelog", - href: "/changelog", - label: t("changelog"), - active: pathname.includes("/changelog"), - icon: "heroicons:arrow-trending-up", + id: "agenda-setting", + href: "/agenda-setting", + label: t("agenda setting"), + active: pathname.includes("/agenda-setting"), + icon: "iconoir:journal-page", + submenus: [], + }, + ], + }, + { + groupLabel: "", + id: "planning", + menus: [ + { + id: "planning", + href: "/planning", + label: t("perencanaan"), + active: pathname.includes("/planning"), + icon: "pajamas:planning", + submenus: [ + { + href: "/planning/mediahub", + label: t("mediaHub"), + active: pathname === "/planning/mediahub", + icon: "heroicons:arrow-trending-up", + children: [], + }, + { + href: "/planning/medsos-mediahub", + label: t("medsos mediahub"), + active: pathname === "/planning/medsos-mediahub", + icon: "heroicons:shopping-cart", + children: [], + }, + ], + }, + ], + }, + { + groupLabel: "", + id: "task", + menus: [ + { + id: "task", + href: "/task", + label: t("penugasan"), + active: pathname.includes("/task"), + icon: "fluent:clipboard-task-add-24-regular", + submenus: [], + }, + ], + }, + { + groupLabel: "", + id: "schedule", + menus: [ + { + id: "schedule", + href: "/schedule", + label: t("schedule"), + active: pathname.includes("/schedule"), + icon: "uil:schedule", + submenus: [ + { + href: "/schedule/press-conference", + label: t("konfesensi pers"), + active: pathname === "/schedule/press-conference", + icon: "heroicons:arrow-trending-up", + children: [], + }, + { + href: "/schedule/event", + label: t("event"), + active: pathname === "/schedule/event", + icon: "heroicons:shopping-cart", + children: [], + }, + { + href: "/schedule/press-release", + label: t("pers rilis"), + active: pathname === "/schedule/press-release", + icon: "heroicons:shopping-cart", + children: [], + }, + ], + }, + ], + }, + { + groupLabel: "", + id: "blog", + menus: [ + { + id: "blog", + href: "/blog", + label: t("indeks"), + active: pathname.includes("/blog"), + icon: "fluent:clipboard-text-32-regular", + submenus: [], + }, + ], + }, + { + groupLabel: "", + id: "curatedcontent", + menus: [ + { + id: "curatedcontent", + href: "/curated-content", + label: t("kurasi konten"), + active: pathname.includes("/curated-content"), + icon: "pixelarticons:calendar-text", + submenus: [], + }, + ], + }, + { + groupLabel: "", + id: "communication", + menus: [ + { + id: "communication", + href: "/communication", + label: t("komunikasi"), + active: pathname.includes("/communication"), + icon: "token:chat", + submenus: [], + }, + ], + }, + { + groupLabel: "", + id: "contest", + menus: [ + { + id: "contest", + href: "/contest", + label: t("lomba"), + active: pathname.includes("/contest"), + icon: "ic:outline-emoji-events", submenus: [], }, ], @@ -129,7 +282,7 @@ export function getMenuList(pathname: string, t: any): Group[] { id: "calendar", href: "/app/calendar", label: t("calendar"), - active:pathname.includes("/app/calendar"), + active: pathname.includes("/app/calendar"), icon: "heroicons-outline:calendar", submenus: [], }, @@ -137,7 +290,7 @@ export function getMenuList(pathname: string, t: any): Group[] { id: "todo", href: "/app/todo", label: t("todo"), - active:pathname.includes("/app/todo"), + active: pathname.includes("/app/todo"), icon: "heroicons-outline:clipboard-check", submenus: [], }, @@ -704,7 +857,7 @@ export function getMenuList(pathname: string, t: any): Group[] { label: t("inputFile"), active: pathname === "/forms/input-file", icon: "", - children: [] + children: [], }, { href: "/forms/form-validation", @@ -1171,10 +1324,10 @@ export function getMenuList(pathname: string, t: any): Group[] { children: [], }, ], - } - ] - } - ] + }, + ], + }, + ], }, { groupLabel: "", @@ -1871,7 +2024,7 @@ export function getHorizontalMenuList(pathname: string, t: any): Group[] { label: t("forms"), active: pathname.includes("/forms"), icon: "heroicons-outline:clipboard-list", - submenus: [ + submenus: [ { href: "/forms/input", label: t("input"), @@ -2391,5 +2544,3 @@ export function getHorizontalMenuList(pathname: string, t: any): Group[] { }, ]; } - -