updated by claude
This commit is contained in:
parent
49b28ffbc6
commit
cb303cc61e
15 changed files with 1489 additions and 295 deletions
26
CLAUDE.md
Normal file
26
CLAUDE.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Development Guide
|
||||
|
||||
## Commands
|
||||
- **Start dev server**: `npm run dev`
|
||||
- **Build for production**: `npm run build`
|
||||
- **Lint code**: `npm run lint`
|
||||
- **Preview production build**: `npm run preview`
|
||||
|
||||
## Code Style Guidelines
|
||||
- **React Components**: Use functional components with hooks
|
||||
- **Imports**: Group imports by: React/libraries, components, styles/assets
|
||||
- **Formatting**: Use 2-space indentation, semicolons, single quotes
|
||||
- **Naming**:
|
||||
- Components: PascalCase (e.g., `Header.jsx`)
|
||||
- Functions/variables: camelCase
|
||||
- Files: Component files use .jsx extension
|
||||
- **CSS**: Use Tailwind utility classes with component-specific CSS when needed
|
||||
- **Error Handling**: Use try/catch blocks and provide user-friendly error messages
|
||||
- **Props**: Use destructuring for component props
|
||||
- **State Management**: Use React hooks (useState, useEffect) for component state
|
||||
|
||||
## Tech Stack
|
||||
- React 18 w/ functional components
|
||||
- React Router for navigation
|
||||
- Tailwind CSS for styling
|
||||
- Vite for build tool
|
|
@ -1,12 +1,168 @@
|
|||
const About = () => (
|
||||
<div className="p-8 flex flex-col items-center justify-center min-h-screen bg-gray-100">
|
||||
<h2 className="text-4xl font-bold text-center leading-tight">
|
||||
About Us
|
||||
</h2>
|
||||
<p className="mt-2 text-xs text-center text-gray-600">
|
||||
Do Tech Bro is dedicated to helping minorities, mainly African Americans, pivot into the tech field.
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const About = () => {
|
||||
return (
|
||||
<div className="bg-dark-900 text-white">
|
||||
{/* Hero Section */}
|
||||
<section className="py-20 bg-gradient-to-b from-dark-800 to-dark-900">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="text-center max-w-3xl mx-auto">
|
||||
<h1 className="text-4xl md:text-5xl font-bold mb-6">Our Mission</h1>
|
||||
<p className="text-xl text-gray-300 leading-relaxed mb-8">
|
||||
DoTechBro is dedicated to empowering minorities, particularly African Americans, to
|
||||
successfully transition into the tech industry and thrive in their careers.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Vision Section */}
|
||||
<section className="py-16 bg-dark-800">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold mb-6 bg-gradient-to-r from-primary-500 to-secondary-500 bg-clip-text text-transparent">Our Vision</h2>
|
||||
<p className="text-gray-300 mb-6 leading-relaxed">
|
||||
We envision a tech industry that reflects the diversity of our society, where
|
||||
minorities have equal opportunities to innovate, lead, and succeed. Our goal is to
|
||||
bridge the gap by providing targeted resources, mentorship, and community support.
|
||||
</p>
|
||||
<p className="text-gray-300 leading-relaxed">
|
||||
By creating comprehensive roadmaps, curating high-quality learning materials, and
|
||||
fostering a supportive community, we aim to give underrepresented individuals the
|
||||
confidence and skills needed to thrive in technology careers.
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-dark-700 p-8 rounded-xl shadow-lg">
|
||||
<h3 className="text-2xl font-bold mb-4">Why We Started</h3>
|
||||
<p className="text-gray-300 mb-4">
|
||||
The tech industry has a well-documented diversity problem. Despite making up 13.4% of the
|
||||
U.S. population, Black Americans represent only about 7% of the computing workforce.
|
||||
We believe this isn't due to lack of talent or interest, but rather barriers to entry and lack of tailored resources.
|
||||
</p>
|
||||
<p className="text-gray-300">
|
||||
DoTechBro was created to address these challenges head-on by providing clear pathways
|
||||
into tech that acknowledge and overcome the unique obstacles minorities face.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* What We Do Section */}
|
||||
<section className="py-16 bg-gradient-to-b from-dark-900 to-dark-800">
|
||||
<div className="container mx-auto px-6">
|
||||
<h2 className="text-3xl font-bold text-center mb-12">What We Do</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div className="bg-dark-700 rounded-xl p-8 shadow-lg hover:shadow-xl transition-shadow duration-300">
|
||||
<div className="text-primary-500 text-3xl mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-3">Career Roadmaps</h3>
|
||||
<p className="text-gray-300">
|
||||
We create tailored roadmaps for various tech career paths, breaking down complex journeys into manageable steps with
|
||||
clear guidance and resources for each stage.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-dark-700 rounded-xl p-8 shadow-lg hover:shadow-xl transition-shadow duration-300">
|
||||
<div className="text-primary-500 text-3xl mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-3">Resource Curation</h3>
|
||||
<p className="text-gray-300">
|
||||
We curate high-quality learning resources, from tutorials to practice projects, saving you time and helping you
|
||||
focus on what actually works to build your skills.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-dark-700 rounded-xl p-8 shadow-lg hover:shadow-xl transition-shadow duration-300">
|
||||
<div className="text-primary-500 text-3xl mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-3">Community Building</h3>
|
||||
<p className="text-gray-300">
|
||||
We're building a supportive community where you can connect with others on similar journeys,
|
||||
share experiences, and get guidance from those who've succeeded.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Values */}
|
||||
<section className="py-16 bg-dark-800">
|
||||
<div className="container mx-auto px-6">
|
||||
<h2 className="text-3xl font-bold text-center mb-6">Our Values</h2>
|
||||
<p className="text-center text-gray-300 max-w-3xl mx-auto mb-12">
|
||||
These core principles guide everything we do at DoTechBro and shape how we serve our community.
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="bg-dark-700 rounded-lg p-6 border-l-4 border-primary-500">
|
||||
<h3 className="text-xl font-bold mb-2">Accessibility</h3>
|
||||
<p className="text-gray-300">
|
||||
We believe tech education should be accessible to everyone, regardless of background or prior experience.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-dark-700 rounded-lg p-6 border-l-4 border-primary-500">
|
||||
<h3 className="text-xl font-bold mb-2">Authenticity</h3>
|
||||
<p className="text-gray-300">
|
||||
We keep it real about the challenges of breaking into tech while providing actionable solutions.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-dark-700 rounded-lg p-6 border-l-4 border-primary-500">
|
||||
<h3 className="text-xl font-bold mb-2">Community</h3>
|
||||
<p className="text-gray-300">
|
||||
We believe in the power of community to overcome obstacles and accelerate growth.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-dark-700 rounded-lg p-6 border-l-4 border-primary-500">
|
||||
<h3 className="text-xl font-bold mb-2">Excellence</h3>
|
||||
<p className="text-gray-300">
|
||||
We're committed to providing high-quality resources that actually prepare you for success in the industry.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Call to Action */}
|
||||
<section className="py-20 bg-gradient-to-b from-dark-800 to-dark-900">
|
||||
<div className="container mx-auto px-6 text-center">
|
||||
<h2 className="text-3xl font-bold mb-6">Ready to Start Your Tech Journey?</h2>
|
||||
<p className="text-xl text-gray-300 mb-8 max-w-2xl mx-auto">
|
||||
Join our community today and take the first step toward your career in tech.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
<Link
|
||||
to="/roadmap"
|
||||
className="px-8 py-3 bg-primary-600 hover:bg-primary-700 text-white rounded-lg shadow-lg transition-colors"
|
||||
>
|
||||
Explore Roadmaps
|
||||
</Link>
|
||||
<Link
|
||||
to="/"
|
||||
className="px-8 py-3 border-2 border-primary-500 text-primary-400 hover:bg-primary-500/10 rounded-lg transition-colors"
|
||||
>
|
||||
Join Our Community
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default About;
|
|
@ -1,31 +1,72 @@
|
|||
import React, { useState } from 'react';
|
||||
|
||||
const Accordion = ({ items }) => {
|
||||
const [openIndex, setOpenIndex] = useState(null);
|
||||
const [openIndex, setOpenIndex] = useState(0); // Start with first item open
|
||||
|
||||
const toggleItem = (index) => {
|
||||
setOpenIndex(openIndex === index ? null : index);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full bg-white p-8 rounded-lg shadow-lg mb-16">
|
||||
<h3 className="text-2xl font-semibold text-center mb-4 text-gray-900">Conquering Challenges: Practical Tips for Diverse Talent</h3>
|
||||
<div className="w-full">
|
||||
{items.map((item, index) => (
|
||||
<div key={index} className="mb-4">
|
||||
<div
|
||||
key={index}
|
||||
className={`mb-4 border border-dark-600 rounded-lg overflow-hidden transition-all duration-300 ${
|
||||
openIndex === index ? 'shadow-lg' : 'shadow'
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
onClick={() => toggleItem(index)}
|
||||
className="w-full text-left text-lg font-semibold text-gray-800 bg-gray-100 p-4 rounded-lg shadow-md hover:bg-gray-300 transition duration-300"
|
||||
className={`w-full flex items-center justify-between text-left p-5 font-medium transition-colors ${
|
||||
openIndex === index
|
||||
? 'bg-dark-700 text-white'
|
||||
: 'bg-dark-800 text-gray-300 hover:bg-dark-700'
|
||||
}`}
|
||||
aria-expanded={openIndex === index}
|
||||
>
|
||||
{item.title}
|
||||
<span className="text-lg">{item.title}</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`h-5 w-5 transition-transform duration-300 ${openIndex === index ? 'transform rotate-180' : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
{openIndex === index && (
|
||||
<div className="mt-2 p-4 bg-gray-200 rounded-lg shadow-inner">
|
||||
<p className="text-gray-700">{item.content}</p>
|
||||
<p className="mt-2 text-gray-700 font-semibold">Solution:</p>
|
||||
<p className="text-gray-700">{item.solution}</p>
|
||||
|
||||
<div
|
||||
className={`overflow-hidden transition-all duration-300 ease-in-out ${
|
||||
openIndex === index ? 'max-h-96' : 'max-h-0'
|
||||
}`}
|
||||
>
|
||||
<div className="p-5 bg-dark-700 border-t border-dark-600">
|
||||
<p className="text-gray-300 mb-4">{item.content}</p>
|
||||
|
||||
<div className="mt-4 border-l-4 border-primary-500 pl-4">
|
||||
<p className="text-primary-400 font-semibold mb-2">Our Solution:</p>
|
||||
<p className="text-gray-300">{item.solution}</p>
|
||||
</div>
|
||||
|
||||
{item.resources && (
|
||||
<div className="mt-4 pt-4 border-t border-dark-600">
|
||||
<p className="text-white font-medium mb-2">Helpful Resources:</p>
|
||||
<ul className="list-disc list-inside text-primary-400 space-y-1">
|
||||
{item.resources.map((resource, i) => (
|
||||
<li key={i}>
|
||||
<a href={resource.url} className="hover:text-primary-300 transition-colors" target="_blank" rel="noopener noreferrer">
|
||||
{resource.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -9,17 +9,68 @@ const icons = {
|
|||
};
|
||||
|
||||
const FeaturedRoadmaps = ({ roadmaps }) => (
|
||||
<div className="p-8">
|
||||
<h2 className="text-4xl font-bold text-center mb-8">Featured Roadmaps</h2>
|
||||
<div className="flex flex-col md:flex-row justify-center items-center space-y-8 md:space-y-0 md:space-x-8">
|
||||
<div className="container mx-auto px-6 py-12">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-4">Featured Roadmaps</h2>
|
||||
<p className="text-lg text-gray-300 max-w-2xl mx-auto">
|
||||
Choose your tech path and follow our step-by-step guidance to build your career
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{roadmaps.map((roadmap, index) => (
|
||||
<Link key={index} to={`/roadmap/${roadmap.id}`} className="bg-white text-gray-900 p-8 rounded-lg shadow-lg w-full md:w-1/3 text-center transform transition-transform hover:scale-105">
|
||||
<FontAwesomeIcon icon={icons[roadmap.id]} className="text-green-600 text-4xl mb-4" />
|
||||
<h3 className="text-2xl font-semibold">{roadmap.title}</h3>
|
||||
<p className="mt-4">{roadmap.description}</p>
|
||||
<Link
|
||||
key={index}
|
||||
to={`/roadmap/${roadmap.id}`}
|
||||
className="feature-card bg-dark-700 rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-all duration-300"
|
||||
>
|
||||
<div className="p-1 bg-gradient-to-r from-primary-500 to-secondary-500">
|
||||
<div className="bg-dark-700 p-8 rounded-t-xl">
|
||||
<div className="flex justify-center items-center w-16 h-16 mx-auto mb-6 rounded-full bg-dark-800 text-primary-500">
|
||||
<FontAwesomeIcon icon={icons[roadmap.id]} className="text-3xl" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-center mb-3">{roadmap.title}</h3>
|
||||
<p className="text-gray-400 text-center mb-4">{roadmap.description}</p>
|
||||
<div className="mt-6 flex justify-center">
|
||||
<span className="inline-flex items-center text-primary-400 font-medium">
|
||||
Explore roadmap
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 ml-1" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fillRule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-8 py-4 bg-dark-600 text-center">
|
||||
<div className="flex justify-center space-x-2">
|
||||
{['Beginner', 'Intermediate', 'Advanced'].map((level, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className={`text-xs px-2 py-1 rounded-full ${
|
||||
i === 0 ? 'bg-primary-500/20 text-primary-300' :
|
||||
'bg-dark-500 text-gray-400'
|
||||
}`}
|
||||
>
|
||||
{level}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-12 text-center">
|
||||
<Link
|
||||
to="/roadmap"
|
||||
className="inline-flex items-center px-6 py-3 bg-dark-700 hover:bg-dark-600 text-white font-medium rounded-lg transition-colors duration-300"
|
||||
>
|
||||
View All Roadmaps
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 ml-2" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fillRule="evenodd" d="M10.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L12.586 11H5a1 1 0 110-2h7.586l-2.293-2.293a1 1 0 010-1.414z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -1,10 +1,95 @@
|
|||
// src/components/Footer.jsx
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const Footer = () => (
|
||||
<footer className="bg-gray-800 text-white p-4 text-center">
|
||||
<p>© {new Date().getFullYear()} Do Tech Bro. All rights reserved.</p>
|
||||
const Footer = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
return (
|
||||
<footer className="bg-dark-900 text-white py-12">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
{/* Logo and About */}
|
||||
<div className="col-span-1 md:col-span-1">
|
||||
<Link
|
||||
to="/"
|
||||
className="text-2xl font-bold bg-gradient-to-r from-primary-500 to-secondary-500 bg-clip-text text-transparent mb-4 block"
|
||||
>
|
||||
DoTechBro.org
|
||||
</Link>
|
||||
<p className="text-gray-400 mt-4">
|
||||
Empowering minorities to succeed in tech through community support and targeted resources.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Quick Links */}
|
||||
<div className="col-span-1">
|
||||
<h3 className="text-lg font-bold mb-4 text-white">Quick Links</h3>
|
||||
<ul className="space-y-2">
|
||||
<li>
|
||||
<Link to="/" className="text-gray-400 hover:text-primary-400 transition-colors">Home</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/about" className="text-gray-400 hover:text-primary-400 transition-colors">About</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/roadmap" className="text-gray-400 hover:text-primary-400 transition-colors">Roadmaps</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Roadmaps */}
|
||||
<div className="col-span-1">
|
||||
<h3 className="text-lg font-bold mb-4 text-white">Popular Roadmaps</h3>
|
||||
<ul className="space-y-2">
|
||||
<li>
|
||||
<Link to="/roadmap" className="text-gray-400 hover:text-primary-400 transition-colors">Web Development</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/roadmap" className="text-gray-400 hover:text-primary-400 transition-colors">Data Science</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/roadmap" className="text-gray-400 hover:text-primary-400 transition-colors">UI/UX Design</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Get in Touch */}
|
||||
<div className="col-span-1">
|
||||
<h3 className="text-lg font-bold mb-4 text-white">Get in Touch</h3>
|
||||
<div className="flex space-x-4 mt-4">
|
||||
<a href="#" className="text-gray-400 hover:text-primary-400 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" className="text-gray-400 hover:text-primary-400 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" className="text-gray-400 hover:text-primary-400 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" className="text-gray-400 hover:text-primary-400 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-gray-800 mt-8 pt-8 text-center">
|
||||
<p className="text-gray-400">
|
||||
© {currentYear} DoTechBro.org. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
|
@ -1,50 +1,50 @@
|
|||
/* src/components/Header.css */
|
||||
.link-underline {
|
||||
/* src/components/Header.css */
|
||||
.link-underline {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
font-weight: 500;
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
|
||||
.link-underline::after {
|
||||
.link-underline::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
bottom: -2px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #38a169;
|
||||
/* Darker green color */
|
||||
background-color: var(--color-primary);
|
||||
transform: scaleX(0);
|
||||
transform-origin: bottom right;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.link-underline:hover::after {
|
||||
.link-underline:hover::after {
|
||||
transform: scaleX(1);
|
||||
transform-origin: bottom left;
|
||||
}
|
||||
}
|
||||
|
||||
/* Header.css */
|
||||
@keyframes dropdown {
|
||||
/* Animations */
|
||||
@keyframes dropdown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.animate-dropdown {
|
||||
animation: dropdown 0.5s ease-in-out;
|
||||
}
|
||||
.animate-dropdown {
|
||||
animation: dropdown 0.3s ease;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
transition: margin-top 0.5s ease-in-out;
|
||||
}
|
||||
/* Responsive layout adjustments */
|
||||
.page-content {
|
||||
transition: margin-top 0.3s ease;
|
||||
}
|
||||
|
||||
.page-content.dropdown-active {
|
||||
margin-top: 150px;
|
||||
/* Adjust based on the height of the dropdown menu */
|
||||
}
|
||||
.page-content.dropdown-active {
|
||||
margin-top: 12rem;
|
||||
}
|
|
@ -7,31 +7,48 @@ const Header = ({ onMenuToggle }) => {
|
|||
|
||||
const toggleMenu = () => {
|
||||
setIsOpen(!isOpen);
|
||||
onMenuToggle(!isOpen);
|
||||
if (onMenuToggle) onMenuToggle(!isOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="bg-gray-900 text-white p-4 flex justify-between items-center relative">
|
||||
<div className="text-2xl font-bold">
|
||||
<Link to="/" className="relative">DoTechBro.org</Link>
|
||||
<header className="bg-dark-800 text-white py-4 px-6 flex justify-between items-center relative shadow-md">
|
||||
<div className="flex items-center">
|
||||
<Link
|
||||
to="/"
|
||||
className="text-2xl font-bold bg-gradient-to-r from-primary-500 to-secondary-500 bg-clip-text text-transparent hover:opacity-90 transition-opacity duration-300"
|
||||
>
|
||||
DoTechBro.org
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="md:hidden">
|
||||
<button onClick={toggleMenu} className="focus:outline-none">
|
||||
<button
|
||||
onClick={toggleMenu}
|
||||
className="p-2 rounded-md hover:bg-dark-700 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors"
|
||||
aria-label={isOpen ? "Close menu" : "Open menu"}
|
||||
aria-expanded={isOpen}
|
||||
>
|
||||
<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 className="hidden md:flex md:items-center md:space-x-8">
|
||||
<Link to="/" className="link-underline text-white hover:text-primary-400 transition-colors">Home</Link>
|
||||
<Link to="/about" className="link-underline text-white hover:text-primary-400 transition-colors">About</Link>
|
||||
<Link to="/roadmap" className="link-underline text-white hover:text-primary-400 transition-colors">Roadmaps</Link>
|
||||
<Link to="/roadmap" className="ml-4 bg-primary-600 hover:bg-primary-700 text-white py-2 px-4 rounded-lg transition-colors shadow-sm">Get Started</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 className="absolute top-full left-0 w-full bg-dark-800 text-white shadow-lg rounded-b-lg z-50 md:hidden animate-dropdown">
|
||||
<div className="flex flex-col py-3 px-6 space-y-4">
|
||||
<Link to="/" className="py-2 link-underline text-white hover:text-primary-400 transition-colors" onClick={toggleMenu}>Home</Link>
|
||||
<Link to="/about" className="py-2 link-underline text-white hover:text-primary-400 transition-colors" onClick={toggleMenu}>About</Link>
|
||||
<Link to="/roadmap" className="py-2 link-underline text-white hover:text-primary-400 transition-colors" onClick={toggleMenu}>Roadmaps</Link>
|
||||
<Link to="/roadmap" className="bg-primary-600 hover:bg-primary-700 text-white py-2 px-4 rounded-lg text-center transition-colors shadow-sm" onClick={toggleMenu}>Get Started</Link>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
|
|
|
@ -1,23 +1,60 @@
|
|||
/* Home.css */
|
||||
.page-content {
|
||||
transition: margin-top 0.5s ease-in-out;
|
||||
transition: margin-top 0.3s ease;
|
||||
}
|
||||
|
||||
.page-content.dropdown-active {
|
||||
margin-top: 150px;
|
||||
/* Adjust based on the height of the dropdown menu */
|
||||
margin-top: 12rem;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn 1s ease-in-out forwards;
|
||||
animation: fadeIn 0.8s ease-out forwards;
|
||||
}
|
||||
|
||||
/* Gradient text effect for headings */
|
||||
.gradient-text {
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
color: transparent;
|
||||
background-image: linear-gradient(to right, var(--color-primary), var(--color-secondary));
|
||||
}
|
||||
|
||||
/* Hover effects for cards */
|
||||
.feature-card {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Button hover effects */
|
||||
.hover-scale {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.hover-scale:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* Image effects */
|
||||
.image-hover {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.image-hover:hover {
|
||||
transform: rotate(2deg) scale(1.02);
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import FeaturedRoadmaps from "./FeaturedRoadmaps";
|
||||
import MailingListDialog from "./MailingListDialog";
|
||||
import roadmaps from "../roadmaps.json";
|
||||
|
@ -50,74 +51,150 @@ const Home = () => {
|
|||
|
||||
return (
|
||||
<div className={`page-content ${menuOpen ? "dropdown-active" : ""}`}>
|
||||
<div className="flex flex-col items-center justify-center w-full">
|
||||
<div
|
||||
className="w-full p-8 flex flex-col md:flex-row items-center justify-center min-h-screen bg-gray-100 opacity-0"
|
||||
{/* Hero Section */}
|
||||
<section
|
||||
className="w-full py-16 md:py-24 bg-gradient-to-b from-dark-900 to-dark-800 text-white opacity-0"
|
||||
ref={(el) => (sectionsRef.current[0] = el)}
|
||||
>
|
||||
<div className="md:w-1/2 flex flex-col items-center text-center">
|
||||
<h2 className="text-6xl font-bold leading-tight">
|
||||
Pivot into <span className="text-green-600">tech.</span>
|
||||
<div className="container mx-auto px-6 flex flex-col md:flex-row items-center justify-between gap-12">
|
||||
<div className="md:w-1/2 flex flex-col items-start">
|
||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold leading-tight mb-4">
|
||||
Pivot into <span className="text-primary-500">tech</span>
|
||||
<br />
|
||||
<span className="font-semibold">with a head start</span>
|
||||
</h2>
|
||||
<p className="mt-4 text-lg max-w-2xl">
|
||||
<span className="font-medium text-3xl md:text-4xl lg:text-5xl">with a head start</span>
|
||||
</h1>
|
||||
<p className="text-lg text-gray-300 mb-8 max-w-lg">
|
||||
Empowering minorities to overcome barriers and succeed in the tech
|
||||
industry with confidence.
|
||||
industry with confidence and community support.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<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"
|
||||
className="px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg shadow-lg transition-colors duration-300 transform hover:scale-105"
|
||||
onClick={handleDialogOpen}
|
||||
>
|
||||
Start Today
|
||||
Start Your Journey
|
||||
</button>
|
||||
<Link
|
||||
to="/roadmap"
|
||||
className="px-6 py-3 bg-transparent border-2 border-primary-500 text-primary-400 font-medium rounded-lg hover:bg-primary-500/10 transition-colors duration-300"
|
||||
>
|
||||
Explore Roadmaps
|
||||
</Link>
|
||||
</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"
|
||||
className="w-full max-w-md rounded-lg shadow-2xl transform hover:rotate-1 transition-transform duration-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div
|
||||
className="w-full bg-gray-900 text-white py-16 opacity-0"
|
||||
{/* Features Section */}
|
||||
<section
|
||||
className="w-full py-16 bg-dark-800 text-white opacity-0"
|
||||
ref={(el) => (sectionsRef.current[1] = el)}
|
||||
>
|
||||
<FeaturedRoadmaps roadmaps={roadmaps} />
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-4">Why Choose Our Roadmaps</h2>
|
||||
<p className="text-lg text-gray-300 max-w-2xl mx-auto">
|
||||
Our carefully designed roadmaps will guide you through your tech journey with clear steps and resources.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="w-full p-8 bg-white text-center my-16 opacity-0"
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div className="bg-dark-700 p-8 rounded-xl shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div className="text-primary-500 text-4xl mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold mb-2">Curated Resources</h3>
|
||||
<p className="text-gray-300">
|
||||
Hand-picked learning resources tested and approved by industry professionals.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-dark-700 p-8 rounded-xl shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div className="text-primary-500 text-4xl mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold mb-2">Community Support</h3>
|
||||
<p className="text-gray-300">
|
||||
Join a community of like-minded individuals on similar journeys.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-dark-700 p-8 rounded-xl shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div className="text-primary-500 text-4xl mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold mb-2">Clear Progression</h3>
|
||||
<p className="text-gray-300">
|
||||
Step-by-step guidance from basics to advanced topics with practical challenges.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Featured Roadmaps Section */}
|
||||
<section
|
||||
className="w-full py-16 bg-gradient-to-b from-dark-800 to-dark-700 text-white 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>
|
||||
<FeaturedRoadmaps roadmaps={roadmaps} />
|
||||
</section>
|
||||
|
||||
<div
|
||||
className="w-full p-8 bg-gray-900 text-white text-center opacity-0"
|
||||
{/* Testimonials (Coming Soon) */}
|
||||
<section
|
||||
className="w-full py-16 bg-dark-700 text-white 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.
|
||||
<div className="container mx-auto px-6 text-center">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-8">Success Stories</h2>
|
||||
<div className="bg-dark-600 p-8 rounded-xl shadow-lg max-w-2xl mx-auto">
|
||||
<p className="text-xl italic mb-6">
|
||||
"Testimonials from our successful community members coming soon... Join us and become one of our success stories!"
|
||||
</p>
|
||||
<div className="flex justify-center">
|
||||
<Link to="/about" className="text-primary-400 hover:text-primary-300 transition-colors font-medium">
|
||||
Learn more about our mission →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Call to Action */}
|
||||
<section
|
||||
className="w-full py-16 bg-gradient-to-b from-dark-700 to-dark-900 text-white opacity-0"
|
||||
ref={(el) => (sectionsRef.current[4] = el)}
|
||||
>
|
||||
<div className="container mx-auto px-6 text-center">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-4">Ready to Start Your Tech Journey?</h2>
|
||||
<p className="text-lg text-gray-300 max-w-2xl mx-auto mb-8">
|
||||
Join our community today and get access to all our roadmaps, resources, and supportive network.
|
||||
</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"
|
||||
className="px-8 py-4 bg-primary-600 hover:bg-primary-700 text-white text-lg font-medium rounded-lg shadow-lg transition-all duration-300 transform hover:scale-105"
|
||||
>
|
||||
Join Now
|
||||
Join Our Community
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<MailingListDialog open={dialogOpen} onClose={handleDialogClose} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
|
||||
|
|
|
@ -6,6 +6,50 @@ import DialogContentText from "@mui/material/DialogContentText";
|
|||
import DialogTitle from "@mui/material/DialogTitle";
|
||||
import Button from "@mui/material/Button";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||
|
||||
// Create a custom theme that matches our design system
|
||||
const theme = createTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#22c55e', // primary-600 color
|
||||
},
|
||||
secondary: {
|
||||
main: '#6366f1', // secondary-500 color
|
||||
},
|
||||
background: {
|
||||
default: '#0f172a', // dark-900 color
|
||||
paper: '#1e293b', // dark-800 color
|
||||
},
|
||||
text: {
|
||||
primary: '#f8fafc',
|
||||
secondary: '#94a3b8',
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'Inter, system-ui, sans-serif',
|
||||
},
|
||||
shape: {
|
||||
borderRadius: 8,
|
||||
},
|
||||
components: {
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
textTransform: 'none',
|
||||
fontWeight: 500,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
borderRadius: 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const MailingListDialog = ({ open, onClose }) => {
|
||||
const [name, setName] = useState("");
|
||||
|
@ -18,6 +62,19 @@ const MailingListDialog = ({ open, onClose }) => {
|
|||
setError("");
|
||||
setSuccess("");
|
||||
|
||||
// Basic validation
|
||||
if (!name.trim() || !email.trim()) {
|
||||
setError("Please fill in all fields");
|
||||
return;
|
||||
}
|
||||
|
||||
// Email validation
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(email)) {
|
||||
setError("Please enter a valid email address");
|
||||
return;
|
||||
}
|
||||
|
||||
const form = document.createElement("form");
|
||||
form.action = "https://tech.us9.list-manage.com/subscribe/post";
|
||||
form.method = "POST";
|
||||
|
@ -45,27 +102,65 @@ const MailingListDialog = ({ open, onClose }) => {
|
|||
setSuccess("Thank you for subscribing!");
|
||||
setName("");
|
||||
setEmail("");
|
||||
|
||||
// Close the dialog after a short delay to allow user to see the success message
|
||||
setTimeout(() => {
|
||||
onClose();
|
||||
}, 1500);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose}>
|
||||
<DialogTitle>Join Our Mailing List</DialogTitle>
|
||||
<ThemeProvider theme={theme}>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
bgcolor: 'background.paper',
|
||||
color: 'text.primary',
|
||||
maxWidth: '500px',
|
||||
width: '100%',
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogTitle sx={{ fontSize: '1.5rem', fontWeight: 700, pb: 1 }}>
|
||||
Join Our Community
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
Stay updated with the latest news and updates from Do Tech Bro.
|
||||
<DialogContentText sx={{ color: 'text.secondary', mb: 3 }}>
|
||||
Get exclusive access to roadmaps, resources, and updates to accelerate your tech journey.
|
||||
</DialogContentText>
|
||||
|
||||
<TextField
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="name"
|
||||
label="Name"
|
||||
label="Full Name"
|
||||
type="text"
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
sx={{
|
||||
mb: 2,
|
||||
'& .MuiOutlinedInput-root': {
|
||||
'& fieldset': {
|
||||
borderColor: 'rgba(148, 163, 184, 0.2)',
|
||||
},
|
||||
'&:hover fieldset': {
|
||||
borderColor: 'primary.main',
|
||||
},
|
||||
},
|
||||
'& .MuiInputLabel-root': {
|
||||
color: 'text.secondary',
|
||||
},
|
||||
'& .MuiInputBase-input': {
|
||||
color: 'text.primary',
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
margin="dense"
|
||||
id="email"
|
||||
|
@ -75,33 +170,73 @@ const MailingListDialog = ({ open, onClose }) => {
|
|||
variant="outlined"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
sx={{
|
||||
mb: 2,
|
||||
'& .MuiOutlinedInput-root': {
|
||||
'& fieldset': {
|
||||
borderColor: 'rgba(148, 163, 184, 0.2)',
|
||||
},
|
||||
'&:hover fieldset': {
|
||||
borderColor: 'primary.main',
|
||||
},
|
||||
},
|
||||
'& .MuiInputLabel-root': {
|
||||
color: 'text.secondary',
|
||||
},
|
||||
'& .MuiInputBase-input': {
|
||||
color: 'text.primary',
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<DialogContentText className="mt-2 text-xs text-gray-600">
|
||||
|
||||
<DialogContentText sx={{ mt: 2, fontSize: '0.85rem', color: 'text.secondary', opacity: 0.8 }}>
|
||||
We promise not to sell your information or email you more than once or
|
||||
twice a month.
|
||||
</DialogContentText>
|
||||
|
||||
{error && (
|
||||
<DialogContentText className="mt-2 text-xs text-red-600">
|
||||
<DialogContentText sx={{ mt: 2, color: '#ef4444', fontSize: '0.875rem' }}>
|
||||
{error}
|
||||
</DialogContentText>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<DialogContentText className="mt-2 text-xs text-green-600">
|
||||
<DialogContentText sx={{ mt: 2, color: 'primary.main', fontSize: '0.875rem' }}>
|
||||
{success}
|
||||
</DialogContentText>
|
||||
)}
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} color="primary">
|
||||
|
||||
<DialogActions sx={{ px: 3, pb: 3 }}>
|
||||
<Button
|
||||
onClick={onClose}
|
||||
sx={{
|
||||
color: 'text.secondary',
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(148, 163, 184, 0.1)',
|
||||
}
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleSubmit} color="primary">
|
||||
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
sx={{
|
||||
px: 4,
|
||||
'&:hover': {
|
||||
backgroundColor: 'primary.dark',
|
||||
}
|
||||
}}
|
||||
>
|
||||
Subscribe
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default MailingListDialog;
|
||||
|
||||
|
|
|
@ -2,12 +2,44 @@ import { Link } from 'react-router-dom';
|
|||
|
||||
const NotFound = () => {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
|
||||
<h1 className="text-6xl font-bold text-gray-900 mb-8">404</h1>
|
||||
<p className="text-lg text-gray-700 mb-8">Oops! The page you're looking for doesn't exist.</p>
|
||||
<Link to="/" className="px-6 py-3 bg-green-600 text-white text-lg font-semibold rounded hover:bg-green-700 transition duration-300">
|
||||
Go Back Home
|
||||
<div className="flex flex-col items-center justify-center min-h-screen bg-dark-900 text-white px-4">
|
||||
<div className="text-center max-w-lg">
|
||||
<h1 className="text-8xl font-bold bg-gradient-to-r from-primary-500 to-secondary-500 bg-clip-text text-transparent mb-6">404</h1>
|
||||
|
||||
<h2 className="text-3xl font-bold mb-4">Page Not Found</h2>
|
||||
|
||||
<p className="text-gray-300 mb-8">
|
||||
Oops! The page you're looking for doesn't exist or has been moved to a different location.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
<Link
|
||||
to="/"
|
||||
className="px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg shadow-lg transition-colors"
|
||||
>
|
||||
Return Home
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to="/roadmap"
|
||||
className="px-6 py-3 border-2 border-primary-500 text-primary-400 hover:bg-primary-500/10 font-medium rounded-lg transition-colors"
|
||||
>
|
||||
Explore Roadmaps
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="mt-16">
|
||||
<p className="text-gray-400 mb-2">
|
||||
Think this is a mistake? Let us know!
|
||||
</p>
|
||||
<a
|
||||
href="mailto:support@dotechbro.org"
|
||||
className="text-primary-400 hover:text-primary-300 transition-colors"
|
||||
>
|
||||
support@dotechbro.org
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,59 +1,143 @@
|
|||
import { Outlet, useLocation, Link } from 'react-router-dom';
|
||||
import challenges from '../challenges';
|
||||
import roadmaps from '../roadmaps.json'; // Import the roadmaps data
|
||||
import Accordion from './Accordion'; // Import the Accordion component
|
||||
import roadmaps from '../roadmaps.json';
|
||||
import Accordion from './Accordion';
|
||||
|
||||
const Roadmap = () => {
|
||||
const location = useLocation();
|
||||
const isRootPath = location.pathname === '/roadmap';
|
||||
|
||||
return (
|
||||
<div className="p-8 flex flex-col items-center justify-center min-h-screen bg-gray-100 overflow-x-hidden">
|
||||
<h2 className="text-4xl font-bold text-center leading-tight text-gray-900 mb-8">
|
||||
Roadmaps
|
||||
</h2>
|
||||
<p className="text-lg text-center max-w-2xl text-gray-700 mb-16">
|
||||
Dive into our comprehensive roadmaps designed to illuminate your path into the tech industry. Each roadmap offers step-by-step guidance, tailored resources, and practical tips to help you navigate challenges and seize opportunities. Whether you’re just starting out or looking to advance your career, these roadmaps are your essential tools for success. Let’s chart your course together!
|
||||
<div className="bg-dark-900 text-white min-h-screen">
|
||||
{isRootPath ? (
|
||||
<>
|
||||
{/* Hero Section */}
|
||||
<section className="py-16 md:py-24 bg-gradient-to-b from-dark-800 to-dark-900">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="max-w-3xl mx-auto text-center">
|
||||
<h1 className="text-4xl md:text-5xl font-bold mb-6">Tech Career Roadmaps</h1>
|
||||
<p className="text-xl text-gray-300 leading-relaxed mb-8">
|
||||
Structured pathways to help you navigate your journey into tech, with step-by-step guidance
|
||||
and curated resources tailored for minorities entering the industry.
|
||||
</p>
|
||||
<div className="inline-flex items-center justify-center p-1 rounded-lg bg-gradient-to-r from-primary-500 to-secondary-500">
|
||||
<a href="#roadmaps" className="bg-dark-800 text-white font-medium px-6 py-3 rounded-md hover:bg-dark-700 transition-colors">
|
||||
Explore Roadmaps
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Challenges Section */}
|
||||
<section className="py-16 bg-dark-800" id="challenges">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<h2 className="text-3xl font-bold mb-8 text-center">Common Challenges</h2>
|
||||
<p className="text-lg text-gray-300 text-center mb-12">
|
||||
We understand the unique obstacles minorities face when entering tech.
|
||||
Here's how our roadmaps address these challenges.
|
||||
</p>
|
||||
<Accordion items={challenges} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Roadmaps Section */}
|
||||
<section className="py-16 bg-gradient-to-b from-dark-900 to-dark-800" id="roadmaps">
|
||||
<div className="container mx-auto px-6">
|
||||
<h2 className="text-3xl font-bold text-center mb-6">Available Roadmaps</h2>
|
||||
<p className="text-lg text-gray-300 text-center max-w-3xl mx-auto mb-12">
|
||||
Select a roadmap that aligns with your interests and goals. Each provides a clear path
|
||||
from beginner to professional.
|
||||
</p>
|
||||
|
||||
{isRootPath && (
|
||||
<>
|
||||
<Accordion items={challenges} />
|
||||
|
||||
<div className="w-screen bg-gray-900 text-white py-16 mb-16">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h3 className="text-2xl font-semibold text-center mb-4">Available Roadmaps</h3>
|
||||
<div className="flex flex-col md:flex-row justify-center items-stretch space-y-8 md:space-y-0 md:space-x-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{roadmaps.map((roadmap, index) => (
|
||||
<Link key={index} to={`/roadmap/${roadmap.id}`} className="bg-white text-gray-900 p-8 rounded-lg shadow-lg w-full md:w-1/3 text-center transform transition-transform hover:scale-105 flex flex-col">
|
||||
<h3 className="text-2xl font-semibold">{roadmap.title}</h3>
|
||||
<p className="mt-4 flex-grow">{roadmap.description}</p>
|
||||
</Link>
|
||||
<Link
|
||||
key={index}
|
||||
to={`/roadmap/${roadmap.id}`}
|
||||
className="group bg-dark-700 rounded-xl overflow-hidden shadow-lg hover:shadow-xl transition-all duration-300 flex flex-col h-full"
|
||||
>
|
||||
<div className="p-1 bg-gradient-to-r from-primary-500 to-secondary-500">
|
||||
<div className="bg-dark-700 p-6 flex-grow">
|
||||
<h3 className="text-2xl font-bold mb-4 group-hover:text-primary-400 transition-colors">
|
||||
{roadmap.title}
|
||||
</h3>
|
||||
<p className="text-gray-300 mb-6">{roadmap.description}</p>
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
{['Beginner-Friendly', 'Step-by-Step', 'Resource Links'].map((tag, i) => (
|
||||
<span key={i} className="text-xs bg-dark-600 text-gray-300 px-2 py-1 rounded-full">
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4 bg-dark-600 text-primary-400 font-medium flex justify-between items-center">
|
||||
<span>View Roadmap</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 transform group-hover:translate-x-1 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
||||
</svg>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="w-full bg-gray-50 p-8 rounded-lg shadow-lg mb-16">
|
||||
<h3 className="text-2xl font-semibold text-center mb-4 text-gray-900">More Roadmaps Coming Soon</h3>
|
||||
<p className="text-lg text-gray-700">
|
||||
We’re excited to share that we’re actively developing additional roadmaps to guide you on your tech journey. These resources are designed to empower you, providing clear paths and actionable steps tailored to your goals. Keep an eye out for updates—your future in tech is bright, and we’re here to support you every step of the way!
|
||||
{/* Coming Soon Section */}
|
||||
<section className="py-16 bg-dark-800">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="bg-gradient-to-r from-dark-700 to-dark-600 rounded-xl p-8 max-w-4xl mx-auto">
|
||||
<h3 className="text-2xl font-bold mb-4 text-center">More Roadmaps Coming Soon</h3>
|
||||
<div className="flex flex-col md:flex-row items-center gap-8">
|
||||
<div className="md:w-3/4">
|
||||
<p className="text-gray-300 mb-4">
|
||||
We're actively developing additional roadmaps for various tech roles including:
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-gray-300 mb-4 space-y-2">
|
||||
<li>Cloud Engineering</li>
|
||||
<li>Machine Learning & AI</li>
|
||||
<li>Product Management</li>
|
||||
<li>Cybersecurity</li>
|
||||
<li>Mobile App Development</li>
|
||||
</ul>
|
||||
<p className="text-gray-300">
|
||||
Subscribe to our newsletter to get notified when new roadmaps are released.
|
||||
</p>
|
||||
</div>
|
||||
<div className="md:w-1/4 flex justify-center">
|
||||
<div className="w-24 h-24 rounded-full bg-dark-500 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-primary-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="w-full bg-white p-8 rounded-lg shadow-lg text-center">
|
||||
<h3 className="text-2xl font-semibold mb-4 text-gray-900">Open Source Collaboration</h3>
|
||||
<p className="text-lg text-gray-700 mb-8">
|
||||
These roadmaps are open source and we welcome collaboration from the community. Feel free to contribute and help us improve these resources.
|
||||
{/* Contribute Section */}
|
||||
<section className="py-16 bg-gradient-to-b from-dark-800 to-dark-900">
|
||||
<div className="container mx-auto px-6 text-center">
|
||||
<h3 className="text-3xl font-bold mb-6">Open Source Collaboration</h3>
|
||||
<p className="text-lg text-gray-300 mb-8 max-w-2xl mx-auto">
|
||||
These roadmaps are open source and we welcome contributions from the community.
|
||||
Help us improve these resources for everyone.
|
||||
</p>
|
||||
<button className="px-6 py-3 bg-green-600 text-white text-lg font-semibold rounded hover:bg-green-700 transition duration-300">
|
||||
Contribute Now
|
||||
<div className="inline-block bg-gradient-to-r from-primary-500 to-secondary-500 p-0.5 rounded-lg">
|
||||
<button className="px-8 py-3 bg-dark-800 hover:bg-dark-700 text-white font-medium rounded-md transition-colors">
|
||||
Contribute on GitHub
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
) : (
|
||||
<Outlet />
|
||||
)}
|
||||
|
||||
{!isRootPath && <Outlet />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,14 +1,241 @@
|
|||
// src/components/RoadmapDetail.jsx
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
import roadmaps from '../roadmaps.json';
|
||||
|
||||
const RoadmapDetail = () => {
|
||||
const { id } = useParams();
|
||||
const [roadmap, setRoadmap] = useState(null);
|
||||
const [activeStep, setActiveStep] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
// Find the roadmap with the matching id
|
||||
const foundRoadmap = roadmaps.find(r => r.id === id);
|
||||
if (foundRoadmap) {
|
||||
setRoadmap(foundRoadmap);
|
||||
}
|
||||
}, [id]);
|
||||
|
||||
if (!roadmap) {
|
||||
return (
|
||||
<div className="container mx-auto px-6 py-16 text-center">
|
||||
<h2 className="text-3xl font-bold mb-4">Roadmap Not Found</h2>
|
||||
<p className="text-gray-300 mb-8">We couldn't find the roadmap you're looking for.</p>
|
||||
<Link
|
||||
to="/roadmap"
|
||||
className="px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-colors"
|
||||
>
|
||||
View All Roadmaps
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Mock data for steps (this would come from the roadmap data in a real implementation)
|
||||
const steps = [
|
||||
{
|
||||
title: "Getting Started",
|
||||
description: "Begin your journey by understanding the fundamentals and setting up your learning environment.",
|
||||
content: `
|
||||
<p>Welcome to your tech journey! This first phase is all about building a solid foundation. You'll get familiar with key concepts, tools, and start building habits that will serve you throughout your career.</p>
|
||||
<h4>Key Objectives:</h4>
|
||||
<ul>
|
||||
<li>Understand the field and career opportunities</li>
|
||||
<li>Set up your development environment</li>
|
||||
<li>Learn the fundamental concepts</li>
|
||||
<li>Build your first small projects</li>
|
||||
</ul>
|
||||
`,
|
||||
resources: [
|
||||
{ title: "Free Code Camp", url: "https://www.freecodecamp.org/" },
|
||||
{ title: "The Odin Project", url: "https://www.theodinproject.com/" },
|
||||
{ title: "MDN Web Docs", url: "https://developer.mozilla.org/" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Building Skills",
|
||||
description: "Develop core technical skills and start working on meaningful projects.",
|
||||
content: `
|
||||
<p>Now that you have the basics down, it's time to deepen your knowledge and start applying what you've learned to more complex problems and projects.</p>
|
||||
<h4>Key Objectives:</h4>
|
||||
<ul>
|
||||
<li>Master core programming concepts</li>
|
||||
<li>Learn industry-standard tools and frameworks</li>
|
||||
<li>Build a portfolio of projects</li>
|
||||
<li>Practice problem-solving skills</li>
|
||||
</ul>
|
||||
`,
|
||||
resources: [
|
||||
{ title: "LeetCode", url: "https://leetcode.com/" },
|
||||
{ title: "GitHub Learning Lab", url: "https://lab.github.com/" },
|
||||
{ title: "Codecademy", url: "https://www.codecademy.com/" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Professional Development",
|
||||
description: "Prepare for the job market and develop professional skills.",
|
||||
content: `
|
||||
<p>Technical skills are just one part of a successful tech career. In this phase, you'll focus on the professional aspects of working in tech and prepare for your job search.</p>
|
||||
<h4>Key Objectives:</h4>
|
||||
<ul>
|
||||
<li>Create a professional resume and online presence</li>
|
||||
<li>Develop interview skills (technical and behavioral)</li>
|
||||
<li>Build your network and find mentors</li>
|
||||
<li>Learn about industry practices and workflows</li>
|
||||
</ul>
|
||||
`,
|
||||
resources: [
|
||||
{ title: "Tech Interview Handbook", url: "https://www.techinterviewhandbook.org/" },
|
||||
{ title: "LinkedIn Learning", url: "https://www.linkedin.com/learning/" },
|
||||
{ title: "AngelList", url: "https://angel.co/jobs" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Landing Your First Role",
|
||||
description: "Strategies for job searching and excelling in your first position.",
|
||||
content: `
|
||||
<p>This is where all your hard work comes together. You'll apply for jobs, go through interviews, and start your professional journey in tech.</p>
|
||||
<h4>Key Objectives:</h4>
|
||||
<ul>
|
||||
<li>Develop an effective job search strategy</li>
|
||||
<li>Prepare for technical and behavioral interviews</li>
|
||||
<li>Evaluate job offers and negotiate compensation</li>
|
||||
<li>Plan for success in your first 90 days</li>
|
||||
</ul>
|
||||
`,
|
||||
resources: [
|
||||
{ title: "Hired", url: "https://hired.com/" },
|
||||
{ title: "Glassdoor", url: "https://www.glassdoor.com/" },
|
||||
{ title: "Blind", url: "https://www.teamblind.com/" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="p-8">
|
||||
<h2 className="text-4xl font-bold text-center mb-8">Roadmap Detail: {id}</h2>
|
||||
<p className="text-lg text-center">Details for roadmap {id} will be displayed here.</p>
|
||||
<div className="container mx-auto px-6 py-16">
|
||||
{/* Roadmap Header */}
|
||||
<div className="mb-16 text-center">
|
||||
<Link to="/roadmap" className="text-primary-400 hover:text-primary-300 transition-colors inline-flex items-center mb-6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fillRule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clipRule="evenodd" />
|
||||
</svg>
|
||||
Back to Roadmaps
|
||||
</Link>
|
||||
<h1 className="text-4xl md:text-5xl font-bold mb-4">{roadmap.title}</h1>
|
||||
<p className="text-xl text-gray-300 max-w-3xl mx-auto">{roadmap.description}</p>
|
||||
</div>
|
||||
|
||||
{/* Progress Indicator */}
|
||||
<div className="mb-12">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 flex items-center">
|
||||
<div className="w-full border-t-2 border-dark-600"></div>
|
||||
</div>
|
||||
<div className="relative flex justify-between">
|
||||
{steps.map((step, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => setActiveStep(index)}
|
||||
className={`flex items-center justify-center w-12 h-12 rounded-full text-lg font-bold ${
|
||||
index === activeStep
|
||||
? 'bg-primary-500 text-white shadow-lg'
|
||||
: index < activeStep
|
||||
? 'bg-primary-800 text-primary-200'
|
||||
: 'bg-dark-600 text-gray-400'
|
||||
} transition-all duration-300`}
|
||||
>
|
||||
{index + 1}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-between">
|
||||
{steps.map((step, index) => (
|
||||
<div key={index} className={`text-center w-1/4 px-2 ${
|
||||
index === activeStep ? 'text-white' : 'text-gray-400'
|
||||
}`}>
|
||||
<h4 className="font-medium text-sm md:text-base truncate">{step.title}</h4>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Active Step Content */}
|
||||
<div className="bg-dark-800 rounded-xl shadow-lg overflow-hidden">
|
||||
<div className="p-1 bg-gradient-to-r from-primary-500 to-secondary-500">
|
||||
<div className="bg-dark-800 p-8">
|
||||
<h2 className="text-3xl font-bold mb-2">{steps[activeStep].title}</h2>
|
||||
<p className="text-xl text-gray-300 mb-6">{steps[activeStep].description}</p>
|
||||
|
||||
<div className="prose prose-invert max-w-none mb-8" dangerouslySetInnerHTML={{ __html: steps[activeStep].content }}></div>
|
||||
|
||||
<div className="bg-dark-700 p-6 rounded-lg">
|
||||
<h3 className="text-xl font-bold mb-4">Recommended Resources</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{steps[activeStep].resources.map((resource, index) => (
|
||||
<a
|
||||
key={index}
|
||||
href={resource.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="bg-dark-600 hover:bg-dark-500 p-4 rounded-lg transition-colors flex items-center"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2 text-primary-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
<span>{resource.title}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navigation Buttons */}
|
||||
<div className="mt-8 flex justify-between">
|
||||
<button
|
||||
onClick={() => setActiveStep(Math.max(0, activeStep - 1))}
|
||||
disabled={activeStep === 0}
|
||||
className={`flex items-center px-6 py-3 rounded-lg transition-colors ${
|
||||
activeStep === 0
|
||||
? 'bg-dark-700 text-gray-500 cursor-not-allowed'
|
||||
: 'bg-dark-700 hover:bg-dark-600 text-white'
|
||||
}`}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
Previous Step
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => setActiveStep(Math.min(steps.length - 1, activeStep + 1))}
|
||||
disabled={activeStep === steps.length - 1}
|
||||
className={`flex items-center px-6 py-3 rounded-lg transition-colors ${
|
||||
activeStep === steps.length - 1
|
||||
? 'bg-dark-700 text-gray-500 cursor-not-allowed'
|
||||
: 'bg-primary-600 hover:bg-primary-700 text-white'
|
||||
}`}
|
||||
>
|
||||
Next Step
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 ml-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Community Support Section */}
|
||||
<div className="mt-16 bg-dark-700 rounded-xl p-8 text-center">
|
||||
<h3 className="text-2xl font-bold mb-4">Need Support?</h3>
|
||||
<p className="text-gray-300 mb-6">
|
||||
Join our community to connect with mentors and peers who are on similar journeys.
|
||||
Get answers to your questions and share your progress.
|
||||
</p>
|
||||
<button className="px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-colors">
|
||||
Join Our Community
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
153
src/index.css
153
src/index.css
|
@ -4,65 +4,184 @@
|
|||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
background-color: #0f172a;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Base typography scale */
|
||||
--font-size-xs: 0.75rem;
|
||||
--font-size-sm: 0.875rem;
|
||||
--font-size-base: 1rem;
|
||||
--font-size-lg: 1.125rem;
|
||||
--font-size-xl: 1.25rem;
|
||||
--font-size-2xl: 1.5rem;
|
||||
--font-size-3xl: 1.875rem;
|
||||
--font-size-4xl: 2.25rem;
|
||||
--font-size-5xl: 3rem;
|
||||
|
||||
/* Spacing scale */
|
||||
--spacing-0: 0;
|
||||
--spacing-1: 0.25rem;
|
||||
--spacing-2: 0.5rem;
|
||||
--spacing-3: 0.75rem;
|
||||
--spacing-4: 1rem;
|
||||
--spacing-6: 1.5rem;
|
||||
--spacing-8: 2rem;
|
||||
--spacing-12: 3rem;
|
||||
--spacing-16: 4rem;
|
||||
|
||||
/* Colors */
|
||||
--color-primary: #22c55e;
|
||||
--color-primary-dark: #15803d;
|
||||
--color-primary-light: #4ade80;
|
||||
--color-secondary: #6366f1;
|
||||
--color-secondary-dark: #4338ca;
|
||||
--color-secondary-light: #818cf8;
|
||||
--color-dark: #0f172a;
|
||||
--color-dark-lighter: #1e293b;
|
||||
--color-gray: #64748b;
|
||||
--color-gray-light: #94a3b8;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
color: var(--color-secondary);
|
||||
text-decoration: inherit;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
color: var(--color-secondary-light);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
flex-direction: column;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
background-color: var(--color-dark);
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
font-size: var(--font-size-4xl);
|
||||
margin-bottom: var(--spacing-6);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-3xl);
|
||||
margin-bottom: var(--spacing-4);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--font-size-2xl);
|
||||
margin-bottom: var(--spacing-3);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--spacing-4);
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
background-color: var(--color-dark-lighter);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
border-color: var(--color-primary);
|
||||
background-color: rgba(34, 197, 94, 0.1);
|
||||
}
|
||||
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Custom utility classes */
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.5rem 1.5rem;
|
||||
font-weight: 500;
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--color-primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--color-primary-dark);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: var(--color-secondary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: var(--color-secondary-dark);
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background-color: transparent;
|
||||
border: 1px solid var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.btn-outline:hover {
|
||||
background-color: var(--color-primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
color: #334155;
|
||||
background-color: #f8fafc;
|
||||
|
||||
--color-dark: #f8fafc;
|
||||
--color-dark-lighter: #f1f5f9;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
|
||||
body {
|
||||
background-color: #f8fafc;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
background-color: #e2e8f0;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: rgba(34, 197, 94, 0.1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,116 @@ export default {
|
|||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: {
|
||||
50: '#f0fdf4',
|
||||
100: '#dcfce7',
|
||||
200: '#bbf7d0',
|
||||
300: '#86efac',
|
||||
400: '#4ade80',
|
||||
500: '#22c55e',
|
||||
600: '#16a34a',
|
||||
700: '#15803d',
|
||||
800: '#166534',
|
||||
900: '#14532d',
|
||||
950: '#052e16',
|
||||
},
|
||||
secondary: {
|
||||
50: '#eef2ff',
|
||||
100: '#e0e7ff',
|
||||
200: '#c7d2fe',
|
||||
300: '#a5b4fc',
|
||||
400: '#818cf8',
|
||||
500: '#6366f1',
|
||||
600: '#4f46e5',
|
||||
700: '#4338ca',
|
||||
800: '#3730a3',
|
||||
900: '#312e81',
|
||||
950: '#1e1b4b',
|
||||
},
|
||||
dark: {
|
||||
50: '#f9fafb',
|
||||
100: '#f3f4f6',
|
||||
200: '#e5e7eb',
|
||||
300: '#d1d5db',
|
||||
400: '#9ca3af',
|
||||
500: '#6b7280',
|
||||
600: '#4b5563',
|
||||
700: '#374151',
|
||||
800: '#1f2937',
|
||||
900: '#111827',
|
||||
950: '#030712',
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'system-ui', 'sans-serif'],
|
||||
inter: ['Inter', 'sans-serif'],
|
||||
},
|
||||
fontSize: {
|
||||
xs: ['0.75rem', { lineHeight: '1rem' }],
|
||||
sm: ['0.875rem', { lineHeight: '1.25rem' }],
|
||||
base: ['1rem', { lineHeight: '1.5rem' }],
|
||||
lg: ['1.125rem', { lineHeight: '1.75rem' }],
|
||||
xl: ['1.25rem', { lineHeight: '1.75rem' }],
|
||||
'2xl': ['1.5rem', { lineHeight: '2rem' }],
|
||||
'3xl': ['1.875rem', { lineHeight: '2.25rem' }],
|
||||
'4xl': ['2.25rem', { lineHeight: '2.5rem' }],
|
||||
'5xl': ['3rem', { lineHeight: '1.16' }],
|
||||
'6xl': ['3.75rem', { lineHeight: '1.16' }],
|
||||
},
|
||||
spacing: {
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem',
|
||||
'40': '10rem',
|
||||
'48': '12rem',
|
||||
'56': '14rem',
|
||||
'64': '16rem',
|
||||
'72': '18rem',
|
||||
'80': '20rem',
|
||||
'96': '24rem',
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0',
|
||||
'sm': '0.125rem',
|
||||
DEFAULT: '0.25rem',
|
||||
'md': '0.375rem',
|
||||
'lg': '0.5rem',
|
||||
'xl': '0.75rem',
|
||||
'2xl': '1rem',
|
||||
'3xl': '1.5rem',
|
||||
'full': '9999px',
|
||||
},
|
||||
boxShadow: {
|
||||
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
||||
DEFAULT: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
|
||||
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
||||
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
||||
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
||||
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
||||
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
|
||||
none: 'none',
|
||||
},
|
||||
animation: {
|
||||
'dropdown': 'dropdown 0.3s ease-in-out',
|
||||
},
|
||||
keyframes: {
|
||||
dropdown: {
|
||||
'0%': { opacity: 0, transform: 'translateY(-10px)' },
|
||||
'100%': { opacity: 1, transform: 'translateY(0)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
|
|
Loading…
Add table
Reference in a new issue