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

Implemented light and dark mode for essential components!! #138

Closed
Closed
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
40 changes: 21 additions & 19 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// eslint-disable-next-line no-unused-vars
import React from "react";
import { useState, useEffect } from "react";
import React, { useState, useEffect } from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import "./App.css";
import Navbar from "./Components/Navbar.jsx";
Expand All @@ -17,9 +15,9 @@ import AddRecipe from "./Pages/AddRecipe.jsx";
import OneRecipe from "./Pages/OneRecipe.jsx";
import UpdateRecipe from "./Pages/UpdateRecipe.jsx";


function App() {
const [showScroll, setShowScroll] = useState(false);
const [darkMode, setDarkMode] = useState(false); // Dark mode state

const handleScroll = () => {
if (window.scrollY > 200) {
Expand All @@ -29,6 +27,10 @@ function App() {
}
};

const toggleDarkMode = () => {
setDarkMode((prevMode) => !prevMode);
};

useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
Expand All @@ -37,7 +39,7 @@ function App() {
}, []);

return (
<main>
<main style={{ backgroundColor: darkMode ? "#2e2e2e" : "#fff", color: darkMode ? "#fff" : "#000" }}>
<ToastContainer
position="bottom-center"
autoClose={5000}
Expand All @@ -48,24 +50,24 @@ function App() {
pauseOnFocusLoss
draggable
pauseOnHover
theme="light"
theme={darkMode ? "dark" : "light"} // Update Toast theme
/>
<BrowserRouter>
<Navbar />
<Navbar darkMode={darkMode} toggleDarkMode={toggleDarkMode} /> {/* Pass darkMode and toggle */}
<Routes>
<Route path="/" element={<Landing />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
<Route path="/recipes" element={<Recipes key={"recipes"} type=""/>} />
<Route path="/mainmeals" element={<Recipes key={"Main-meal"} type="Main-meal"/>} />
<Route path="/smallbites" element={<Recipes key={"Small-bite"} type="Small-bite"/>} />
<Route path="/healthy" element={<Recipes key={"Healthy"} type="Healthy"/>} />
<Route path="/user/:id" element={<Dashboard />} />
<Route path="/user/:id/new/recipe" element={<AddRecipe />} />
<Route path="/user/:id/update/recipe" element={<UpdateRecipe />} />
<Route path="/recipe/:id" element={<OneRecipe/>} />
<Route path="/" element={<Landing darkMode={darkMode} />} />
<Route path="/login" element={<Login darkMode={darkMode} />} />
<Route path="/signup" element={<Signup darkMode={darkMode} />} />
<Route path="/recipes" element={<Recipes darkMode={darkMode} key={"recipes"} type=""/>} />
<Route path="/mainmeals" element={<Recipes darkMode={darkMode} key={"Main-meal"} type="Main-meal"/>} />
<Route path="/smallbites" element={<Recipes darkMode={darkMode} key={"Small-bite"} type="Small-bite"/>} />
<Route path="/healthy" element={<Recipes darkMode={darkMode} key={"Healthy"} type="Healthy"/>} />
<Route path="/user/:id" element={<Dashboard darkMode={darkMode} />} />
<Route path="/user/:id/new/recipe" element={<AddRecipe darkMode={darkMode} />} />
<Route path="/user/:id/update/recipe" element={<UpdateRecipe darkMode={darkMode} />} />
<Route path="/recipe/:id" element={<OneRecipe darkMode={darkMode} />} />
</Routes>
<Footer />
<Footer darkMode={darkMode} /> {/* Pass darkMode prop */}
</BrowserRouter>

{showScroll && <ScrollToTop />}
Expand Down
83 changes: 61 additions & 22 deletions frontend/src/Components/Cards.jsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,91 @@
// eslint-disable-next-line no-unused-vars
import React from "react";
import PropTypes from "prop-types"
import PropTypes from "prop-types";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowRight, faHeart, faShare } from "@fortawesome/free-solid-svg-icons";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";

// Cards Component for Creating Recipe Cards
const Cards = ({dish}) => {
const navigator = useNavigate()
const Cards = ({ dish, darkMode }) => {
const navigator = useNavigate();

// Checks if user is authenticated or not
const handleClick = async()=>{
const token = await JSON.parse(localStorage.getItem("tastytoken"))
if(token !== null){
navigator(`/recipe/${dish._id}`, {state: {dish}})
}else{
toast.info("Please Login First")
navigator("/login")
const handleClick = async () => {
const token = await JSON.parse(localStorage.getItem("tastytoken"));
if (token !== null) {
navigator(`/recipe/${dish._id}`, { state: { dish } });
} else {
toast.info("Please Login First");
navigator("/login");
}
}
};

return (
<div className="p-4 cursor-pointer" onClick={handleClick}>
<div className="border-2 border-gray-200 border-opacity-60 rounded-lg overflow-hidden">
<div
className="p-4 cursor-pointer"
onClick={handleClick}
style={{
backgroundColor: darkMode ? "#333" : "#fff", // Background changes based on darkMode
color: darkMode ? "#fff" : "#000", // Text color changes based on darkMode
borderRadius: "0.5rem", // Consistent rounded corners
boxShadow: darkMode ? "0 2px 10px rgba(0, 0, 0, 0.8)" : "0 2px 10px rgba(0, 0, 0, 0.1)", // Shadow effect based on darkMode
}}
>
<div
className="border-2 border-opacity-60 rounded-lg overflow-hidden"
style={{
borderColor: darkMode ? "#555" : "#ccc", // Border color changes based on darkMode
}}
>
<img
className="lg:h-48 md:h-36 w-full object-cover object-center"
src={dish.image}
alt={dish.name}
loading="lazy"
/>
<div className="p-6">
<h2 className="tracking-widest text-xs title-font font-medium text-gray-400 mb-1">
<h2
className="tracking-widest text-xs title-font font-medium mb-1"
style={{
color: darkMode ? "#bbb" : "#555", // Subtle text color change for dark mode
}}
>
{dish.type.join(", ")}
</h2>
<h1 className="title-font text-lg font-medium text-gray-900 mb-3">
<h1
className="title-font text-lg font-medium mb-3"
style={{
color: darkMode ? "#fff" : "#000", // Primary text color change
}}
>
{dish.name}
</h1>
<p className="leading-relaxed mb-3">
{dish.description.slice(0, 174)}
{dish.description.length>174? "...": null}
{dish.description.length > 174 ? "..." : null}
</p>
<div className="flex items-center flex-wrap ">
<span className="text-red-500 inline-flex items-center md:mb-2 lg:mb-0">Recipe <FontAwesomeIcon icon={faArrowRight} /></span>
<span className="text-gray-400 mr-3 inline-flex items-center lg:ml-auto md:ml-0 ml-auto leading-none text-sm pr-3 py-1 border-r-2 border-gray-200 cursor-pointer">
<FontAwesomeIcon icon={faHeart} className="mx-2 "/>
<div className="flex items-center flex-wrap">
<span className="text-red-500 inline-flex items-center md:mb-2 lg:mb-0">
Recipe <FontAwesomeIcon icon={faArrowRight} />
</span>
<span
className="mr-3 inline-flex items-center lg:ml-auto md:ml-0 ml-auto leading-none text-sm pr-3 py-1 border-r-2 cursor-pointer"
style={{
color: darkMode ? "#bbb" : "#777", // Icon and text color change for darkMode
borderColor: darkMode ? "#555" : "#ccc", // Border color changes based on darkMode
}}
>
<FontAwesomeIcon icon={faHeart} className="mx-2" />
{dish.likes}
</span>
<span className="text-gray-400 inline-flex items-center leading-none text-sm cursor-pointer">
<FontAwesomeIcon icon={faShare} className="mx-2 "/>
<span
className="inline-flex items-center leading-none text-sm cursor-pointer"
style={{
color: darkMode ? "#bbb" : "#777", // Icon and text color change for darkMode
}}
>
<FontAwesomeIcon icon={faShare} className="mx-2" />
{dish.share}
</span>
</div>
Expand All @@ -59,6 +97,7 @@ const Cards = ({dish}) => {

Cards.propTypes = {
dish: PropTypes.object.isRequired,
darkMode: PropTypes.bool.isRequired, // Added prop type for darkMode
};

export default Cards;
81 changes: 56 additions & 25 deletions frontend/src/Components/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "@fortawesome/free-brands-svg-icons";
import { Link, useLocation } from "react-router-dom";

const Footer = () => {
const Footer = ({ darkMode }) => {
const [showModal, setShowModal] = useState(false);
const [rating, setRating] = useState(0);
const [name, setName] = useState("");
Expand All @@ -23,9 +23,8 @@ const Footer = () => {
const handleSubmit = (e) => {
e.preventDefault(); // Prevent form from refreshing the page


// Check for mandatory fields
if (!name || !email || !message || rating === 0) {
// Check for mandatory fields
if (!name || !email || !message || rating === 0) {
alert("Name, Email, Message, and Rating are mandatory fields!");
return; // Exit the function if validation fails
}
Expand All @@ -38,7 +37,7 @@ const Footer = () => {
rating,
});

// Optionally, you can reset the form after submission
// Optionally, reset the form after submission
setName("");
setEmail("");
setMessage("");
Expand All @@ -50,47 +49,75 @@ const Footer = () => {
<div>
{path !== "/user" && (
<>
<footer className="text-gray-600 body-font">
<footer
className="body-font"
style={{
backgroundColor: darkMode ? "#333" : "#fff",
color: darkMode ? "#fff" : "#000"
}}
>
<div className="container px-5 py-8 mx-auto flex items-center sm:flex-row flex-col">
<span className="flex title-font font-bold items-center md:justify-start justify-center text-red-700">
<span className="ml-3 text-xl font-[Mrriweather]">TastyTrails</span>
<span
className="flex title-font font-bold items-center md:justify-start justify-center"
style={{ color: darkMode ? "#ff6347" : "#e53e3e" }} // Adjust brand color for dark mode
>
<span className="ml-3 text-xl font-[Merriweather]">
TastyTrails
</span>
</span>
<p className="text-sm text-gray-500 sm:ml-4 sm:pl-4 sm:border-l-2 sm:border-gray-200 sm:py-2 sm:mt-0 mt-4 sm:text-center">
<p className="text-sm sm:ml-4 sm:pl-4 sm:border-l-2 sm:border-gray-200 sm:py-2 sm:mt-0 mt-4 sm:text-center">
© {new Date().getFullYear()} TastyTrails Developer —
<Link
to="https://twitter.com/A_l_f_i_y_a"
className="text-gray-600 ml-1 sm:text-center"
className="ml-1"
rel="noopener noreferrer"
target="_blank"
style={{
color: darkMode ? "#e0e0e0" : "#4a4a4a", // Adjust link color based on mode
}}
>
@A_l_f_i_y_A
</Link>
</p>
<span className="inline-flex sm:ml-auto sm:mt-0 mt-4 justify-center sm:justify-start">
<Link
to={"https://www.instagram.com/alfiya.17.siddiq/"}
className="text-ref-500 text-red-700"
className="text-red-700"
>
<FontAwesomeIcon icon={faInstagramSquare} />
<FontAwesomeIcon
icon={faInstagramSquare}
style={{ color: darkMode ? "#ff6347" : "#e53e3e" }} // Adjust icon color
/>
</Link>
<Link
to={"https://www.linkedin.com/in/alfiya-siddique-987a59240/"}
className="ml-3 text-red-700"
>
<FontAwesomeIcon icon={faLinkedinIn} className="" />
<FontAwesomeIcon
icon={faLinkedinIn}
style={{ color: darkMode ? "#ff6347" : "#e53e3e" }} // Adjust icon color
/>
</Link>
<Link
to={"https://github.com/AlfiyaSiddique"}
className="ml-3 text-red-700"
>
<FontAwesomeIcon icon={faGithubSquare} />
<FontAwesomeIcon
icon={faGithubSquare}
style={{ color: darkMode ? "#ff6347" : "#e53e3e" }} // Adjust icon color
/>
</Link>
</span>

{/* Contact Us / Rate Us Button */}
<button
onClick={() => setShowModal(true)}
className="ml-4 py-2 px-4 bg-transparent border border-red-700 text-red-700 rounded hover:bg-red-700 hover:text-white"
className="ml-4 py-2 px-4 border rounded transition-all"
style={{
backgroundColor: "transparent",
borderColor: darkMode ? "#ff6347" : "#e53e3e",
color: darkMode ? "#ff6347" : "#e53e3e",
}}
>
Feedback
</button>
Expand All @@ -103,15 +130,15 @@ const Footer = () => {
<div className="bg-white p-6 rounded-lg w-full max-w-lg">
<h2 className="text-2xl font-bold mb-4">Feedback</h2>
<form className="space-y-4" onSubmit={handleSubmit}>
<div>
<div>
<label className="block text-gray-700">Name</label>
<input
type="text"
className="w-full px-4 py-2 border border-gray-300 rounded"
placeholder="Your Name"
value={name}
onChange={(e) => setName(e.target.value)} // Update name state
required // HTML5 required attribute
onChange={(e) => setName(e.target.value)}
required
/>
</div>

Expand All @@ -122,8 +149,8 @@ const Footer = () => {
className="w-full px-4 py-2 border border-gray-300 rounded"
placeholder="Your Email"
value={email}
onChange={(e) => setEmail(e.target.value)} // Update email state
required // HTML5 required attribute
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>

Expand All @@ -133,19 +160,21 @@ const Footer = () => {
className="w-full px-4 py-2 border border-gray-300 rounded"
placeholder="Your Message"
value={message}
onChange={(e) => setMessage(e.target.value)} // Update message state
required // HTML5 required attribute
onChange={(e) => setMessage(e.target.value)}
required
></textarea>
</div>

<div>
<label className="block text-gray-700">Rate Us</label>
<div className="flex text-2xl"> {/* Increased star size here */}
<div className="flex text-2xl">
{[1, 2, 3, 4, 5].map((star) => (
<span
key={star}
className={`cursor-pointer ${
rating >= star ? "text-yellow-400" : "text-gray-400"
rating >= star
? "text-yellow-400"
: "text-gray-400"
}`}
onClick={() => handleRating(star)}
>
Expand All @@ -154,7 +183,9 @@ const Footer = () => {
))}
</div>
{!rating && (
<p className="text-red-600 text-sm">Rating is required!</p>
<p className="text-red-600 text-sm">
Rating is required!
</p>
)}
</div>

Expand Down
Loading