Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat-#36 fix-#97: Adding theme toggle functionality for the entire app (#95) #95

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom';
import HomePage from '@/pages/home-page';
import AddBlog from '@/pages/add-blog';
import DetailsPage from '@/pages/details-page';
import ScrollToTop from '@/components/scroll-to-top';
function App() {
return (
<BrowserRouter>
<ScrollToTop />
<Routes>
<Route path="/">
<Route index element={<HomePage />} />
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/assets/svg/add-icon-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions frontend/src/assets/svg/moon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions frontend/src/assets/svg/sun.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/components/post-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function PostCard({ post }: { post: Post }) {
return (
<div className="w-full md:w-1/2 lg:w-1/3 xl:w-1/4">
<div
className="mr-8 mt-4 mb-4 cursor-pointer rounded-lg bg-light shadow-md dark:bg-dark-card"
className="mb-4 mr-8 mt-4 cursor-pointer rounded-lg bg-light shadow-md dark:bg-dark-card"
onClick={() => navigate(`/details-page/${slug}/${post._id}`, { state: { post } })}
>
<img
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/components/scroll-to-top.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

export default function ScrollToTop() {
const { pathname } = useLocation();

useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);

return null;
}
2 changes: 1 addition & 1 deletion frontend/src/components/skeletons/post-card-skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Skeleton } from '@/components/ui/skeleton';
export const PostCardSkeleton = () => {
return (
<div className="w-full md:w-1/2 lg:w-1/3 xl:w-1/4">
<div className="mr-8 mt-4 mb-4 rounded-lg bg-light shadow-md dark:bg-dark-card">
<div className="mb-4 mr-8 mt-4 rounded-lg bg-light shadow-md dark:bg-dark-card">
<Skeleton className="h-48 w-full rounded-lg bg-slate-200 dark:bg-slate-700" />
<div className="p-4">
<Skeleton className="mb-2 h-3 w-2/3 bg-slate-200 dark:bg-slate-700" />
Expand Down
47 changes: 47 additions & 0 deletions frontend/src/components/theme-toggle-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useEffect, useState } from 'react';
import Sun from '@/assets/svg/sun.svg';
import Moon from '@/assets/svg/moon.svg';
function ThemeToggle() {
const [isDarkTheme, setIsDarkTheme] = useState<boolean | null>(null);
const toggleTheme = () => {
setIsDarkTheme((prevTheme) => (prevTheme === null ? true : !prevTheme));
};
useEffect(() => {
const storedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
setIsDarkTheme(storedTheme === 'dark' || (!storedTheme && prefersDark) || null);
if (storedTheme === 'dark' || (!storedTheme && prefersDark)) {
document.documentElement.classList.add('dark');
}
}, []);

useEffect(() => {
if (isDarkTheme !== null) {
document.documentElement.classList.toggle('dark', isDarkTheme);

localStorage.setItem('theme', isDarkTheme ? 'dark' : 'light');
}
}, [isDarkTheme]);
return (
<div>
<button
className={`${
isDarkTheme ? 'bg-dark-theme-background' : 'bg-light-theme-background'
} flex h-8 w-16 cursor-pointer items-center justify-start rounded-full px-1 py-1`}
onClick={toggleTheme}
>
<div
className={` ${
isDarkTheme
? 'translate-x-8 bg-dark-theme-foreground'
: 'translate-x-0 bg-light-theme-foreground'
} h-6 w-6 rounded-full bg-black px-1 py-1 duration-300`}
>
<img src={`${isDarkTheme ? Moon : Sun}`} />
</div>
</button>
</div>
);
}

export default ThemeToggle;
19 changes: 3 additions & 16 deletions frontend/src/pages/add-blog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,23 +111,10 @@ function AddBlog() {
}
};
const navigate = useNavigate();

const [isDarkMode, setIsDarkMode] = useState(
window.matchMedia('(prefers-color-scheme: dark)').matches
);

const [isDarkMode, setIsDarkMode] = useState<boolean | null>(null);
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

const handleThemeChange = (event: MediaQueryListEvent) => {
setIsDarkMode(event.matches);
};

mediaQuery.addListener(handleThemeChange);

return () => {
mediaQuery.removeListener(handleThemeChange);
};
const storedTheme = localStorage.getItem('theme');
setIsDarkMode(storedTheme === 'dark');
}, []);

function Asterisk() {
Expand Down
36 changes: 27 additions & 9 deletions frontend/src/pages/home-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import BlogFeed from '@/components/blog-feed';
import PostCard from '@/components/post-card';
import Post from '@/types/post-type';
import { PostCardSkeleton } from '@/components/skeletons/post-card-skeleton';
import ThemeToggle from '@/components/theme-toggle-button';
import AddIcon from '@/assets/svg/add-icon-white.svg';

function HomePage() {
const navigate = useNavigate();
const [posts, setPosts] = useState<Post[]>([]);
Expand All @@ -30,15 +33,30 @@ function HomePage() {
<div className="absolute inset-0 bg-black opacity-50"></div>
<div className="absolute inset-0 flex flex-col px-8 py-8 text-slate-50 md:px-16">
<div className="flex w-full justify-between">
<div className="text-2xl font-semibold">WanderLust</div>
<button
className="rounded border border-slate-50 px-4 py-2 hover:bg-slate-500/25"
onClick={() => {
navigate('/add-blog');
}}
>
Create post
</button>
<div className="flex items-center justify-between text-2xl font-semibold">
WanderLust
</div>
<div className="flex justify-between px-2">
<div className="flex items-center justify-end px-2 py-2 md:px-20">
<ThemeToggle />
</div>
<button
className="hidden rounded border border-slate-50 px-4 py-2 hover:bg-slate-500/25 md:inline-block"
onClick={() => {
navigate('/add-blog');
}}
>
Create post
</button>
<button
className="px-2 py-2 hover:bg-slate-500/25 md:hidden"
onClick={() => {
navigate('/add-blog');
}}
>
<img className="h-10 w-10" src={AddIcon} />
</button>
</div>
</div>
<div className="mb-8 flex max-w-3xl flex-1 flex-col justify-end text-slate-50">
<h1 className="text-2xl font-bold md:text-4xl">Journey Beyond Horizons</h1>
Expand Down
6 changes: 5 additions & 1 deletion frontend/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const defaultTheme = require('tailwindcss/defaultTheme');

export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
darkMode: 'media',
darkMode: 'class',
theme: {
extend: {
colors: {
Expand All @@ -27,6 +27,10 @@ export default {
description: colors.slate[700],
info: colors.slate[500],
},
'light-theme-background': '#fae9b1',
'light-theme-foreground': '#f1c237',
'dark-theme-background': '#092e40',
'dark-theme-foreground': '#25a5e3',
},
fontFamily: {
sans: ['Poppins', ...defaultTheme.fontFamily.sans],
Expand Down