feat:change sidebar

This commit is contained in:
Anang Yusman 2024-11-27 11:14:10 +07:00
parent 1cdfc5bad5
commit ead5912044
47 changed files with 2033 additions and 183 deletions

View File

@ -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<string[] | null>(null);
const [selectedEventDate, setSelectedEventDate] = useState<Date | null>(null);
const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(null);
const [draggableInitialized, setDraggableInitialized] = useState<boolean>(false);
const t = useTranslations("CalendarApp")
// event canvas state
const [sheetOpen, setSheetOpen] = useState<boolean>(false);
const [date, setDate] = React.useState<Date>(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 (
<>
<div className="grid grid-cols-12 gap-6 divide-x divide-border">
<Card className="col-span-12 lg:col-span-4 2xl:col-span-3 pb-5">
<CardContent className="p-0">
<CardHeader className="border-none mb-2 pt-5">
<Button
onClick={handleDateClick}
className="dark:bg-background dark:text-foreground"
>
<Plus className="w-4 h-4 me-1" />
{t("addEvent")}
</Button>
</CardHeader>
<div className="px-3">
<Calendar
mode="single"
selected={date}
onSelect={(s) => {
handleDateClick(s);
}}
className="rounded-md border w-full p-0 border-none"
/>
</div>
<div id="external-events" className=" space-y-1.5 mt-6 px-4">
<p className="text-sm font-medium text-default-700 mb-3">
{t("shortDesc")}
</p>
{dragEvents.map((event) => (
<ExternalDraggingevent key={event.id} event={event} />
))}
</div>
<div className="py-4 text-default-800 font-semibold text-xs uppercase mt-4 mb-2 px-4">
{t("filter")}
</div>
<ul className="space-y-3 px-4">
<li className=" flex gap-3">
<Checkbox
checked={selectedCategory?.length === categories?.length}
onClick={() => {
if (selectedCategory?.length === categories?.length) {
setSelectedCategory([]);
} else {
setSelectedCategory(categories.map((c) => c.value));
}
}}
/>
<Label>All</Label>
</li>
{categories?.map((category) => (
<li className="flex gap-3 " key={category.value}>
<Checkbox
className={category.className}
id={category.label}
checked={selectedCategory?.includes(category.value)}
onClick={() => handleCategorySelection(category.value)}
/>
<Label htmlFor={category.label}>{category.label}</Label>
</li>
))}
</ul>
</CardContent>
</Card>
<Card className="col-span-12 lg:col-span-8 2xl:col-span-9 pt-5">
<CardContent className="dashcode-app-calendar">
<FullCalendar
plugins={[
dayGridPlugin,
timeGridPlugin,
interactionPlugin,
listPlugin,
]}
headerToolbar={{
left: "prev,next today",
center: "title",
right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek",
}}
events={filteredEvents}
editable={true}
rerenderDelay={10}
eventDurationEditable={false}
selectable={true}
selectMirror={true}
droppable={true}
dayMaxEvents={2}
weekends={true}
eventClassNames={handleClassName}
dateClick={handleDateClick}
eventClick={handleEventClick}
initialView="dayGridMonth"
/>
</CardContent>
</Card>
</div>
<EventModal
open={sheetOpen}
onClose={handleCloseModal}
categories={categories}
event={selectedEvent}
selectedDate={selectedEventDate}
/>
</>
);
};
export default CalendarView;

View File

@ -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]

View File

@ -0,0 +1,23 @@
import { cn } from "@/lib/utils";
const ExternalDraggingevent = ({ event }: any) => {
const { title, id, tag } = event;
return (
<div
title={title}
data-id={id}
className="fc-event px-4 py-1.5 bg-default-100 dark:bg-default-300 rounded text-sm flex items-center gap-2 shadow-sm cursor-move" >
<span
className={cn("h-2 w-2 rounded-full block", {
"bg-primary": tag === "business",
"bg-warning": tag === "meeting",
"bg-destructive": tag === "holiday",
"bg-info": tag === "etc",
})}
></span>
<span className="text-sm font-medium text-default-900">{title}</span>
</div>
);
};
export default ExternalDraggingevent;

View File

@ -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<Date>(new Date());
const [endDate, setEndDate] = useState<Date>(new Date());
const [isPending, startTransition] = React.useTransition();
const [calendarProps, setCalendarProps] = React.useState<any>(categories[0].value);
// delete modal state
const [deleteModalOpen, setDeleteModalOpen] = useState<boolean>(false);
const [eventIdToDelete, setEventIdToDelete] = useState<string | null>(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 (
<>
<DeleteConfirmationDialog
open={deleteModalOpen}
onClose={() => setDeleteModalOpen(false)}
onConfirm={onDeleteEventAction}
defaultToast={false}
/>
<Dialog open={open} onOpenChange={onClose}>
<DialogContent
onPointerDownOutside={onClose}
>
<DialogHeader>
<DialogTitle>
{event ? "Edit Event" : "Create Event"} {event?.title}
</DialogTitle>
</DialogHeader>
<div className="mt-6 h-full">
<form className="h-full" onSubmit={handleSubmit(onSubmit)}>
<div className="space-y-4 pb-5 ">
<div className="space-y-1.5">
<Label htmlFor="title">Event Name</Label>
<Input
id="title"
type="text"
placeholder="Enter Event Name"
{...register("title")}
/>
{errors?.title?.message && (
<div className="text-destructive text-sm">
{typeof errors?.title?.message === 'string'
? errors?.title?.message
: JSON.stringify(errors?.title?.message)}
</div>
)}
</div>
<div className="space-y-1.5">
<Label htmlFor="startDate">Start Date </Label>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
size="md"
className={cn(
"w-full justify-between text-left font-normal border-default-200 text-default-600 md:px-4",
!startDate && "text-muted-foreground"
)}
>
{startDate ? (
format(startDate, "PP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Controller
name="startDate"
control={control}
render={({ field }) => (
<Calendar
mode="single"
selected={startDate}
onSelect={(date) => setStartDate(date as Date)}
initialFocus
/>
)}
/>
</PopoverContent>
</Popover>
</div>
<div className="space-y-1.5">
<Label htmlFor="endDate">End Date</Label>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
size="md"
className={cn(
"w-full justify-between text-left font-normal border-default-200 text-default-600 md:px-4",
!endDate && "text-muted-foreground"
)}
>
{endDate ? (
format(endDate, "PP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Controller
name="endDate"
control={control}
render={({ field }) => (
<Calendar
mode="single"
selected={endDate}
onSelect={(date) => setEndDate(date as Date)}
initialFocus
/>
)}
/>
</PopoverContent>
</Popover>
</div>
<div className="space-y-1.5">
<Label htmlFor="calendarProps">Label </Label>
<Controller
name="calendarProps"
control={control}
render={({ field }) => (
<Select
value={calendarProps}
onValueChange={(data) => setCalendarProps(data)}
>
<SelectTrigger>
<SelectValue placeholder="Label" />
</SelectTrigger>
<SelectContent>
{categories.map((category: CalendarCategory) => (
<SelectItem
value={category.value}
key={category.value}
>
{category.label}
</SelectItem>
))}
</SelectContent>
</Select>
)}
/>
</div>
</div>
<div className="flex flex-wrap gap-2 mt-10">
<Button type="submit" disabled={isPending} className="flex-1">
{isPending ? (
<>
<Loader2 className="me-2 h-4 w-4 animate-spin" />
{event ? "Updating..." : "Adding..."}
</>
) : event ? (
"Update Event"
) : (
"Add Event"
)}
</Button>
{event && (
<Button
type="button"
color="destructive"
onClick={() => handleOpenDeleteModal(event?.event?.id)}
className="flex-1"
>
Delete
</Button>
)}
</div>
</form>
</div>
</DialogContent>
</Dialog>
</>
);
};
export default EventModal;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Calender",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -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 (
<div>
<CalendarView events={events} categories={formattedCategories} />
</div>
);
};
export default CalenderPage;

View File

@ -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;
}

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const BlogPage = async () => {
return <div></div>;
};
export default BlogPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Communication",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const CommunicationPage = async () => {
return <div></div>;
};
export default CommunicationPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Video",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const VideoPage = async () => {
return <div></div>;
};
export default VideoPage;

View File

@ -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<string[] | null>(null);
const [selectedEventDate, setSelectedEventDate] = useState<Date | null>(null);
const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(null);
const [draggableInitialized, setDraggableInitialized] = useState<boolean>(false);
const t = useTranslations("CalendarApp")
// event canvas state
const [sheetOpen, setSheetOpen] = useState<boolean>(false);
const [date, setDate] = React.useState<Date>(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 (
<>
<div className="grid grid-cols-12 gap-6 divide-x divide-border">
<Card className="col-span-12 lg:col-span-4 2xl:col-span-3 pb-5">
<CardContent className="p-0">
<CardHeader className="border-none mb-2 pt-5">
<Button
onClick={handleDateClick}
className="dark:bg-background dark:text-foreground"
>
<Plus className="w-4 h-4 me-1" />
{t("addEvent")}
</Button>
</CardHeader>
<div className="px-3">
<Calendar
mode="single"
selected={date}
onSelect={(s) => {
handleDateClick(s);
}}
className="rounded-md border w-full p-0 border-none"
/>
</div>
<div id="external-events" className=" space-y-1.5 mt-6 px-4">
<p className="text-sm font-medium text-default-700 mb-3">
{t("shortDesc")}
</p>
{dragEvents.map((event) => (
<ExternalDraggingevent key={event.id} event={event} />
))}
</div>
<div className="py-4 text-default-800 font-semibold text-xs uppercase mt-4 mb-2 px-4">
{t("filter")}
</div>
<ul className="space-y-3 px-4">
<li className=" flex gap-3">
<Checkbox
checked={selectedCategory?.length === categories?.length}
onClick={() => {
if (selectedCategory?.length === categories?.length) {
setSelectedCategory([]);
} else {
setSelectedCategory(categories.map((c) => c.value));
}
}}
/>
<Label>All</Label>
</li>
{categories?.map((category) => (
<li className="flex gap-3 " key={category.value}>
<Checkbox
className={category.className}
id={category.label}
checked={selectedCategory?.includes(category.value)}
onClick={() => handleCategorySelection(category.value)}
/>
<Label htmlFor={category.label}>{category.label}</Label>
</li>
))}
</ul>
</CardContent>
</Card>
<Card className="col-span-12 lg:col-span-8 2xl:col-span-9 pt-5">
<CardContent className="dashcode-app-calendar">
<FullCalendar
plugins={[
dayGridPlugin,
timeGridPlugin,
interactionPlugin,
listPlugin,
]}
headerToolbar={{
left: "prev,next today",
center: "title",
right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek",
}}
events={filteredEvents}
editable={true}
rerenderDelay={10}
eventDurationEditable={false}
selectable={true}
selectMirror={true}
droppable={true}
dayMaxEvents={2}
weekends={true}
eventClassNames={handleClassName}
dateClick={handleDateClick}
eventClick={handleEventClick}
initialView="dayGridMonth"
/>
</CardContent>
</Card>
</div>
<EventModal
open={sheetOpen}
onClose={handleCloseModal}
categories={categories}
event={selectedEvent}
selectedDate={selectedEventDate}
/>
</>
);
};
export default CalendarView;

View File

@ -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]

View File

@ -0,0 +1,23 @@
import { cn } from "@/lib/utils";
const ExternalDraggingevent = ({ event }: any) => {
const { title, id, tag } = event;
return (
<div
title={title}
data-id={id}
className="fc-event px-4 py-1.5 bg-default-100 dark:bg-default-300 rounded text-sm flex items-center gap-2 shadow-sm cursor-move" >
<span
className={cn("h-2 w-2 rounded-full block", {
"bg-primary": tag === "business",
"bg-warning": tag === "meeting",
"bg-destructive": tag === "holiday",
"bg-info": tag === "etc",
})}
></span>
<span className="text-sm font-medium text-default-900">{title}</span>
</div>
);
};
export default ExternalDraggingevent;

View File

@ -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<Date>(new Date());
const [endDate, setEndDate] = useState<Date>(new Date());
const [isPending, startTransition] = React.useTransition();
const [calendarProps, setCalendarProps] = React.useState<any>(categories[0].value);
// delete modal state
const [deleteModalOpen, setDeleteModalOpen] = useState<boolean>(false);
const [eventIdToDelete, setEventIdToDelete] = useState<string | null>(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 (
<>
<DeleteConfirmationDialog
open={deleteModalOpen}
onClose={() => setDeleteModalOpen(false)}
onConfirm={onDeleteEventAction}
defaultToast={false}
/>
<Dialog open={open} onOpenChange={onClose}>
<DialogContent
onPointerDownOutside={onClose}
>
<DialogHeader>
<DialogTitle>
{event ? "Edit Event" : "Create Event"} {event?.title}
</DialogTitle>
</DialogHeader>
<div className="mt-6 h-full">
<form className="h-full" onSubmit={handleSubmit(onSubmit)}>
<div className="space-y-4 pb-5 ">
<div className="space-y-1.5">
<Label htmlFor="title">Event Name</Label>
<Input
id="title"
type="text"
placeholder="Enter Event Name"
{...register("title")}
/>
{errors?.title?.message && (
<div className="text-destructive text-sm">
{typeof errors?.title?.message === 'string'
? errors?.title?.message
: JSON.stringify(errors?.title?.message)}
</div>
)}
</div>
<div className="space-y-1.5">
<Label htmlFor="startDate">Start Date </Label>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
size="md"
className={cn(
"w-full justify-between text-left font-normal border-default-200 text-default-600 md:px-4",
!startDate && "text-muted-foreground"
)}
>
{startDate ? (
format(startDate, "PP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Controller
name="startDate"
control={control}
render={({ field }) => (
<Calendar
mode="single"
selected={startDate}
onSelect={(date) => setStartDate(date as Date)}
initialFocus
/>
)}
/>
</PopoverContent>
</Popover>
</div>
<div className="space-y-1.5">
<Label htmlFor="endDate">End Date</Label>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
size="md"
className={cn(
"w-full justify-between text-left font-normal border-default-200 text-default-600 md:px-4",
!endDate && "text-muted-foreground"
)}
>
{endDate ? (
format(endDate, "PP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Controller
name="endDate"
control={control}
render={({ field }) => (
<Calendar
mode="single"
selected={endDate}
onSelect={(date) => setEndDate(date as Date)}
initialFocus
/>
)}
/>
</PopoverContent>
</Popover>
</div>
<div className="space-y-1.5">
<Label htmlFor="calendarProps">Label </Label>
<Controller
name="calendarProps"
control={control}
render={({ field }) => (
<Select
value={calendarProps}
onValueChange={(data) => setCalendarProps(data)}
>
<SelectTrigger>
<SelectValue placeholder="Label" />
</SelectTrigger>
<SelectContent>
{categories.map((category: CalendarCategory) => (
<SelectItem
value={category.value}
key={category.value}
>
{category.label}
</SelectItem>
))}
</SelectContent>
</Select>
)}
/>
</div>
</div>
<div className="flex flex-wrap gap-2 mt-10">
<Button type="submit" disabled={isPending} className="flex-1">
{isPending ? (
<>
<Loader2 className="me-2 h-4 w-4 animate-spin" />
{event ? "Updating..." : "Adding..."}
</>
) : event ? (
"Update Event"
) : (
"Add Event"
)}
</Button>
{event && (
<Button
type="button"
color="destructive"
onClick={() => handleOpenDeleteModal(event?.event?.id)}
className="flex-1"
>
Delete
</Button>
)}
</div>
</form>
</div>
</DialogContent>
</Dialog>
</>
);
};
export default EventModal;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Audio",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -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 (
<div>
<CalendarView events={events} categories={formattedCategories} />
</div>
);
};
export default CalenderPage;

View File

@ -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;
}

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Image",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const ImagePage = async () => {
return <div></div>;
};
export default ImagePage;

View File

@ -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;
}

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Nulis",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const CalenderPage = async () => {
return <div></div>;
};
export default CalenderPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Spit",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const CalenderPage = async () => {
return <div></div>;
};
export default CalenderPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Teks",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const TeksPage = async () => {
return <div></div>;
};
export default TeksPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Contest",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const ContestPage = async () => {
return <div></div>;
};
export default ContestPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Kurasi Konten",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const CuratedContentPage = async () => {
return <div></div>;
};
export default CuratedContentPage;

View File

@ -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 (
<div>
<div className="grid grid-cols-12 items-center gap-5 mb-5">
<div className="2xl:col-span-3 lg:col-span-4 col-span-12">
<WelcomeBlock>
<div className="max-w-[180px] relative z-10">
<div className="text-xl font-medium text-default-900 dark:text-default-100 mb-2">
{t("widget_title")}
</div>
<p className="text-sm text-default-800 dark:text-default-100">
{t("widget_desc")}
</p>
const t = useTranslations("AnalyticsDashboard");
return (
<div>
<div className="grid grid-cols-12 items-center gap-5 mb-5">
<div className="2xl:col-span-3 lg:col-span-4 col-span-12">
<WelcomeBlock>
<div className="max-w-[180px] relative z-10">
<div className="text-xl font-medium text-default-900 dark:text-default-100 mb-2">
{t("widget_title")}
</div>
<BlockBadge className="end-3">{t("widget_badge")}</BlockBadge>
<Image
src="/images/all-img/widget-bg-1.png"
width={400}
height={150}
priority
alt="Description of the image"
className="absolute top-0 start-0 w-full h-full object-cover rounded-md"
/>
</WelcomeBlock>
</div>
<div className="2xl:col-span-9 lg:col-span-8 col-span-12">
<Card>
<CardContent className="p-4">
<div className="grid md:grid-cols-3 gap-4">
<StatisticsBlock
title={t("revenue_chart_title")}
total="3,564"
className="bg-info/10 border-none shadow-none"
/>
<StatisticsBlock
title={t("sold_chart_title")}
total="564"
className="bg-warning/10 border-none shadow-none"
chartColor="#FB8F65"
/>
<StatisticsBlock
title={t("growth_chart_title")}
total="+5.0%"
className="bg-primary/10 border-none shadow-none"
chartColor="#2563eb"
/>
</div>
</CardContent>
</Card>
</div>
<p className="text-sm text-default-800 dark:text-default-100">
{t("widget_desc")}
</p>
</div>
<BlockBadge className="end-3">{t("widget_badge")}</BlockBadge>
<Image
src="/images/all-img/widget-bg-1.png"
width={400}
height={150}
priority
alt="Description of the image"
className="absolute top-0 start-0 w-full h-full object-cover rounded-md"
/>
</WelcomeBlock>
</div>
<div className="grid grid-cols-12 gap-5">
<div className="lg:col-span-8 col-span-12">
<Card>
<CardContent className="p-4">
<RevinueBarChart/>
</CardContent>
</Card>
</div>
<div className="lg:col-span-4 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("overview_circle_chart_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent>
<OverviewChart />
</CardContent>
</Card>
</div>
<div className="lg:col-span-8 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("company_table_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent className="p-0">
<CompanyTable />
</CardContent>
</Card>
</div>
<div className="lg:col-span-4 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("recent_activity_table_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent>
<RecentActivity />
</CardContent>
</Card>
</div>
<div className="lg:col-span-8 col-span-12">
<MostSales />
</div>
<div className="lg:col-span-4 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("overview_circle_chart_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent>
<OverviewRadialChart />
<div className="bg-default-50 rounded p-4 mt-8 flex justify-between flex-wrap">
<div className="space-y-1">
<h4 className="text-default-600 text-xs font-normal">
{t("invested_amount")}
</h4>
<div className="text-sm font-medium text-default-900">
$8264.35
</div>
<div className="text-default-500 text-xs font-normal">
+0.001.23 (0.2%)
</div>
</div>
<div className="space-y-1">
<h4 className="text-default-600 text-xs font-normal">
{t("invested_amount")}
</h4>
<div className="text-sm font-medium text-default-900">
$8264.35
</div>
</div>
<div className="space-y-1">
<h4 className="text-default-600 text-xs font-normal">
{t("invested_amount")}
</h4>
<div className="text-sm font-medium text-default-900">
$8264.35
</div>
</div>
</div>
</CardContent>
</Card>
</div>
<div className="2xl:col-span-9 lg:col-span-8 col-span-12">
<Card>
<CardContent className="p-4">
<div className="grid md:grid-cols-3 gap-4">
<StatisticsBlock
title={t("revenue_chart_title")}
total="3,564"
className="bg-info/10 border-none shadow-none"
/>
<StatisticsBlock
title={t("sold_chart_title")}
total="564"
className="bg-warning/10 border-none shadow-none"
chartColor="#FB8F65"
/>
<StatisticsBlock
title={t("growth_chart_title")}
total="+5.0%"
className="bg-primary/10 border-none shadow-none"
chartColor="#2563eb"
/>
</div>
</CardContent>
</Card>
</div>
</div>
);
}
<div className="grid grid-cols-12 gap-5">
<div className="lg:col-span-8 col-span-12">
<Card>
<CardContent className="p-4">
<RevinueBarChart />
</CardContent>
</Card>
</div>
<div className="lg:col-span-4 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("overview_circle_chart_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent>
<OverviewChart />
</CardContent>
</Card>
</div>
<div className="lg:col-span-8 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("company_table_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent className="p-0">
<CompanyTable />
</CardContent>
</Card>
</div>
<div className="lg:col-span-4 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("recent_activity_table_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent>
<RecentActivity />
</CardContent>
</Card>
</div>
<div className="lg:col-span-8 col-span-12">
<MostSales />
</div>
<div className="lg:col-span-4 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
{t("overview_circle_chart_title")}
</CardTitle>
<DashboardDropdown />
</CardHeader>
<CardContent>
<OverviewRadialChart />
<div className="bg-default-50 rounded p-4 mt-8 flex justify-between flex-wrap">
<div className="space-y-1">
<h4 className="text-default-600 text-xs font-normal">
{t("invested_amount")}
</h4>
<div className="text-sm font-medium text-default-900">
$8264.35
</div>
<div className="text-default-500 text-xs font-normal">
+0.001.23 (0.2%)
</div>
</div>
export default DashboardPage;
<div className="space-y-1">
<h4 className="text-default-600 text-xs font-normal">
{t("invested_amount")}
</h4>
<div className="text-sm font-medium text-default-900">
$8264.35
</div>
</div>
<div className="space-y-1">
<h4 className="text-default-600 text-xs font-normal">
{t("invested_amount")}
</h4>
<div className="text-sm font-medium text-default-900">
$8264.35
</div>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
</div>
);
};
export default DashboardPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Mediahub",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const MediahubPage = async () => {
return <div></div>;
};
export default MediahubPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Medsos Mediahub",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const MedsosMediahubPage = async () => {
return <div></div>;
};
export default MedsosMediahubPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Event",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const EventPage = async () => {
return <div></div>;
};
export default EventPage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Press Conference",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const PressConferencePage = async () => {
return <div></div>;
};
export default PressConferencePage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Press Release",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const PressReleasePage = async () => {
return <div></div>;
};
export default PressReleasePage;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Task",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,5 @@
const TaskPage = async () => {
return <div></div>;
};
export default TaskPage;

View File

@ -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[] {
},
];
}