feat: added animations and navbar goodies

This commit is contained in:
mike 2024-10-22 07:40:36 -04:00
parent 88d1556f78
commit 088df9c4ee
5 changed files with 195 additions and 67 deletions

View file

@ -1,26 +1,32 @@
// src/App.jsx // src/App.jsx
import React from 'react'; import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Header from './components/Header'; import Header from './components/Header';
import Footer from './components/Footer'; import Footer from './components/Footer';
import Home from './components/Home'; import Home from './components/Home';
import About from './components/About'; import About from './components/About';
import Roadmap from './components/Roadmap'; import Roadmap from './components/Roadmap';
const App = () => ( const App = () => {
<Router> const [menuOpen, setMenuOpen] = useState(false);
<Header />
<main> const handleMenuToggle = (isOpen) => {
<Routes> setMenuOpen(isOpen);
<Route path="/" element={<Home />} /> };
<Route path="/about" element={<About />} />
<Route path="/roadmap" element={<Roadmap />} /> return (
</Routes> <Router>
</main> <Header onMenuToggle={handleMenuToggle} />
<Footer /> <main className={`page-content ${menuOpen ? 'dropdown-active' : ''}`}>
</Router> <Routes>
); <Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/roadmap" element={<Roadmap />} />
</Routes>
</main>
<Footer />
</Router>
);
};
export default App; export default App;

View file

@ -22,3 +22,29 @@
transform: scaleX(1); transform: scaleX(1);
transform-origin: bottom left; transform-origin: bottom left;
} }
/* Header.css */
@keyframes dropdown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-dropdown {
animation: dropdown 0.5s ease-in-out;
}
.page-content {
transition: margin-top 0.5s ease-in-out;
}
.page-content.dropdown-active {
margin-top: 150px;
/* Adjust based on the height of the dropdown menu */
}

View file

@ -1,17 +1,41 @@
import { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import './Header.css'; // Import the custom CSS file import './Header.css'; // Import the custom CSS file
const Header = () => ( const Header = ({ onMenuToggle }) => {
<header className="bg-gray-900 text-white p-4 flex justify-between items-center"> const [isOpen, setIsOpen] = useState(false);
<div className="text-2xl font-bold">
<Link to="/" className="relative ">DoTechBro.org</Link> const toggleMenu = () => {
</div> setIsOpen(!isOpen);
<nav className="space-x-4"> onMenuToggle(!isOpen);
<Link to="/" className="relative link-underline">Home</Link> };
<Link to="/about" className="relative link-underline">About</Link>
<Link to="/roadmap" className="relative link-underline">Roadmaps</Link> return (
</nav> <header className="bg-gray-900 text-white p-4 flex justify-between items-center relative">
</header> <div className="text-2xl font-bold">
); <Link to="/" className="relative">DoTechBro.org</Link>
</div>
<div className="md:hidden">
<button onClick={toggleMenu} className="focus:outline-none">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d={isOpen ? "M6 18L18 6M6 6l12 12" : "M4 6h16M4 12h16m-7 6h7"}></path>
</svg>
</button>
</div>
<nav className="hidden md:flex md:space-x-4">
<Link to="/" className="link-underline">Home</Link>
<Link to="/about" className="link-underline">About</Link>
<Link to="/roadmap" className="link-underline">Roadmaps</Link>
</nav>
{isOpen && (
<div className="absolute top-full left-0 w-full bg-gray-900 text-white flex flex-col items-center md:hidden animate-dropdown">
<Link to="/" className="block py-2 link-underline" onClick={toggleMenu}>Home</Link>
<Link to="/about" className="block py-2 link-underline" onClick={toggleMenu}>About</Link>
<Link to="/roadmap" className="block py-2 link-underline" onClick={toggleMenu}>Roadmaps</Link>
</div>
)}
</header>
);
};
export default Header; export default Header;

23
src/components/Home.css Normal file
View file

@ -0,0 +1,23 @@
/* Home.css */
.page-content {
transition: margin-top 0.5s ease-in-out;
}
.page-content.dropdown-active {
margin-top: 150px;
/* Adjust based on the height of the dropdown menu */
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.animate-fade-in {
animation: fadeIn 1s ease-in-out forwards;
}

View file

@ -1,10 +1,40 @@
import { useState } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import FeaturedRoadmaps from './FeaturedRoadmaps'; import FeaturedRoadmaps from './FeaturedRoadmaps';
import MailingListDialog from './MailingListDialog'; import MailingListDialog from './MailingListDialog';
import roadmaps from '../roadmaps.json'; import roadmaps from '../roadmaps.json';
import './Home.css'; // Import the custom CSS file
const Home = () => { const Home = () => {
const [dialogOpen, setDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
const sectionsRef = useRef([]);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-fade-in');
}
});
},
{ threshold: 0.1 }
);
sectionsRef.current.forEach((section) => {
if (section) {
observer.observe(section);
}
});
return () => {
sectionsRef.current.forEach((section) => {
if (section) {
observer.unobserve(section);
}
});
};
}, []);
const handleDialogOpen = () => { const handleDialogOpen = () => {
setDialogOpen(true); setDialogOpen(true);
@ -14,51 +44,70 @@ const Home = () => {
setDialogOpen(false); setDialogOpen(false);
}; };
const handleMenuToggle = (isOpen) => {
setMenuOpen(isOpen);
};
return ( return (
<div className="flex flex-col items-center justify-center w-full"> <div className={`page-content ${menuOpen ? 'dropdown-active' : ''}`}>
<div className="w-full p-8 flex flex-col md:flex-row items-center justify-center min-h-screen bg-gray-100"> <div className="flex flex-col items-center justify-center w-full">
<div className="md:w-1/2 flex flex-col items-center text-center"> <div
<h2 className="text-6xl font-bold leading-tight"> className="w-full p-8 flex flex-col md:flex-row items-center justify-center min-h-screen bg-gray-100 opacity-0"
Pivot into <span className="text-green-600">tech.</span> ref={(el) => (sectionsRef.current[0] = el)}
<br /> >
<span className="font-semibold">with a head start</span> <div className="md:w-1/2 flex flex-col items-center text-center">
</h2> <h2 className="text-6xl font-bold leading-tight">
<p className="mt-4 text-lg max-w-2xl"> Pivot into <span className="text-green-600">tech.</span>
Empowering minorities to overcome barriers and succeed in the tech industry with confidence. <br />
<span className="font-semibold">with a head start</span>
</h2>
<p className="mt-4 text-lg max-w-2xl">
Empowering minorities to overcome barriers and succeed in the tech industry with confidence.
</p>
<button
className="mt-8 px-6 py-3 bg-green-600 text-white text-lg font-semibold rounded hover:bg-green-700 transition duration-300"
onClick={handleDialogOpen}
>
Start Today
</button>
</div>
<div className="mt-8 md:mt-0 md:w-1/2 flex justify-center">
<img src="/hero-logo.png" alt="Tech illustration" className="w-full max-w-md rounded-lg shadow-lg" />
</div>
</div>
<div
className="w-full bg-gray-900 text-white py-16 opacity-0"
ref={(el) => (sectionsRef.current[1] = el)}
>
<FeaturedRoadmaps roadmaps={roadmaps} />
</div>
<div
className="w-full p-8 bg-white text-center my-16 opacity-0"
ref={(el) => (sectionsRef.current[2] = el)}
>
<h2 className="text-4xl font-bold mb-8">Testimonials</h2>
<p className="text-lg">Coming soon...</p>
</div>
<div
className="w-full p-8 bg-gray-900 text-white text-center opacity-0"
ref={(el) => (sectionsRef.current[3] = el)}
>
<h2 className="text-4xl font-bold mb-8">Join Our Community</h2>
<p className="text-lg max-w-2xl mx-auto">
Connect with like-minded individuals, share your journey, and get support from our community.
</p> </p>
<button onClick={handleDialogOpen} className="mt-8 px-6 py-3 bg-green-600 text-white text-lg font-semibold rounded hover:bg-green-700 transition duration-300"> <button className="mt-8 px-6 py-3 bg-green-600 text-white text-lg font-semibold rounded hover:bg-green-700 transition duration-300">
Start Today Join Now
</button> </button>
</div> </div>
<div className="mt-8 md:mt-0 md:w-1/2 flex justify-center">
<img src="/hero-logo.png" alt="Tech illustration" className="w-full max-w-md rounded-lg shadow-lg" />
</div>
</div>
<div className="w-full bg-gray-900 text-white py-16"> <MailingListDialog open={dialogOpen} onClose={handleDialogClose} />
<FeaturedRoadmaps roadmaps={roadmaps} />
</div> </div>
<div className="w-full p-8 bg-white text-center my-16">
<h2 className="text-4xl font-bold mb-8">Testimonials</h2>
<p className="text-lg">Coming soon...</p>
</div>
<div className="w-full p-8 bg-gray-900 text-white text-center">
<h2 className="text-4xl font-bold mb-8">Join Our Community</h2>
<p className="text-lg max-w-2xl mx-auto">
Connect with like-minded individuals, share your journey, and get support from our community.
</p>
<button
onClick={handleDialogOpen}
className="mt-8 px-6 py-3 bg-green-600 text-white text-lg font-semibold rounded hover:bg-green-700 transition duration-300">
Join Now
</button>
</div>
<MailingListDialog open={dialogOpen} onClose={handleDialogClose} />
</div> </div>
) );
}; };
export default Home; export default Home;