diff --git a/Dockerfile b/Dockerfile
index ff1dd29..335d444 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -11,7 +11,7 @@ RUN npm install -g pnpm
WORKDIR /usr/src/app
# Menyalin file penting terlebih dahulu untuk caching
-COPY package.json pnpm-lock.yaml ./
+COPY package.json ./
# Menyalin direktori ckeditor5 jika diperlukan
COPY vendor/ckeditor5 ./vendor/ckeditor5
diff --git a/app/(admin)/admin/dashboard/page.tsx b/app/(admin)/admin/dashboard/page.tsx
index 3be562d..92cce1c 100644
--- a/app/(admin)/admin/dashboard/page.tsx
+++ b/app/(admin)/admin/dashboard/page.tsx
@@ -1,11 +1,34 @@
+"use client";
+
import DashboardContainer from "@/components/main/dashboard/dashboard-container";
+import { motion } from "framer-motion";
+import { useEffect, useState } from "react";
export default function AdminPage() {
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ if (!mounted) {
+ return (
+
-
+
);
}
diff --git a/app/globals.css b/app/globals.css
index dc98be7..a609acd 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -120,3 +120,65 @@
@apply bg-background text-foreground;
}
}
+
+/* Custom utility classes */
+@layer utilities {
+ .line-clamp-1 {
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 1;
+ }
+
+ .line-clamp-2 {
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+ }
+
+ .line-clamp-3 {
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 3;
+ }
+
+ .text-gradient {
+ background: linear-gradient(to right, var(--tw-gradient-stops));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ }
+
+ .scrollbar-hide {
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+ }
+
+ .scrollbar-hide::-webkit-scrollbar {
+ display: none;
+ }
+
+ .scrollbar-thin {
+ scrollbar-width: thin;
+ scrollbar-color: rgb(203 213 225) transparent;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar-thumb {
+ background-color: rgb(203 213 225);
+ border-radius: 3px;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar-thumb:hover {
+ background-color: rgb(148 163 184);
+ }
+}
diff --git a/app/layout.tsx b/app/layout.tsx
index 14490a5..63e2178 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,16 +1,16 @@
import type { Metadata } from "next";
-// import { Geist, Geist_Mono } from "next/font/google";
+import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
-// const geistSans = Geist({
-// variable: "--font-geist-sans",
-// subsets: ["latin"],
-// });
+const geistSans = Geist({
+ variable: "--font-geist-sans",
+ subsets: ["latin"],
+});
-// const geistMono = Geist_Mono({
-// variable: "--font-geist-mono",
-// subsets: ["latin"],
-// });
+const geistMono = Geist_Mono({
+ variable: "--font-geist-mono",
+ subsets: ["latin"],
+});
export const metadata: Metadata = {
title: "Mikul News",
@@ -23,10 +23,8 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
-
+
+
{children}
diff --git a/components/form/login.tsx b/components/form/login.tsx
index 5736c86..7eeee15 100644
--- a/components/form/login.tsx
+++ b/components/form/login.tsx
@@ -55,18 +55,6 @@ export default function Login() {
if (!username || !password) {
error("Username & Password Wajib Diisi !");
} else {
- // let response = await emailValidation(data);
- // if (response?.error) {
- // error("Username / Password Tidak Sesuai");
- // return false;
- // }
-
- // if (response?.data?.messages[0] === "Continue to setup email") {
- // setFirstLogin(true);
- // } else {
- // setNeedOtp(true);
- // }
-
loading();
const response = await postSignIn(data);
if (response?.error) {
@@ -93,7 +81,7 @@ export default function Login() {
const resActivity = await saveActivity(
{
activityTypeId: 1,
- url: "https://kontenhumas.com/auth",
+ url: "https://dev.mikulnews.com/auth",
userId: profile?.data?.data?.id,
},
accessData?.id_token
@@ -139,7 +127,6 @@ export default function Login() {
close();
}
}
- // }
};
const checkUsername = async () => {
@@ -173,90 +160,6 @@ export default function Login() {
});
};
- // const submitOtp = async () => {
- // loading();
- // const validation = await otpValidationLogin({
- // username: username,
- // otpCode: otpValue,
- // });
- // if (validation?.error) {
- // error("OTP Tidak Sesuai");
- // return false;
- // }
-
- // const response = await postSignIn({
- // username: username,
- // password: password,
- // });
-
- // const resProfile = await getProfile(response?.data?.data?.access_token);
- // const profile = resProfile?.data?.data;
-
- // const dateTime: any = new Date();
-
- // const newTime: any = dateTime.getTime() + 10 * 60 * 1000;
-
- // Cookies.set("access_token", response?.data?.data?.access_token, {
- // expires: 1,
- // });
- // Cookies.set("refresh_token", response?.data?.data?.refresh_token, {
- // expires: 1,
- // });
- // Cookies.set("time_refresh", newTime, {
- // expires: 1,
- // });
- // Cookies.set("is_first_login", "true", {
- // secure: true,
- // sameSite: "strict",
- // });
- // const resActivity = await saveActivity(
- // {
- // activityTypeId: 1,
- // url: "https://kontenhumas.com/auth",
- // userId: profile?.data?.data?.id,
- // },
- // accessData?.id_token
- // );
- // Cookies.set("profile_picture", profile?.profilePictureUrl, {
- // expires: 1,
- // });
- // Cookies.set("uie", profile?.id, {
- // expires: 1,
- // });
- // Cookies.set("ufne", profile?.fullname, {
- // expires: 1,
- // });
- // Cookies.set("ulie", profile?.userLevelGroup, {
- // expires: 1,
- // });
- // Cookies.set("username", profile?.username, {
- // expires: 1,
- // });
- // Cookies.set("urie", profile?.roleId, {
- // expires: 1,
- // });
- // Cookies.set("roleName", profile?.roleName, {
- // expires: 1,
- // });
- // Cookies.set("masterPoldaId", profile?.masterPoldaId, {
- // expires: 1,
- // });
- // Cookies.set("ulne", profile?.userLevelId, {
- // expires: 1,
- // });
- // Cookies.set("urce", profile?.roleCode, {
- // expires: 1,
- // });
- // Cookies.set("email", profile?.email, {
- // expires: 1,
- // });
- // router.push("/admin/dashboard");
- // Cookies.set("status", "login", {
- // expires: 1,
- // });
- // close();
- // };
-
const submitCheckEmail = async () => {
const req = {
oldEmail: oldEmail,
@@ -281,190 +184,264 @@ export default function Login() {
};
return (
-
-
-
-

-
+
+ {/* Left Side - Logo Section */}
+
+
+
+
+
+
+

+
+
+
+
Portal Mikul News
+
Platform berita terpercaya untuk informasi terkini
+
+
+
+ {/* Decorative elements */}
+
+
- {isFirstLogin ? (
-
-
- Setting Account
-
- {/*
Email Lama
*/}
- {/*
*/}
-
-
- setOldEmail(e.target.value)}
- />
-
- {/*
Email Baru
*/}
- {/*
*/}
-
-
- setNewEmail(e.target.value)}
- />
-
-
-
- ) : needOtp ? (
-
- {/*
Submit OTP
-
OTP
-
-
-
-
- Beranda
-
-
*/}
-
- ) : isResetPassword ? (
-
-
- Reset Password
-
-
-
setCheckUsernameValue(e.target.value.trim())}
- onPaste={(e) => setCheckUsernameValue(e.currentTarget.value.trim())}
- onCopy={(e) => setCheckUsernameValue(e.currentTarget.value.trim())}
- />
-
-
-
-
- ) : (
-
-
-
- Selamat Datang di Portal Mikul News
-
-
- Silahkan Login untuk Melihat informasi serta untuk mengetahui
- status permintaan informasi dan keberatan yang sudah diajukan.
-
-
-
-
setValUsername(e.target.value.trim())}
- onPaste={(e) => setValUsername(e.currentTarget.value.trim())}
- onCopy={(e) => setValUsername(e.currentTarget.value.trim())}
- />
-
-
-
-
setPassword(e.target.value)}
+ {/* Right Side - Login Form */}
+
+
+ {/* Mobile Logo */}
+
+
+

-
-
-
-
-
-
+
+
+ {isFirstLogin ? (
+
+
+
+
Setup Akun
+
Lengkapi informasi email Anda
+
+
+
+
+
+ setOldEmail(e.target.value)}
+ />
+
+
+
+
+ setNewEmail(e.target.value)}
+ />
+
+
+
+
+
+ ) : needOtp ? (
+
+
+
+
Verifikasi OTP
+
Masukkan kode OTP yang telah dikirim
+
+
+ ) : isResetPassword ? (
+
+
+
+
Reset Password
+
Masukkan username untuk reset password
+
+
+
+
+
+ setCheckUsernameValue(e.target.value.trim())}
+ onPaste={(e) => setCheckUsernameValue(e.currentTarget.value.trim())}
+ onCopy={(e) => setCheckUsernameValue(e.currentTarget.value.trim())}
+ />
+
+
+
+
+
+
+ Beranda
+
+
+
+
+
+
+ ) : (
+
+
+
+
Selamat Datang
+
Portal Mikul News - Platform berita terpercaya
+
+
+
+
+
+ setValUsername(e.target.value.trim())}
+ onPaste={(e) => setValUsername(e.currentTarget.value.trim())}
+ onCopy={(e) => setValUsername(e.currentTarget.value.trim())}
+ />
+
+
+
+
+
+ setPassword(e.target.value)}
+ />
+
+
+
+
+
+
+
+
+ Beranda
+
+
+
+
+
+
+ {/*
+
+
+
+
Informasi Portal
+
Akses informasi terkini dan status permintaan informasi yang telah diajukan.
+
+
+
*/}
+
+ )}
- )}
+
);
}
diff --git a/components/landing-page/option.tsx b/components/landing-page/option.tsx
index 42670c5..512232d 100644
--- a/components/landing-page/option.tsx
+++ b/components/landing-page/option.tsx
@@ -21,35 +21,98 @@ const Option = ({ Icon, title, selected, setSelected, open, notifs, active }: Op
onClick={() => setSelected?.(title)}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
- className={`relative flex h-10 w-full items-center rounded-md transition-colors cursor-pointer ${isActive ? "bg-slate-400 text-black" : "text-black hover:bg-slate-100"}`}
+ className={`relative flex h-12 w-full px-3 items-center rounded-xl transition-all duration-200 cursor-pointer group ${
+ isActive
+ ? "bg-gradient-to-r from-emerald-500 to-green-500 text-white shadow-lg shadow-emerald-500/25"
+ : "text-slate-600 hover:bg-gradient-to-r hover:from-slate-100 hover:to-slate-200/50 hover:text-slate-800"
+ }`}
+ whileHover={{ scale: 1.02 }}
+ whileTap={{ scale: 0.98 }}
>
-
-
+ {/* Active indicator */}
+ {isActive && (
+
+ )}
+
+
+
+
+
{open && (
-
- {title}
-
- )}
-
- {!open && hovered && (
-
{title}
)}
+ {/* Tooltip for collapsed state */}
+ {!open && hovered && (
+
+
+ {title}
+ {/* Tooltip arrow */}
+
+
+
+ )}
+
+ {/* Notification badge */}
{notifs && open && (
-
+
{notifs}
)}
+
+ {/* Hover effect overlay */}
+ {hovered && !isActive && (
+
+ )}
);
};
diff --git a/components/landing-page/retracting-sidedar.tsx b/components/landing-page/retracting-sidedar.tsx
index dfcbdc1..8353e97 100644
--- a/components/landing-page/retracting-sidedar.tsx
+++ b/components/landing-page/retracting-sidedar.tsx
@@ -1,6 +1,6 @@
"use client";
-import React, { Dispatch, SetStateAction, useState } from "react";
+import React, { Dispatch, SetStateAction, useState, useEffect } from "react";
import Image from "next/image";
import { Icon } from "@iconify/react";
@@ -8,7 +8,8 @@ import Link from "next/link";
import DashboardContainer from "../main/dashboard/dashboard-container";
import { usePathname } from "next/navigation";
import Option from "./option";
-import { motion } from "framer-motion";
+import { motion, AnimatePresence } from "framer-motion";
+import { useTheme } from "../layout/theme-context";
interface RetractingSidebarProps {
sidebarData: boolean;
@@ -17,7 +18,7 @@ interface RetractingSidebarProps {
const sidebarSections = [
{
- title: "DashBoard",
+ title: "Dashboard",
items: [
{
title: "Dashboard",
@@ -29,15 +30,15 @@ const sidebarSections = [
],
},
{
- title: "Apps",
+ title: "Content Management",
items: [
{
- title: "Artikel",
+ title: "Articles",
icon: () => ,
link: "/admin/article",
},
{
- title: "Kategori",
+ title: "Categories",
icon: () => ,
link: "/admin/master-category",
},
@@ -47,7 +48,7 @@ const sidebarSections = [
// link: "/admin/magazine",
// },
{
- title: "Advertise",
+ title: "Advertisements",
icon: () => ,
link: "/admin/advertise",
},
@@ -59,15 +60,15 @@ const sidebarSections = [
],
},
{
- title: "Master",
+ title: "System",
items: [
{
- title: "Master Static Page",
+ title: "Static Pages",
icon: () => ,
link: "/admin/static-page",
},
{
- title: "Master User",
+ title: "User Management",
icon: () => ,
link: "/admin/master-user",
},
@@ -80,43 +81,94 @@ export const RetractingSidebar = ({
updateSidebarData,
}: RetractingSidebarProps) => {
const pathname = usePathname();
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ if (!mounted) {
+ return null;
+ }
return (
<>
{/* DESKTOP SIDEBAR */}
-
-
-
-
- {/* MOBILE SIDEBAR */}
- {sidebarData && (
-
+
- {/* */}
-
- )}
+
+
+
+ {/* Desktop Toggle Button - appears when sidebar is collapsed */}
+
+ {!sidebarData && (
+ updateSidebarData(true)}
+ >
+
+
+ )}
+
+
+ {/* Mobile Toggle Button */}
+
+ {!sidebarData && (
+ updateSidebarData(true)}
+ >
+
+
+ )}
+
+
+ {/* MOBILE SIDEBAR */}
+
+ {sidebarData && (
+
+ {/* */}
+
+
+ )}
+
>
);
};
@@ -130,130 +182,212 @@ const SidebarContent = ({
pathname: string;
updateSidebarData: (newData: boolean) => void;
}) => {
+ const { theme, toggleTheme } = useTheme();
return (
- <>
- {/* BAGIAN ATAS */}
-
- {!open && (
-
-
-
- )}
-
-
-
-

-
- {/* {open && (
-
- )} */}
- {open && (
-
- )}
-
-
-
- {sidebarSections.map((section) => (
-
-
{section.title}
- {section.items.map((item) => (
-
-
-
- ))}
-
- ))}
-
-
-
- {/* BAGIAN BAWAH */}
-
-