Building a Social Media Theme Switcher Website using React

Abhishek GurjarAbhishek Gurjar
6 min read

Introduction

In this tutorial, we will build a Social Media Theme Switcher using React. This project demonstrates how to implement light and dark themes in a React application, making it ideal for users who want to toggle between different styles for improved user experience and accessibility.

Project Overview

This theme switcher project allows users to toggle between light and dark themes on a social media-like interface. The application switches the colors of the entire user interface, including the background, text, and button colors, based on the selected theme.

Features

  • Light/Dark Mode Toggle: Switch between light and dark modes to suit user preferences.

  • Responsive Design: Ensures the layout adjusts smoothly across different devices.

  • Persist Theme: The chosen theme is saved to localStorage, allowing users to maintain their preferred theme across sessions.

Technologies Used

  • React: For building the user interface and handling the theme switch functionality.

  • CSS: For styling the different themes and ensuring a responsive design.

  • localStorage: To persist the theme selection across sessions.

Project Structure

The project is structured as follows:

├── public
├── src
│   │  
│   ├── App.jsx
│   ├── App.css
│   ├── index.js
│   └── index.css
├── package.json
└── README.md

Key Components

  • App.jsx: Contain the theme switcher and manages the overall layout of the application.

  • App.css: Contains the styles for both light and dark themes.

Code Explanation

App Component

The App is have code of social media content and applies global styles based on the current theme.

import { useState } from "react";
import "./App.css";
import upLogo from "./assets/images/icon-up.svg";
import downLogo from "./assets/images/icon-down.svg";
import fbLogo from "./assets/images/icon-facebook.svg";
import igLogo from "./assets/images/icon-instagram.svg";
import twLogo from "./assets/images/icon-twitter.svg";
import ytLogo from "./assets/images/icon-youtube.svg";

const App = () => {
  const [isDarkMode, setIsDarkMode] = useState(false);

  const toggleTheme = () => {
    setIsDarkMode(!isDarkMode);
  };
  return (
    <>
      <div className={`body ${isDarkMode ? "light" : "dark"}`}>
        <div className="app">
          <div className="header">
            <div className="dashboard">
              <h1>Social Media Dashboard</h1>
              <p>Total Followers: 23,004</p>
            </div>
            <div className="mode">
              <p>{isDarkMode ? "Light Mode" : "Dark Mode"}</p>
              <div className="toggle-area">
                <div
                  onClick={toggleTheme}
                  className={`${
                    isDarkMode ? "left-toggle-btn" : "right-toggle-btn"
                  }`}
                ></div>
              </div>
            </div>
          </div>
          <div className="social-cards">
            <div className="social-card-section">
              <div className="card">
                <div className="user">
                  <img src={fbLogo} alt="logo" />
                  <p>@nathnaf</p>
                </div>
                <div className="follower">
                  <h1>1987</h1>
                  <p>FOLLOWERS</p>
                </div>
                <div className="view">
                  <img src={upLogo} alt="up" />
                  <p>12 Today</p>
                </div>
              </div>
              <div className="card">
                <div className="user">
                  <img src={twLogo} alt="logo" />
                  <p>@nathnaf</p>
                </div>
                <div className="follower">
                  <h1>1044</h1>
                  <p>FOLLOWERS</p>
                </div>
                <div className="view">
                  <img src={upLogo} alt="up" />
                  <p>99 Today</p>
                </div>
              </div>
            </div>
            <div className="social-card-section">
              <div className="card">
                <div className="user">
                  <img src={igLogo} alt="logo" />
                  <p>@nathnaf</p>
                </div>
                <div className="follower">
                  <h1>11k</h1>
                  <p>FOLLOWERS</p>
                </div>
                <div className="view">
                  <img src={upLogo} alt="up" />
                  <p>1987 Today</p>
                </div>
              </div>
              <div className="card">
                <div className="user">
                  <img src={ytLogo} alt="logo" />
                  <p>Nathan F</p>
                </div>
                <div className="follower">
                  <h1>8239</h1>
                  <p>SUBSCRIBER</p>
                </div>
                <div className="view down">
                  <img src={downLogo} alt="up" />
                  <p>144 Today</p>
                </div>
              </div>
            </div>
          </div>
          <div className="overView">
            <h1>Overview - Today</h1>
          </div>
          <div className="reach">
            <div className="analytics">
              <div className="section-a">
                <div className="a-card">
                  <div className="views">
                    <p>Page view</p>
                    <h1>87</h1>
                  </div>
                  <div className="logosImage">
                    <img src={fbLogo} alt="" />
                    <p>
                      <img src={upLogo} alt="" />
                      3%
                    </p>
                  </div>
                </div>
                <div className="a-card">
                  <div className="views">
                    <p>Likes</p>
                    <h1>52</h1>
                  </div>
                  <div className="logosImage">
                    <img src={fbLogo} alt="" />
                    <p>
                      <img src={upLogo} alt="" />
                      2%
                    </p>
                  </div>
                </div>
              </div>
              <div className="section-a">
                <div className="a-card">
                  <div className="views">
                    <p>Likes</p>
                    <h1>5462</h1>
                  </div>
                  <div className="logosImage">
                    <img src={igLogo} alt="" />
                    <p>
                      <img src={upLogo} alt="" />
                      2257%
                    </p>
                  </div>
                </div>
                <div className="a-card">
                  <div className="views">
                    <p>Page view</p>
                    <h1>52k</h1>
                  </div>
                  <div className="logosImage">
                    <img src={fbLogo} alt="" />
                    <p>
                      <img src={upLogo} alt="" />
                      1375%
                    </p>
                  </div>
                </div>
              </div>
            </div>
            <div className="analytics">
              <div className="section-a">
                <div className="a-card">
                  <div className="views">
                    <p>Retweets</p>
                    <h1>117</h1>
                  </div>
                  <div className="logosImage">
                    <img src={twLogo} alt="" />
                    <p>
                      <img src={upLogo} alt="" />
                      303%
                    </p>
                  </div>
                </div>
                <div className="a-card">
                  <div className="views">
                    <p>Likes</p>
                    <h1>507</h1>
                  </div>
                  <div className="logosImage">
                    <img src={fbLogo} alt="" />
                    <p>
                      <img src={upLogo} alt="" />
                      303%
                    </p>
                  </div>
                </div>
              </div>
              <div className="section-a">
                <div className="a-card">
                  <div className="views">
                    <p>Likes</p>
                    <h1>107</h1>
                  </div>
                  <div className="logosImage">
                    <img src={ytLogo} alt="" />
                    <p>
                      <img src={downLogo} alt="" />
                      19%
                    </p>
                  </div>
                </div>
                <div className="a-card">
                  <div className="views">
                    <p>Total Views</p>
                    <h1>1407</h1>
                  </div>
                  <div className="logosImage">
                    <img src={fbLogo} alt="" />
                    <p>
                      <img src={downLogo} alt="" />
                      12%
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <p>Made with ❤️ by Abhishek Gurjar</p>
        </div>
      </div>
    </>
  );
};

export default App;

CSS Styling

In the CSS file, we define styles for both the light and dark themes and apply them dynamically based on the body class.

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

.body {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Inter', sans-serif;
}

.app {
  width: 100%;
  display: flex;
  align-items: center;
  flex-direction: column;
}

.header {
  width: 100%;
  margin-block: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.dashboard h1 {
  font-size: 1.7rem;
  line-height: 0;
}

.dashboard p {
  font-size: 0.9rem;
  color: #8b97c6;
}

.mode {
  width: 50%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
}

.mode p {
  color: #8b97c6;
}

.toggle-area {
  width: 50px;
  height: 22px;
  border-radius: 20px;
  background: linear-gradient(90deg, hsl(210, 78%, 56%) 5%, hsl(146, 68%, 55%) 100%);
  display: flex;
  align-items: center;
}

.left-toggle-btn {
  background-color: #1f212e;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  margin-left: 29px;
}

.right-toggle-btn {
  margin-left: 1px;
  background-color: #1f212e;
  width: 18px;
  height: 18px;
  border-radius: 50%;
}

.social-cards {
  display: flex;
  align-items: center;
  gap: 30px;
}

.social-card-section {
  display: flex;
  align-items: center;
  gap: 30px;
}

.card {
  width: 280px;
  height: 240px;
  background-color: #252a41;
  border-radius: 8px;
  display: flex;
  align-items: center;
  flex-direction: column;
  transition: transform 0.3s ease-in-out;
}

.card:hover {
  transform: scale(1.1);
}

.user {
  display: flex;
  align-items: center;
  gap: 10px;
}

.follower {
  display: flex;
  align-items: center;
  flex-direction: column;
}

.follower h1 {
  font-size: 60px;
  line-height: 0;
}

.follower p {
  font-size: 16px;
  line-height: 0;
  color: rgb(98, 107, 174);
  letter-spacing: 2px;
}

.view {
  display: flex;
  align-items: center;
  gap: 4px;
}

.view img {
  width: 14px;
}

.view p {
  color: #1eb589;
}

.overView {
  width: 100%;
  margin-block: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 850px;
}

.overView h1 {
  font-size: 1.7rem;
}

.reach {
  display: flex;
  align-items: center;
  flex-direction: column;
  gap: 30px;
  margin-bottom: 100px;
}

.analytics {
  display: flex;
  align-items: center;
  gap: 30px;
}

.section-a {
  display: flex;
  align-items: center;
  gap: 30px;
}

.a-card {
  background-color: #252a41;
  width: 280px;
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  border-radius: 10px;
  gap: 30px;
  transition: transform 0.3s ease-in-out;
}

.a-card:hover {
  transform: scale(1.1);
}

.logosImage p {
  color: #1eb589;
}

.logosImage p img {
  width: 15px;
}

.down p {
  color: #dc414c;
}

@media (max-width: 1230px) {
  .social-card-section {
    flex-direction: column;
  }
  .section-a {
    flex-direction: column;
  }
  .overView {
    margin-right: 0;
  }
  .header {
    text-align: center;
    flex-direction: column;
  }
  .mode {
    justify-content: center;
  }
}

@media (max-width: 660px) {
  .social-cards {
    flex-direction: column;
  }
  .analytics {
    flex-direction: column;
  }
}

/* Light Mode */

.body.light .card {
  background-color: #f0f2fa;
}

.body.light .a-card {
  background-color: #f0f2fa;
}

.body.light .toggle-area {
  background: #aeb3cb;
}

.body.light {
  background-color: white;
  color: black;
}

.body.dark {
  background-color: #1f212e;
  color: white;
}

Installation and Usage

To get started with this project, clone the repository and install the necessary dependencies:

git clone https://github.com/abhishekgurjar-in/Social-Media-Theme-Switcher.git
cd social-media-theme-switcher
npm install
npm start

This will start the development server and open the application in your default web browser.

Live Demo

Check out the live demo of the Social Media Theme Switcher here.

Conclusion

The Social Media Theme Switcher is a great project to learn about handling user preferences in React and storing data in localStorage. You can extend this project by adding more themes or applying different styles for each theme.

Credits

  • Inspiration: This project was inspired by modern social media platforms that offer a theme toggle feature to enhance the user experience.

Author

Abhishek Gurjar is a dedicated web developer passionate about building accessible and user-friendly web applications. Check out more of his work on GitHub.

1
Subscribe to my newsletter

Read articles from Abhishek Gurjar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abhishek Gurjar
Abhishek Gurjar

I’m Abhishek Gurjar, a Full Stack MERN developer specializing in MongoDB, Express.js, React, and Node.js. I love creating dynamic web apps and sharing insights on web development.