Skip to content

Commit

Permalink
fix-#16: Support Dark theme based on the web browser's theme (#62)
Browse files Browse the repository at this point in the history
Added Dark theme support for the entire application based on the browser's default theme
  • Loading branch information
SankalpHaritash21 authored Nov 30, 2023
1 parent eb4691c commit 91567b1
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 84 deletions.
18 changes: 11 additions & 7 deletions frontend/src/components/blog-feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function BlogFeed() {
<div className="container mx-auto py-6">
<div className="-mx-4 flex flex-wrap">
<div className="w-full p-4 md:w-2/3">
<h1 className="mb-4 text-2xl font-semibold">
<h1 className="mb-4 text-2xl font-semibold dark:text-white">
{selectedCategory === 'featured'
? 'Featured Posts'
: `Posts related to "${selectedCategory}"`}
Expand All @@ -53,13 +53,15 @@ export default function BlogFeed() {
? Array(5)
.fill(0)
.map((_, index) => <FeaturedPostCardSkeleton key={index} />)
: posts.slice(0, 5).map((post, index) => <FeaturedPostCard key={index} post={post} />)}
: posts
.slice(0, 5)
.map((post, index) => <FeaturedPostCard key={index} post={post} />)}
</div>
</div>
<div className="w-full p-4 md:w-1/3">
<div className="mb-6">
<div className="text-gray-500">Discover by topic</div>
<h2 className="mb-4 text-2xl font-semibold">Categories</h2>
<div className="text-gray-500 dark:text-white">Discover by topic</div>
<h2 className="mb-4 text-2xl font-semibold dark:text-white">Categories</h2>
<div className="flex flex-wrap gap-2">
{CATEGORIES.map((category) => (
<button
Expand All @@ -79,14 +81,16 @@ export default function BlogFeed() {
</div>
</div>
<div>
<div className="text-gray-500">What's new ?</div>
<h2 className="mb-4 text-2xl font-semibold">Latest Posts</h2>
<div className="text-gray-500 dark:text-white">What's new ?</div>
<h2 className="mb-4 text-2xl font-semibold dark:text-white">Latest Posts</h2>
<div className="flex flex-col gap-2">
{latestPosts.length === 0
? Array(5)
.fill(0)
.map((_, index) => <LatestPostCardSkeleton key={index} />)
: latestPosts.slice(0, 5).map((post, index) => <LatestPostCard key={index} post={post} />)}
: latestPosts
.slice(0, 5)
.map((post, index) => <LatestPostCard key={index} post={post} />)}
</div>
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/featured-post-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function FeaturedPostCard({ post }: { post: Post }) {
const navigate = useNavigate();
return (
<div
className="flex h-48 cursor-pointer gap-4 rounded-lg bg-white"
className="flex h-48 cursor-pointer gap-4 rounded-lg bg-white p-2 dark:bg-dark-textfield"
onClick={() => navigate('/details-page', { state: { post } })}
>
<div className="w-1/3">
Expand All @@ -18,7 +18,7 @@ export default function FeaturedPostCard({ post }: { post: Post }) {
/>
</div>
<div className="flex h-full w-2/3 flex-col gap-2">
<div className="text-xl font-semibold">{post.title}</div>
<div className="text-xl font-semibold dark:text-white">{post.title}</div>
<div className="flex flex-wrap gap-2">
{post.categories.map((category, index) => (
<span key={index} className={categoryProps(category)}>
Expand All @@ -27,9 +27,9 @@ export default function FeaturedPostCard({ post }: { post: Post }) {
))}
</div>
<div className="line-clamp-2 text-gray-600">
<p className="overflow-ellipsis">{post.description}</p>
<p className="overflow-ellipsis dark:text-white">{post.description}</p>
</div>
<div className="mb-1 flex flex-1 items-end text-xs text-gray-500">
<div className="mb-1 flex flex-1 items-end text-xs text-gray-500 dark:text-white">
{post.authorName}{formatPostTime(post.timeOfPost)}
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/components/latest-post-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ export default function LatestPostCard({ post }: { post: Post }) {
const navigate = useNavigate();
return (
<div
className="cursor-pointer rounded-lg bg-white py-2 shadow-sm"
className="cursor-pointer rounded-lg bg-white p-2 py-2 shadow-sm dark:bg-dark-textfield"
onClick={() => navigate('/details-page', { state: { post } })}
>
<div className="flex">
<div className="mb-2 flex flex-1 flex-wrap gap-2">
<div className="mb-2 flex flex-1 flex-wrap gap-2 ">
{post.categories.map((category, index) => (
<span key={index} className={categoryProps(category)}>
{category}
</span>
))}
</div>
<img src={linkIcon} style={{ height: 12, width: 12 }} onClick={() => navigate(-1)} />
<img src={linkIcon} className="h-3 w-3" onClick={() => navigate(-1)} />
</div>
<div className="mb-2 line-clamp-2 text-xl font-semibold">{post.title}</div>
<div className="text-xs text-gray-500">
<div className="mb-2 line-clamp-2 text-xl font-semibold dark:text-white">{post.title}</div>
<div className="text-xs text-gray-500 dark:text-white">
{post.authorName}{formatPostTime(post.timeOfPost)}
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/components/post-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ export default function PostCard({ post }: { post: Post }) {
className="w-full cursor-pointer p-4 md:w-1/2 lg:w-1/3 xl:w-1/4"
onClick={() => navigate('/details-page', { state: { post } })}
>
<div className="rounded-lg bg-white shadow-md">
<div className="rounded-lg bg-white shadow-md dark:bg-dark-textfield">
<img
src={post.imageLink}
alt={post.title}
className="h-48 w-full rounded-lg object-cover"
/>
<div className="p-4">
<div className="mb-2 text-xs text-gray-500">
<div className="mb-2 text-xs text-gray-500 dark:text-white">
{post.authorName}{formatPostTime(post.timeOfPost)}
</div>
<h2 className="mb-2 line-clamp-1 text-xl font-semibold">{post.title}</h2>
<p className="line-clamp-2 text-gray-600">{post.description}</p>
<div className="mt-4 flex flex-wrap gap-2">
<h2 className="mb-2 line-clamp-1 text-xl font-semibold dark:text-white">{post.title}</h2>
<p className="line-clamp-2 text-gray-600 dark:text-white">{post.description}</p>
<div className="mt-4 flex flex-wrap gap-2 dark:text-black">
{post.categories.map((category, index) => (
<span key={index} className={categoryProps(category)}>
{category}
Expand Down
16 changes: 4 additions & 12 deletions frontend/src/components/ui/skeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import { cn } from "@/lib/utils"
import { cn } from '@/lib/utils';

function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn("animate-pulse rounded-md bg-muted", className)}
{...props}
/>
)
function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return <div className={cn('bg-muted animate-pulse rounded-md', className)} {...props} />;
}

export { Skeleton }
export { Skeleton };
9 changes: 8 additions & 1 deletion frontend/src/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind utilities;

@layer base {
:root {
--color-dark-background: #10172a;
--color-dark-textfield-card: #1d293c;
}
}
55 changes: 41 additions & 14 deletions frontend/src/pages/add-blog.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import axios from 'axios';
import { ChangeEvent, FormEvent, useState } from 'react';
import { ChangeEvent, FormEvent, useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import navigateBackBlackIcon from '@/assets/svg/navigate-back-black.svg';
import navigateBackWhiteIcon from '@/assets/svg/navigate-back-white.svg';
import { CATEGORIES } from '@/constants/categories';
import { categoryProps } from '@/utils/category-props';
import ModalComponent from '@/components/modal';

type FormData = {
title: string;
authorName: string;
Expand Down Expand Up @@ -101,17 +103,38 @@ function AddBlog() {
}
};
const navigate = useNavigate();

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

useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

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

mediaQuery.addListener(handleThemeChange);

return () => {
mediaQuery.removeListener(handleThemeChange);
};
}, []);

return (
<div className="bg-white p-4 px-16 font-[Poppins]">
<div className="min-h-screen bg-white p-4 px-16 font-[Poppins] dark:bg-dark">
<div className="mb-4 flex items-center justify-start">
<div className="w-fit cursor-pointer text-base text-black md:text-lg lg:text-2xl">
<div className="w-fit cursor-pointer text-base text-black md:text-lg lg:text-2xl">
<img
src={navigateBackBlackIcon}
style={{ height: 20, width: 40 }}
src={isDarkMode ? navigateBackWhiteIcon : navigateBackBlackIcon}
onClick={() => navigate(-1)}
className="h-5 w-10"
/>
</div>
<h2 className="ml-4 text-sm font-bold md:text-lg lg:text-2xl">Create Post</h2>
<h2 className="ml-4 text-sm font-bold dark:text-white md:text-lg lg:text-2xl">
Create Post
</h2>
</div>

<form onSubmit={handleSubmit}>
Expand All @@ -120,7 +143,7 @@ function AddBlog() {
type="text"
name="title"
placeholder="Title"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800 dark:bg-dark-textfield dark:text-white dark:placeholder:text-white"
value={formData.title}
onChange={handleInputChange}
/>
Expand All @@ -130,7 +153,7 @@ function AddBlog() {
type="text"
name="authorName"
placeholder="Author Name"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800 dark:bg-dark-textfield dark:text-white dark:placeholder:text-white"
value={formData.authorName}
onChange={handleInputChange}
/>
Expand All @@ -142,14 +165,14 @@ function AddBlog() {
id="imgtext"
name="imageLink"
placeholder="Image URL"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800 dark:bg-dark-textfield dark:text-white dark:placeholder:text-white"
value={formData.imageLink}
onChange={handleInputChange}
/>
</div>
<button
type="button"
className="rounded-lg bg-black px-3 text-white hover:bg-gray-800"
className="rounded-lg bg-black px-3 text-white hover:bg-gray-800 dark:bg-white dark:text-black"
onClick={() => {
setmodal(true);
}}
Expand All @@ -161,14 +184,16 @@ function AddBlog() {
<textarea
name="description"
placeholder="Description"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800"
className="w-full rounded-lg bg-gray-50 p-2 placeholder:text-gray-800 dark:bg-dark-textfield dark:text-white dark:placeholder:text-white"
value={formData.description}
onChange={handleInputChange}
/>
</div>

<div className="mb-4 flex flex-col items-center md:flex-row">
<label className="mb-2 block w-full font-semibold md:mr-8 md:w-fit">Categories</label>
<label className="mb-2 block w-full font-semibold dark:text-white md:mr-8 md:w-fit">
Categories
</label>
<div className="flex flex-wrap gap-2">
{CATEGORIES.map((category) => (
<span
Expand All @@ -189,7 +214,9 @@ function AddBlog() {

<div className="mb-4 flex items-center">
<label className="flex items-center">
<span className="text-base font-medium text-gray-800">Featured Post</span>
<span className="text-base font-medium text-gray-800 dark:text-white">
Featured Post
</span>
<input
type="checkbox"
name="isFeaturedPost"
Expand All @@ -202,7 +229,7 @@ function AddBlog() {

<button
type="submit"
className="flex w-full items-center justify-center rounded-lg bg-black p-2 text-base text-white hover:bg-gray-800 md:w-fit"
className="flex w-full items-center justify-center rounded-lg bg-black p-2 text-base text-white hover:bg-gray-800 dark:bg-white dark:text-black md:w-fit"
>
Create Blog
</button>
Expand Down
56 changes: 25 additions & 31 deletions frontend/src/pages/details-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,34 @@ const DetailsPage = () => {
const post: Post = state?.post;
const navigate = useNavigate();
return (
<div className="w-full font-[Poppins]">
<div className="relative flex flex-col">
<img
src={post.imageLink}
alt={post.title}
className="h-[360px] w-full object-cover md:h-[460px]"
/>
<div className="min-h-screen dark:bg-dark">
<div className="min-h-min w-full font-[Poppins] dark:bg-dark">
<div className="relative flex flex-col">
<img src={post.imageLink} alt={post.title} className="h-80 w-full object-cover md:h-96" />

<div className="absolute left-0 top-0 h-full w-full bg-black opacity-50"></div>
<div className="absolute top-16 w-full cursor-pointer justify-start px-4 text-lg text-white md:top-24 md:px-8 md:text-xl lg:px-16 lg:text-2xl">
<img
src={navigateBackWhiteIcon}
style={{ height: 20, width: 40 }}
onClick={() => navigate(-1)}
/>
</div>
<div className="absolute bottom-4 w-full px-4 text-white md:bottom-8 md:px-8 lg:bottom-16 lg:px-16">
<div className="mb-6 flex space-x-2">
{post.categories.map((category, index) => (
<div key={index} className="rounded-full bg-gray-500 px-3 py-1 text-sm text-white">
{category}
</div>
))}
<div className="absolute left-0 top-0 h-full w-full bg-black opacity-50"></div>
<div className="absolute top-16 w-full cursor-pointer justify-start px-4 text-lg text-white md:top-24 md:px-8 md:text-xl lg:px-16 lg:text-2xl">
<img src={navigateBackWhiteIcon} className="h-5 w-10" onClick={() => navigate(-1)} />
</div>
<div className="absolute bottom-4 w-full px-4 text-white md:bottom-8 md:px-8 lg:bottom-16 lg:px-16">
<div className="mb-6 flex space-x-2">
{post.categories.map((category, index) => (
<div key={index} className="rounded-full bg-gray-500 px-3 py-1 text-sm text-white">
{category}
</div>
))}
</div>
<h1 className="text-lg font-semibold md:text-2xl lg:text-4xl">{post.title}</h1>
</div>
<h1 className="text-lg font-semibold md:text-2xl lg:text-4xl">{post.title}</h1>
</div>
</div>
<div className="flex w-full flex-col gap-y-4 px-4 pt-4 text-left md:px-8 md:pt-8 lg:px-16 lg:pt-16">
<div>
<p className="text-gray-700">{post.description}</p>
</div>
<div className="">
<p className="font-semibold text-gray-600">By {post.authorName}</p>
<p className="text-sm">{formatPostTime(post.timeOfPost)}</p>
<div className="flex w-full flex-col gap-y-4 px-4 pt-4 text-left dark:text-white md:px-8 md:pt-8 lg:px-16 lg:pt-16">
<div>
<p className="text-gray-700 dark:text-white">{post.description}</p>
</div>
<div className="">
<p className="font-semibold text-gray-600 dark:text-white">By {post.authorName}</p>
<p className="text-sm">{formatPostTime(post.timeOfPost)}</p>
</div>
</div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/pages/home-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function HomePage() {
}, []);
const navigate = useNavigate();
return (
<div className="w-full font-[Poppins]">
<div className="w-full font-[Poppins] dark:bg-dark">
<div
style={{ backgroundImage: `url(${bg})` }}
className="relative mt-[-8px] h-[460px] bg-cover bg-fixed bg-center"
Expand All @@ -39,7 +39,7 @@ function HomePage() {
Create post
</button>
</div>
<div className="flex max-w-5xl flex-1 flex-col justify-end pb-8">
<div className="flex max-w-5xl flex-1 flex-col justify-end pb-8 dark:text-white">
<h1 className="text-4xl font-bold">Journey Beyond Horizons</h1>
<p className="my-4 text-xl">
Dive into the World of Travel with Stories That Transport You to Far-Off Lands.
Expand All @@ -51,7 +51,7 @@ function HomePage() {
</div>
<div className="px-16">
<BlogFeed />
<h1 className="text-2xl font-semibold">All Blog Posts</h1>
<h1 className="text-2xl font-semibold dark:text-white">All Blog Posts</h1>
<div className="-mx-4 flex flex-wrap">
{posts.length === 0
? Array(8)
Expand Down
Loading

1 comment on commit 91567b1

@vercel
Copy link

@vercel vercel bot commented on 91567b1 Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.