diff --git a/components/form/login.tsx b/components/form/login.tsx index 5736c86..1d063ff 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) { @@ -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 ( -
-
- - logo - +
+ {/* Left Side - Logo Section */} +
+
+
+
+ +
+ Mikul News Logo +
+ +
+

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())} - /> - - -
- - Beranda - - - setIsResetPassword(false)} - > - Login - -
-
- ) : ( -
-
-
- 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 */} +
+ + Mikul News 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 45d544c..512232d 100644 --- a/components/landing-page/option.tsx +++ b/components/landing-page/option.tsx @@ -21,9 +21,9 @@ const Option = ({ Icon, title, selected, setSelected, open, notifs, active }: Op onClick={() => setSelected?.(title)} onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} - className={`relative flex h-12 w-full items-center rounded-xl transition-all duration-200 cursor-pointer group ${ + 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-blue-500 to-purple-500 text-white shadow-lg shadow-blue-500/25" + ? "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 }} @@ -94,7 +94,7 @@ const Option = ({ Icon, title, selected, setSelected, open, notifs, active }: Op transition={{ delay: 0.3, type: "spring" }} className={`absolute right-3 top-1/2 -translate-y-1/2 size-5 rounded-full text-xs font-semibold flex items-center justify-center ${ isActive - ? "bg-white text-blue-500" + ? "bg-white text-emerald-500" : "bg-red-500 text-white" }`} > diff --git a/components/landing-page/retracting-sidedar.tsx b/components/landing-page/retracting-sidedar.tsx index ba869b6..8353e97 100644 --- a/components/landing-page/retracting-sidedar.tsx +++ b/components/landing-page/retracting-sidedar.tsx @@ -9,6 +9,7 @@ import DashboardContainer from "../main/dashboard/dashboard-container"; import { usePathname } from "next/navigation"; import Option from "./option"; import { motion, AnimatePresence } from "framer-motion"; +import { useTheme } from "../layout/theme-context"; interface RetractingSidebarProps { sidebarData: boolean; @@ -97,7 +98,7 @@ export const RetractingSidebar = ({ updateSidebarData(true)} > @@ -155,7 +156,7 @@ export const RetractingSidebar = ({ animate={{ x: 0 }} exit={{ x: "-100%" }} transition={{ type: "tween", duration: 0.3 }} - className="fixed top-0 left-0 z-50 w-[280px] h-full bg-gradient-to-b from-slate-50 to-white p-4 flex flex-col md:hidden shadow-2xl backdrop-blur-sm" + className="fixed top-0 left-0 z-50 w-[280px] h-full bg-gradient-to-b from-slate-50 to-white dark:from-slate-800 dark:to-slate-900 p-4 flex flex-col md:hidden shadow-2xl backdrop-blur-sm" > {/* - )} + )} */}
- +
); }; diff --git a/components/layout/admin-layout.tsx b/components/layout/admin-layout.tsx index e041d41..69cdb5e 100644 --- a/components/layout/admin-layout.tsx +++ b/components/layout/admin-layout.tsx @@ -3,6 +3,7 @@ import { useEffect, useState } from "react"; import React, { ReactNode } from "react"; import { SidebarProvider } from "./sidebar-context"; +import { ThemeProvider } from "./theme-context"; import { Breadcrumbs } from "./breadcrumbs"; import { BurgerButtonIcon } from "../icons"; import { RetractingSidebar } from "../landing-page/retracting-sidedar"; @@ -31,103 +32,59 @@ export const AdminLayout = ({ children }: { children: ReactNode }) => { } return ( - -
-
- - - - - {/* Header */} - + +
+
+ + + + -
-
- - + {/* Header */} + +
+
+ + +
- - {/* Header Actions */} -
- {/* Notifications */} - -
- - - - -
-
-
- - {/* Search */} - -
- - - -
-
- - {/* Profile */} - -
- A -
-
-

Admin

-

admin@mikul.com

-
-
-
-
- + - {/* Main Content */} - -
- {children} -
-
- - + {/* Main Content */} + +
+ {children} +
+
+ + +
-
-
+ + ); }; diff --git a/components/layout/theme-context.tsx b/components/layout/theme-context.tsx new file mode 100644 index 0000000..b498a01 --- /dev/null +++ b/components/layout/theme-context.tsx @@ -0,0 +1,67 @@ +"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/main/dashboard/dashboard-container.tsx b/components/main/dashboard/dashboard-container.tsx index 5baadef..a562193 100644 --- a/components/main/dashboard/dashboard-container.tsx +++ b/components/main/dashboard/dashboard-container.tsx @@ -193,7 +193,7 @@ export default function DashboardContainer() { return (
{/* Stats Cards */} -
+
{/* User Profile Card */}
-
+
- - {/* Post Statistics Table */} - -
-

- Post Statistics by Region -

-
- - - - - - { - if (date) { - setPostContentDate((prev) => ({ - ...prev, - startDate: date, - })); - } - }} - maxDate={postContentDate.endDate} - inline - /> - - - to - - - - - - { - if (date) { - setPostContentDate((prev) => ({ - ...prev, - endDate: date, - })); - } - }} - minDate={postContentDate.startDate} - inline - /> - - -
-
- -
- - - - - - - - - - {postCount?.map((list) => ( - - - - - - ))} - -
NoRegionPosts
{list?.no}{list?.userLevelName} - {list?.totalArticle} -
-
-
); }