Skip to content

Commit

Permalink
fix themes
Browse files Browse the repository at this point in the history
  • Loading branch information
SakinduRansindu committed Nov 16, 2024
1 parent 4f7fb93 commit 8d80123
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 62 deletions.
1 change: 1 addition & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { NextConfig } from "next";

const nextConfig: NextConfig = {
output: process.env.NODE_ENV === 'production' ? 'export' : undefined,
trailingSlash: true,
images: {
unoptimized: true,
remotePatterns: [
Expand Down
20 changes: 12 additions & 8 deletions src/app/admin/admin-dashboard-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { MoonIcon, SunIcon } from "@heroicons/react/24/solid";
import LOGO_SMALL from "../../../public/Images/logo/RUR20_small.png";
import { useAuth } from "@/context/auth-provider";
import { useRouter } from "next/navigation";
import { IThemeContextType } from "@/interfaces/IThemeContext";

interface AdminDashboardLayoutProps {
children: ReactNode;
Expand Down Expand Up @@ -46,12 +47,13 @@ function Navbar({ className }: { className?: string }) {
const router = useRouter();
const [active, setActive] = useState<string | null>(null);

const [tougleTheme, currentTheme] = useContext<any>(ThemeContext);

const handleLogout = async () => {
await logOut();
router.push("/admin/");
const themeContext = useContext<IThemeContextType|null>(ThemeContext);
if (!themeContext) {
throw new Error("ThemeToggleButton must be used within a ThemeContext.Provider");
}
const { toggleTheme, theme } = themeContext;



return (
<div className={cn("fixed top-10 inset-x-0 max-w-2xl mx-auto z-50", className)}>
Expand All @@ -64,14 +66,16 @@ function Navbar({ className }: { className?: string }) {
<MenuItem setActive={setActive} active={null} link="/admin/dashboard/timeline" item="Timeline" />

<MenuItem setActive={setActive} active={null} link="/admin/dashboard/sponsors" item="Sponsors"/>

<MenuItem setActive={setActive} active={null} link="/admin/dashboard" item="Dashboard"/>

<MenuItem setActive={setActive} active={null} link="/admin/logout" item="Logout"/>
{user && <MenuItem setActive={setActive} active={null} link="/admin/logout" item="Logout"/>}

<button
onClick={()=>tougleTheme()}
onClick={toggleTheme}
className="border text-sm font-medium relative border-neutral-200 dark:border-white/[0.2] text-black dark:text-white px-4 py-2 rounded-full"
>
{currentTheme() === "dark" ? (
{theme == "dark" ? (
<SunIcon className="h-5 w-5" />
) : (
<MoonIcon className="h-5 w-5" />
Expand Down
84 changes: 42 additions & 42 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,71 @@
'use client'
'use client';

import localFont from "next/font/local";
import "./globals.css";
import React, { useCallback, useState } from "react";
import React, { useCallback, useEffect, useState } from "react";
import { AuthProvider } from "@/context/auth-provider";

import {ITheme, IThemeContextType} from "@/interfaces/IThemeContext";

const geistSans = localFont({
src: "./fonts/GeistVF.woff",
variable: "--font-geist-sans",
weight: "100 900",
});

const geistMono = localFont({
src: "./fonts/GeistMonoVF.woff",
variable: "--font-geist-mono",
weight: "100 900",
});

export const ThemeContext = React.createContext<any>(null);
export const ThemeContext = React.createContext<IThemeContextType|null>(null);

export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
const DEFAULT_THEME = "dark";
const [theme, setThemeMode] = useState<ITheme>(DEFAULT_THEME);

export default function RootLayout({children}: Readonly<{ children: React.ReactNode }>) {
useEffect(() => {
const storedTheme = localStorage.getItem('theme') as ITheme;
if (storedTheme) {
setThemeMode(storedTheme);
} else {
localStorage.setItem('theme', DEFAULT_THEME);
setThemeMode(DEFAULT_THEME);
}
}, []);

const DEFAULT_THEME:'dark'|'light' = 'dark';
const [theme,setThemeMode] = useState<'dark'|'light'>(DEFAULT_THEME);

const currentTheme = ():'dark'|'light' => {
if (typeof window !== 'undefined') {
const t = localStorage.getItem('theme') as 'dark'|'light';
if(!t){
localStorage.setItem('theme',DEFAULT_THEME);
return DEFAULT_THEME;
} else {
return t;
}
}
return DEFAULT_THEME;
}
useEffect(() => {
document.documentElement.className = theme as ITheme;
}, [theme]);


const setTheme = useCallback((newTheme:'dark'|'light') => {
if(currentTheme()!==newTheme && currentTheme()!==null){
localStorage.setItem('theme',newTheme);
const setTheme = useCallback(
(newTheme: ITheme) => {
if (theme !== newTheme) {
localStorage.setItem('theme', newTheme);
setThemeMode(newTheme);
console.log('theme set to',newTheme);
}
},[]);

const tougleTheme = () => {
setThemeMode((prev) => prev === 'dark' ? 'light' : 'dark');
console.log('Theme set to', newTheme);
}
},
[theme]
);

const toggleTheme = useCallback(() => {
const newTheme = theme === 'dark' ? 'light' : 'dark';
setTheme(newTheme);
console.log('Toggled theme to', newTheme);
}, [theme, setTheme]);

return (
<AuthProvider>

<ThemeContext.Provider value={[setTheme,tougleTheme,currentTheme]}>
<html className={theme} lang="en">
<body className={`${geistSans.variable} ${geistMono.variable} dark:bg-dark-gradient bg-light-gradient antialiased`} >
<ThemeContext.Provider value={{ setTheme, toggleTheme, theme }}>
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} dark:bg-dark-gradient bg-light-gradient antialiased`}
>
{children}
</body>
</html>
</ThemeContext.Provider>

</html>
</ThemeContext.Provider>
</AuthProvider>
);


};


}
33 changes: 21 additions & 12 deletions src/components/ui/floating-navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import React, { useContext, useState } from "react";
import React, { use, useContext, useEffect, useState } from "react";
import {
motion,
AnimatePresence,
Expand All @@ -13,6 +13,7 @@ import { MoonIcon, SunIcon } from "@heroicons/react/24/solid";
import { ThemeContext } from "@/app/layout";
import LOGO_SMALL from "../../../public/Images/logo/RUR20_small.png";
import Image from "next/image";
import { IThemeContextType } from "@/interfaces/IThemeContext";


export const FloatingNav = ({
Expand Down Expand Up @@ -47,7 +48,14 @@ export const FloatingNav = ({
}
});

const [tougleTheme,currentTheme] = useContext<any>(ThemeContext);
const themeContext = useContext<IThemeContextType|null>(ThemeContext);

if (!themeContext) {
throw new Error("ThemeToggleButton must be used within a ThemeContext.Provider");
}

const { toggleTheme, theme } = themeContext;


return (
<AnimatePresence mode="wait">
Expand Down Expand Up @@ -92,16 +100,17 @@ export const FloatingNav = ({
</Link>
))}

<button
onClick={tougleTheme}
className="border text-sm font-medium relative border-neutral-200 dark:border-white/[0.2] text-black dark:text-white px-4 py-2 rounded-full"
>
{currentTheme === "dark" ? (
<SunIcon className="h-5 w-5" />
) : (
<MoonIcon className="h-5 w-5" />
)}
</button>
<button
onClick={toggleTheme}
className="border text-sm font-medium relative border-neutral-200 dark:border-white/[0.2] text-black dark:text-white px-4 py-2 rounded-full"
>
{theme === "dark" ? (
<SunIcon className="h-5 w-5" />
) : (
<MoonIcon className="h-5 w-5" />
)}
</button>


{/* <button className="border text-sm font-medium relative border-neutral-200 dark:border-white/[0.2] text-black dark:text-white px-4 py-2 rounded-full">
<span>Login</span>
Expand Down
7 changes: 7 additions & 0 deletions src/interfaces/IThemeContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type ITheme = 'dark' | 'light';

export interface IThemeContextType {
theme: ITheme;
toggleTheme: () => void;
setTheme: (newTheme: 'dark' | 'light') => void;
}

0 comments on commit 8d80123

Please sign in to comment.