diff --git a/app/[locale]/(admin)/admin/layout.tsx b/app/[locale]/(admin)/admin/layout.tsx
deleted file mode 100644
index 459794f..0000000
--- a/app/[locale]/(admin)/admin/layout.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-"use client";
-
-import { AdminLayout } from "@/components/layout/admin-layout";
-
-export default function AdminPageLayout({
- children,
-}: {
- children: React.ReactNode;
-}) {
- return {children};
-}
diff --git a/app/[locale]/theme.css b/app/[locale]/theme.css
new file mode 100644
index 0000000..3800566
--- /dev/null
+++ b/app/[locale]/theme.css
@@ -0,0 +1,63 @@
+.theme-dark {
+ --sidebar: 222.2 84% 4.9%;
+ --header: 222.2 84% 4.9%;
+}
+.theme-rose {
+ --sidebar: 341, 64%, 43%;
+ --header: 341, 64%, 43%;
+ --secondary: 339, 60%, 51%;
+ --menu-arrow: 339, 60%, 51%;
+ --menu-arrow-active: 336, 67%, 60%;
+
+}
+
+.theme-gray {
+ --sidebar: 210, 10%, 23%;
+ --header: 210, 10%, 23%;
+
+ --secondary: 207, 14%, 31%;
+ --menu-arrow: 207, 14%, 31%;
+ --menu-arrow-active: 203, 16%, 43%;
+}
+.theme-steel-blue {
+ --sidebar: 226, 36%, 39%;
+ --header: 226, 36%, 39%;
+ --secondary: 224, 40%, 48%;
+ --menu-arrow: 224, 40%, 48%;
+ --menu-arrow-active: 216, 47%, 60%;
+}
+.theme-purple {
+ --sidebar: 299, 56%, 19%;
+ --header: 299, 56%, 19%;
+ --secondary: 299, 40%, 28%;
+ --menu-arrow: 299, 40%, 28%;
+ --menu-arrow-active: 298, 44%, 33%;
+}
+
+.theme-redwood {
+ --sidebar: 345, 24%, 29%;
+ --header: 345, 24%, 29%;
+ --secondary: 346, 26%, 35%;
+ --menu-arrow: 346, 26%, 35%;
+ --menu-arrow-active: 344, 27%, 42%;
+}
+.theme-green {
+ --sidebar: 164, 64%, 21%;
+ --header: 164, 64%, 21%;
+
+ --secondary: 164, 68%, 24%;
+ --menu-arrow: 164, 68%, 24%;
+ --menu-arrow-active: 163, 69%, 30%;
+}
+.theme-ocean-blue {
+ --sidebar: 206, 92%, 35%;
+ --header: 206, 92%, 35%;
+
+ --secondary: 205, 94%, 39%;
+ --menu-arrow: 205, 94%, 39%;
+ --menu-arrow-active: 203, 85%, 48%;
+}
+.theme-transparent{
+ --header: transparent;
+ box-shadow: none;
+}
\ No newline at end of file
diff --git a/components/layout/admin-layout.tsx b/components/layout/admin-layout.tsx
deleted file mode 100644
index fd45da0..0000000
--- a/components/layout/admin-layout.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-"use client";
-
-import { useEffect, useState } from "react";
-import React, { ReactNode } from "react";
-import { ThemeProvider } from "./theme-context";
-import { motion, AnimatePresence } from "framer-motion";
-import { SidebarProvider } from "./sidebar-context";
-import { ModernSidebar } from "./modern-sidebar";
-import { ModernHeader } from "./modern-header";
-
-export const AdminLayout = ({ children }: { children: ReactNode }) => {
- const [sidebarOpen, setSidebarOpen] = useState(true);
- const [hasMounted, setHasMounted] = useState(false);
-
- const toggleSidebar = () => {
- setSidebarOpen(!sidebarOpen);
- };
-
- // Hooks
- useEffect(() => {
- setHasMounted(true);
- // Auto-collapse sidebar on mobile
- const handleResize = () => {
- if (window.innerWidth < 1024) {
- setSidebarOpen(false);
- } else {
- setSidebarOpen(true);
- }
- };
-
- handleResize();
- window.addEventListener('resize', handleResize);
- return () => window.removeEventListener('resize', handleResize);
- }, []);
-
- // Render loading state until mounted
- if (!hasMounted) {
- return (
-
- );
- }
-
- return (
-
-
-
-
- {/* Modern Sidebar */}
-
-
- {/* Main Content Area */}
-
- {/* Modern Header */}
-
-
- {/* Main Content */}
-
-
- {children}
-
-
-
-
-
-
-
- );
-};
diff --git a/components/layout/modern-header.tsx b/components/layout/modern-header.tsx
deleted file mode 100644
index a1566db..0000000
--- a/components/layout/modern-header.tsx
+++ /dev/null
@@ -1,136 +0,0 @@
-"use client";
-
-import React, { useState, useEffect, useRef } from "react";
-import { motion, AnimatePresence } from "framer-motion";
-import {
- Search,
- Bell,
- User,
- Settings,
- LogOut,
- ChevronDown,
- Menu,
-} from "lucide-react";
-
-interface ModernHeaderProps {
- onMenuToggle: () => void;
- sidebarOpen: boolean;
-}
-
-export const ModernHeader: React.FC = ({
- onMenuToggle,
- sidebarOpen,
-}) => {
- const [showUserDropdown, setShowUserDropdown] = useState(false);
- const [searchQuery, setSearchQuery] = useState("");
- const dropdownRef = useRef(null);
-
- // Close dropdown when clicking outside
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
- setShowUserDropdown(false);
- }
- };
-
- document.addEventListener('mousedown', handleClickOutside);
- return () => {
- document.removeEventListener('mousedown', handleClickOutside);
- };
- }, []);
-
- return (
-
- );
-};
diff --git a/components/layout/modern-sidebar.tsx b/components/layout/modern-sidebar.tsx
deleted file mode 100644
index 68ad996..0000000
--- a/components/layout/modern-sidebar.tsx
+++ /dev/null
@@ -1,266 +0,0 @@
-"use client";
-
-import React, { useState } from "react";
-import Link from "next/link";
-import { usePathname } from "next/navigation";
-import { motion, AnimatePresence } from "framer-motion";
-import {
- LayoutDashboard,
- Image,
- Video,
- FileText,
- Music,
- ChevronRight,
- ChevronDown,
- Menu,
- X,
-} from "lucide-react";
-
-interface SidebarItem {
- title: string;
- icon: React.ComponentType<{ className?: string }>;
- link?: string;
- children?: SidebarItem[];
-}
-
-const sidebarItems: SidebarItem[] = [
- {
- title: "Dashboard",
- icon: LayoutDashboard,
- link: "/admin/dashboard",
- },
- {
- title: "Content Management",
- icon: FileText,
- children: [
- {
- title: "Foto",
- icon: Image,
- link: "/admin/content/image",
- },
- {
- title: "Audio Visual",
- icon: Video,
- link: "/admin/content/audio-visual",
- },
- {
- title: "Teks",
- icon: FileText,
- link: "/admin/content/document",
- },
- {
- title: "Audio",
- icon: Music,
- link: "/admin/content/audio",
- },
- ],
- },
-];
-
-interface ModernSidebarProps {
- isOpen: boolean;
- onToggle: () => void;
-}
-
-export const ModernSidebar: React.FC = ({
- isOpen,
- onToggle,
-}) => {
- const pathname = usePathname();
- const [expandedItems, setExpandedItems] = useState([]);
-
- const toggleExpanded = (title: string) => {
- setExpandedItems((prev) =>
- prev.includes(title)
- ? prev.filter((item) => item !== title)
- : [...prev, title]
- );
- };
-
- const SidebarItemComponent: React.FC<{
- item: SidebarItem;
- level?: number;
- }> = ({ item, level = 0 }) => {
- const isExpanded = expandedItems.includes(item.title);
- const hasChildren = item.children && item.children.length > 0;
- const isActive = pathname === item.link;
-
- if (hasChildren) {
- return (
-
- {/* Parent Menu */}
-
-
- {/* Expanded Submenu (when sidebar is open) */}
-
- {isOpen && isExpanded && (
-
-
- {item.children?.map((child) => (
-
- ))}
-
-
- )}
-
-
- {/* Collapsed Submenu Icons (when sidebar is collapsed) */}
- {!isOpen && (
-
- {item.children?.map((child) => (
-
-
-
-
-
- ))}
-
- )}
-
- );
- }
-
- return (
-
- 0 ? "ml-4" : ""}`}
- >
-
- {isOpen && (
- {item.title}
- )}
-
-
- );
- };
-
- return (
- <>
- {/* Mobile Overlay */}
-
- {isOpen && (
-
- )}
-
-
- {/* Sidebar */}
-
- {/* Header */}
-
-
-
- N
-
- {isOpen && (
-
-
- Netidhub
-
- Admin Panel
-
- )}
-
-
-
- {/* Navigation */}
-
-
-
-
- {/* Floating Toggle Button - Expand */}
-
- {!isOpen && (
-
-
-
- )}
-
-
- {/* Floating Toggle Button - Collapse */}
-
- {isOpen && (
-
-
-
- )}
-
- >
- );
-};
diff --git a/components/layout/sidebar-context.tsx b/components/layout/sidebar-context.tsx
deleted file mode 100644
index a566005..0000000
--- a/components/layout/sidebar-context.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-'use client'
-import React, { createContext, useContext, useEffect, useState } from 'react';
-
-interface SidebarContextType {
- isOpen: boolean;
- toggleSidebar: () => void;
-}
-
-const SidebarContext = createContext(undefined);
-
-export const SidebarProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
- const [isOpen, setIsOpen] = useState(() => {
- if (typeof window !== 'undefined') {
- const storedValue = localStorage.getItem('sidebarOpen');
- return storedValue ? JSON.parse(storedValue) : false;
- }
- });
-
- const toggleSidebar = () => {
- setIsOpen(!isOpen);
- };
-
- useEffect(() => {
- localStorage.setItem('sidebarOpen', JSON.stringify(isOpen));
- }, [isOpen]);
-
- useEffect(() => {
- const handleResize = () => {
- setIsOpen(window.innerWidth > 768); // Ganti 768 dengan lebar yang sesuai dengan breakpoint Anda
- };
-
- handleResize(); // Pastikan untuk memanggil fungsi handleResize saat komponen dimuat
-
- window.addEventListener('resize', handleResize);
-
- return () => {
- window.removeEventListener('resize', handleResize);
- };
- }, []);
-
- return (
-
- {children}
-
- );
-};
-
-export const useSidebar = () => {
- const context = useContext(SidebarContext);
- if (!context) {
- throw new Error('useSidebar must be used within a SidebarProvider');
- }
- return context;
-};
-
-export const useSidebarContext = () => {
- return useContext(SidebarContext);
-};
\ No newline at end of file
diff --git a/components/layout/theme-context.tsx b/components/layout/theme-context.tsx
deleted file mode 100644
index b498a01..0000000
--- a/components/layout/theme-context.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-"use client";
-
-import React, { createContext, useContext, useEffect, useState } from 'react';
-
-type Theme = 'light' | 'dark';
-
-interface ThemeContextType {
- theme: Theme;
- toggleTheme: () => void;
- setTheme: (theme: Theme) => void;
-}
-
-const ThemeContext = createContext(undefined);
-
-export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
- const [theme, setThemeState] = useState('light');
- const [mounted, setMounted] = useState(false);
-
- useEffect(() => {
- setMounted(true);
- // Get theme from localStorage or default to 'light'
- const savedTheme = localStorage.getItem('theme') as Theme;
- if (savedTheme) {
- setThemeState(savedTheme);
- } else {
- // Check system preference
- const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
- setThemeState(systemTheme);
- }
- }, []);
-
- useEffect(() => {
- if (!mounted) return;
-
- // Update document class and localStorage
- document.documentElement.classList.remove('light', 'dark');
- document.documentElement.classList.add(theme);
- localStorage.setItem('theme', theme);
- }, [theme, mounted]);
-
- const toggleTheme = () => {
- setThemeState(prev => prev === 'light' ? 'dark' : 'light');
- };
-
- const setTheme = (newTheme: Theme) => {
- setThemeState(newTheme);
- };
-
- // Prevent hydration mismatch
- if (!mounted) {
- return <>{children}>;
- }
-
- return (
-
- {children}
-
- );
-};
-
-export const useTheme = () => {
- const context = useContext(ThemeContext);
- if (context === undefined) {
- throw new Error('useTheme must be used within a ThemeProvider');
- }
- return context;
-};
\ No newline at end of file
diff --git a/components/logo.tsx b/components/logo.tsx
index 2b940df..941e434 100644
--- a/components/logo.tsx
+++ b/components/logo.tsx
@@ -31,10 +31,9 @@ const Logo = () => {
D
)} */}
);
diff --git a/components/partials/sidebar/common/collapse-menu-button.tsx b/components/partials/sidebar/common/collapse-menu-button.tsx
index 006cf42..6f7db4f 100644
--- a/components/partials/sidebar/common/collapse-menu-button.tsx
+++ b/components/partials/sidebar/common/collapse-menu-button.tsx
@@ -146,7 +146,7 @@ export function CollapseMenuButton({
variant="ghost"
fullWidth
size='sm'
- className={cn('w-full justify-center text-center p-0 h-auto hover:bg-transparent hover:text-default capitalize text-xs font-normal mb-2 first:mt-4 last:mb-0', {
+ className={cn('w-full justify-center text-center p-0 h-auto hover:bg-transparent hover:text-default capitalize text-xs font-normal mb-1.5 first:mt-2 last:mb-0', {
'font-semibold': active
})}
asChild
@@ -180,7 +180,7 @@ export function CollapseMenuButton({
ref={setNodeRef}
variant={active ? "default" : "ghost"}
color='secondary'
- className={cn('justify-start capitalize group h-auto py-3 md:px-3 px-3 ring-offset-sidebar group-data-[state=open]:bg-secondary ', {
+ className={cn('justify-start capitalize group h-auto py-2.5 md:px-3 px-3 ring-offset-sidebar group-data-[state=open]:bg-secondary ', {
'hover:md:ps-8': config.sidebar === 'draggable' && isDesktop
})}
fullWidth
@@ -237,7 +237,7 @@ export function CollapseMenuButton({
key={index}
color='secondary'
variant="ghost"
- className={cn('w-full justify-start h-auto hover:bg-transparent hover:ring-offset-0 capitalize text-sm font-normal mb-2 last:mb-0 first:mt-3 md:px-5 px-5', {
+ className={cn('w-full justify-start h-auto hover:bg-transparent hover:ring-offset-0 capitalize text-sm font-normal mb-1.5 last:mb-0 first:mt-2 md:px-5 px-5', {
'font-medium': active,
'dark:opacity-80': !active,
})}
diff --git a/components/partials/sidebar/common/menu-item.tsx b/components/partials/sidebar/common/menu-item.tsx
index 1e04826..d4bb2f9 100644
--- a/components/partials/sidebar/common/menu-item.tsx
+++ b/components/partials/sidebar/common/menu-item.tsx
@@ -4,7 +4,7 @@ import React, { CSSProperties } from 'react'
import { Button } from "@/components/ui/button";
import { Icon } from '@/components/ui/icon'
import { type Menu } from '@/lib/menus';
-import { Link } from '@/i18n/routing';
+import { Link } from '@/components/navigation';
import { cn } from "@/lib/utils";
import { GripVertical } from 'lucide-react';
@@ -58,7 +58,7 @@ const MenuItem = ({ href, label, icon, active, id, collapsed }: MenuItemProps) =
color={active ? "default" : "secondary"}
fullWidth
className={cn('', {
- 'justify-start text-sm font-medium capitalize group hover:md:px-8 h-auto py-3 md:px-3 px-3': !collapsed,
+ 'justify-start text-sm font-medium capitalize group hover:md:px-8 h-auto py-2.5 md:px-3 px-3': !collapsed,
'hover:ring-transparent hover:ring-offset-0': !active
})}
asChild
@@ -129,7 +129,7 @@ const MenuItem = ({ href, label, icon, active, id, collapsed }: MenuItemProps) =
fullWidth
color={active ? "default" : "secondary"}
className={cn('', {
- 'justify-start text-sm font-medium capitalize h-auto py-3 md:px-3 px-3': !collapsed || hovered,
+ 'justify-start text-sm font-medium capitalize h-auto py-2.5 md:px-3 px-3': !collapsed || hovered,
'hover:ring-transparent hover:ring-offset-0': !active
})}
asChild
diff --git a/components/partials/sidebar/common/menu-label.tsx b/components/partials/sidebar/common/menu-label.tsx
index 0ec5918..f128766 100644
--- a/components/partials/sidebar/common/menu-label.tsx
+++ b/components/partials/sidebar/common/menu-label.tsx
@@ -7,7 +7,7 @@ const MenuLabel = ({ label, className }: { label: string, className?: string })
const [config] = useConfig()
if (config.sidebar === 'compact') return null
return (
-
+
{label}
)
diff --git a/components/partials/sidebar/menu/menu-classic.tsx b/components/partials/sidebar/menu/menu-classic.tsx
index b371b9e..12df7bc 100644
--- a/components/partials/sidebar/menu/menu-classic.tsx
+++ b/components/partials/sidebar/menu/menu-classic.tsx
@@ -84,10 +84,10 @@ export function MenuClassic({ }) {
) : ""}