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

Solved the issue #128 #165

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
47 changes: 31 additions & 16 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useState, useEffect } from 'react'
import { useDispatch } from 'react-redux'
import './App.css'
import authService from "./appwrite/auth"
import { login, logout } from "./store/authSlice"
import authService from './appwrite/auth'
import { login, logout } from './store/authSlice'
import { Footer, Header } from './componenets'
import { Outlet } from 'react-router-dom'
import { Routes, Route, Outlet, Navigate } from 'react-router-dom'
import BackToTopButton from './components/ui/BackToTopButton'
import NotFound from './componenets/NotFound'

function App() {
const [loading, setLoading] = useState(true)
Expand All @@ -21,20 +22,34 @@ function App() {
}
})
.finally(() => setLoading(false))
}, [])
}, [dispatch])

return !loading ? (
<div className='custom-theme min-h-screen flex flex-wrap content-between '>
<div className='w-full block'>
<BackToTopButton />
<Header />
<main>
<Outlet />
</main>
<Footer />
</div>
if (loading) return null

return (
<div className='custom-theme min-h-screen flex flex-wrap content-between'>
<Routes>
{/* Public Routes with Header, Footer, and Outlet */}
<Route path="/" element={
<>
<BackToTopButton />
<Header />
<main>
<Outlet />
</main>
<Footer />
</>
}>
{/* Add other valid routes here */}
<Route path="home" element={<h1>Home Page</h1>} />
<Route path="profile" element={<h1>User Profile</h1>} />
</Route>

{/* Route for invalid URLs */}
<Route path="*" element={<NotFound />} />
</Routes>
</div>
) : null
)
}

export default App
export default App
171 changes: 68 additions & 103 deletions src/componenets/Header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,31 @@ import { Link } from "react-router-dom";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { Container, Logo, LogoutBtn } from "../index";
import { FaBars, FaTimes } from "react-icons/fa"; // For hamburger icon
import { FaBars, FaTimes, FaSun, FaMoon } from "react-icons/fa"; // Import icons

function Header() {
const authStatus = useSelector((state) => state.auth.status);
const navigate = useNavigate();

// State to track theme mode
const [isDarkMode, setIsDarkMode] = useState(false);
const [menuOpen, setMenuOpen] = useState(false); // State for hamburger menu
const [isSticky, setIsSticky] = useState(false); // State for sticky navbar
const [menuOpen, setMenuOpen] = useState(false);
const [isSticky, setIsSticky] = useState(false);

useEffect(() => {
const handleScroll = () => {
if (window.scrollY > window.innerHeight * 0.1) {
// 10vh
setIsSticky(true);
} else {
setIsSticky(false);
}
};

window.addEventListener("scroll", handleScroll);

return () => {
window.removeEventListener("scroll", handleScroll);
};
return () => window.removeEventListener("scroll", handleScroll);
}, []);

/* Toggle Text Color */
const toggleTextColor = () => {
const toggleTheme = () => {
const rootElement = document.getElementById("root");
// Toggle text color for the root
rootElement.classList.toggle("white-color");

const footerLinks = document.getElementsByClassName("toggle");
Expand All @@ -43,114 +36,89 @@ function Header() {
link.classList.toggle("text-alice-blue-900");
});

// Toggle background and text color for custom screen elements
const screenElements = document.querySelectorAll(".custom-theme");
screenElements.forEach((screenElement) => {
screenElement.classList.toggle("dark-mode-bg"); // Toggle background color
screenElement.classList.toggle("light-text"); // Toggle text color
screenElements.forEach((el) => {
el.classList.toggle("dark-mode-bg");
el.classList.toggle("light-text");
});

// Toggle between dark and light mode
setIsDarkMode(!isDarkMode);
};

const navItems = [
{
name: "Home",
slug: "/",
active: true,
},
{
name: "Login",
slug: "/login",
active: !authStatus,
},
{
name: "Signup",
slug: "/signup",
active: !authStatus,
},
{
name: "Profile",
slug: "/profile",
active: !authStatus,
},
{
name: "All Posts",
slug: "/all-posts",
active: authStatus,
},
{
name: "Add Post",
slug: "/add-post",
active: authStatus,
},
{ name: "Home", slug: "/", active: true },
{ name: "Login", slug: "/login", active: !authStatus },
{ name: "Signup", slug: "/signup", active: !authStatus },
{ name: "Profile", slug: "/profile", active: !authStatus },
{ name: "All Posts", slug: "/all-posts", active: authStatus },
{ name: "Add Post", slug: "/add-post", active: authStatus },
];

// Toggle the hamburger menu
const toggleMenu = () => setMenuOpen(!menuOpen);

return (
<>
<style>
{`
/* Initial navbar styles */
.header-custom-theme {
position: relative;
width: 100%;
transition: all 0.3s ease-in-out;
}

/* Sticky navbar styles */
.header-custom-theme.sticky {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 10;
background-color: #fff; /* Adjust as needed */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* Optional for shadow effect */
background-color: #fff;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.theme-icon {
font-size: 1.5rem;
color: #555;
cursor: pointer;
transition: color 0.3s;
}

.theme-icon:hover {
color: #007bff;
}
`}
</style>
<header
className={`custom-theme header-custom-theme py-3 shadow bg-gray-200 ${isSticky ? "sticky" : ""
}`}
>
<header className={`custom-theme header-custom-theme py-3 shadow bg-gray-200 ${isSticky ? "sticky" : ""}`}>
<Container>
<nav className='flex justify-between items-center p-2'>
<div className='mr-4 ml-10'>
<Link to='/'>
<Logo width='70px' />
<nav className="flex justify-between items-center p-2">
<div className="mr-4 ml-10">
<Link to="/">
<Logo width="70px" />
</Link>
</div>

{/* Hamburger Icon for smaller screens */}
<button className='text-2xl md:hidden' onClick={toggleMenu}>
<button className="text-2xl md:hidden" onClick={toggleMenu}>
{menuOpen ? <FaTimes /> : <FaBars />}
</button>

{/* Navbar items for large screens */}
<ul className='hidden md:flex ml-auto'>
<ul className="hidden md:flex ml-auto">
<li>
<button
onClick={toggleTextColor}
className='inline-block px-6 py-2 duration-200 hover:bg-blue-100 rounded-full'
>
{isDarkMode ? "LightMode" : "DarkMode"}
<button onClick={toggleTheme} className="inline-block p-2">
{isDarkMode ? <FaSun className="theme-icon" /> : <FaMoon className="theme-icon" />}
</button>
</li>
{navItems.map((item) =>
item.active ? (
<li key={item.name}>
<button
onClick={() => navigate(item.slug)}
className='inline-block px-6 py-2 duration-200 hover:bg-blue-100 rounded-full'
>
{item.name}
</button>
</li>
) : null
{navItems.map(
(item) =>
item.active && (
<li key={item.name}>
<button
onClick={() => navigate(item.slug)}
className="inline-block px-6 py-2 duration-200 hover:bg-blue-100 rounded-full"
>
{item.name}
</button>
</li>
)
)}
{authStatus && (
<li>
Expand All @@ -159,34 +127,31 @@ function Header() {
)}
</ul>

{/* Hamburger Menu items for small screens */}
{menuOpen && (
<ul className='md:hidden flex flex-col absolute top-16 right-0 bg-gray-200 w-full text-center shadow-lg z-10'>
<li className='p-4'>
<button
onClick={toggleTextColor}
className='inline-block px-6 py-2 duration-200 hover:bg-blue-100 rounded-full'
>
{isDarkMode ? "LightMode" : "DarkMode"}
<ul className="md:hidden flex flex-col absolute top-16 right-0 bg-gray-200 w-full text-center shadow-lg z-10">
<li className="p-4">
<button onClick={toggleTheme} className="inline-block p-2">
{isDarkMode ? <FaSun className="theme-icon" /> : <FaMoon className="theme-icon" />}
</button>
</li>
{navItems.map((item) =>
item.active ? (
<li key={item.name} className='p-4'>
<button
onClick={() => {
navigate(item.slug);
setMenuOpen(false); // Close menu after navigation
}}
className='inline-block px-6 py-2 duration-200 hover:bg-blue-100 rounded-full'
>
{item.name}
</button>
</li>
) : null
{navItems.map(
(item) =>
item.active && (
<li key={item.name} className="p-4">
<button
onClick={() => {
navigate(item.slug);
setMenuOpen(false);
}}
className="inline-block px-6 py-2 duration-200 hover:bg-blue-100 rounded-full"
>
{item.name}
</button>
</li>
)
)}
{authStatus && (
<li className='p-4'>
<li className="p-4">
<LogoutBtn />
</li>
)}
Expand Down
21 changes: 21 additions & 0 deletions src/componenets/NotFound/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

.not-found-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 70vh;
}
.not-found-img {
width: 400px;
}
.button {
padding: 10px 20px;
font-size: 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}

16 changes: 16 additions & 0 deletions src/componenets/NotFound/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import './index.css'
import {Link} from 'react-router-dom'
const NotFound = () => (
<div className="not-found-container">
<img
src="https://assets.ccbp.in/frontend/react-js/not-found-blog-img.png"
alt="not found"
className="not-found-img"
/>
<Link to="/">
<button className='Button'>Go Back Home</button>
</Link>
</div>
)

export default NotFound