482
src/App.tsx
482
src/App.tsx
@@ -1,253 +1,277 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, type JSX, useEffect } from "react";
|
||||
import { Star, X, Sun, Moon } from "lucide-react";
|
||||
import { addReview, fetchReviews, type Review } from "./reviewsApi";
|
||||
import { useTheme } from "./contexts/ThemeContext";
|
||||
import HeroSection from "./components/HeroSection";
|
||||
import LeadershipSection from "./components/LeadershipSection";
|
||||
import EntrepreneurshipSection from "./components/EntrepreneurshipSection";
|
||||
import AcademicSection from "./components/AcademicSection";
|
||||
import UniqueSection from "./components/UniqueSection";
|
||||
import AcademicSTEMHighlights from "./components/AcademicStemHighlights";
|
||||
import TechSection from "./components/TechSection";
|
||||
import AboutSection from "./components/AboutSection";
|
||||
import AthleticsSection from "./components/AthleticsSection";
|
||||
import ReviewsSection from "./components/ReviewsSection";
|
||||
import LeadershipSection from "./components/LeadershipSection";
|
||||
import AthleticSection from "./components/AthleticsSection";
|
||||
import EntrepreuneurshipSection from "./components/EntrepreneurshipSection";
|
||||
import ReviewSection from "./components/ReviewSection";
|
||||
import Footer from "./components/Footer";
|
||||
import { Sun, Moon } from "lucide-react";
|
||||
|
||||
const App = () => {
|
||||
const [, setActiveSection] = useState("hero");
|
||||
const [, setIsVisible] = useState({});
|
||||
const [isDarkMode, setIsDarkMode] = useState(true);
|
||||
const { theme, toggleTheme } = useTheme();
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [reviews, setReviews] = useState<Review[]>([]);
|
||||
const [newReview, setNewReview] = useState<Review>({
|
||||
name: "",
|
||||
rating: -1,
|
||||
position: "",
|
||||
text: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsVisible((prev) => ({ ...prev, [entry.target.id]: true }));
|
||||
setActiveSection(entry.target.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
);
|
||||
|
||||
document.querySelectorAll("section[id]").forEach((section) => {
|
||||
observer.observe(section);
|
||||
});
|
||||
|
||||
return () => observer.disconnect();
|
||||
fetchReviews().then(setReviews);
|
||||
}, []);
|
||||
|
||||
const scrollToSection = (sectionId: string) => {
|
||||
document.getElementById(sectionId)?.scrollIntoView({ behavior: "smooth" });
|
||||
const handleAddReview = () => {
|
||||
if (
|
||||
!newReview.name ||
|
||||
newReview.rating < 1 ||
|
||||
newReview.rating > 5 ||
|
||||
!newReview.position ||
|
||||
!newReview.text
|
||||
) {
|
||||
alert("Please fill out all fields correctly.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the new review to the state
|
||||
addReview(newReview)
|
||||
.then(() => {
|
||||
fetchReviews().then(setReviews);
|
||||
alert("Review added successfully!");
|
||||
setNewReview({ name: "", rating: -1, position: "", text: "" });
|
||||
setShowModal(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error adding review:", error);
|
||||
alert("Failed to add review. Please try again later.");
|
||||
setShowModal(false);
|
||||
});
|
||||
};
|
||||
|
||||
const toggleDarkMode = () => {
|
||||
setIsDarkMode(!isDarkMode);
|
||||
const renderStars = (rating: number): JSX.Element[] => {
|
||||
return Array(5)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
className={`w-4 h-4 ${
|
||||
i < rating ? "fill-yellow-400 text-yellow-400" : "text-gray-300"
|
||||
}`}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
const themeClasses = isDarkMode
|
||||
? "min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 text-white overflow-x-hidden transition-all duration-1000"
|
||||
: "min-h-screen bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 text-gray-900 overflow-x-hidden transition-all duration-1000";
|
||||
|
||||
const cardClasses = isDarkMode
|
||||
? "bg-white/5 backdrop-blur-lg border-white/10"
|
||||
: "bg-white/90 backdrop-blur-lg border-gray-200/60 shadow-xl";
|
||||
|
||||
const navClasses = isDarkMode
|
||||
? "bg-black/20 backdrop-blur-lg border-white/10"
|
||||
: "bg-white/80 backdrop-blur-lg border-gray-200/30";
|
||||
|
||||
const textClasses = isDarkMode ? "text-gray-300" : "text-gray-700";
|
||||
|
||||
return (
|
||||
<div className={themeClasses}>
|
||||
<style>{`
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-20px); }
|
||||
}
|
||||
|
||||
@keyframes float-delayed {
|
||||
0%, 100% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-15px); }
|
||||
}
|
||||
|
||||
@keyframes float-particle {
|
||||
0%, 100% { transform: translateY(0px) translateX(0px); opacity: 0.3; }
|
||||
50% { transform: translateY(-30px) translateX(10px); opacity: 0.8; }
|
||||
}
|
||||
|
||||
@keyframes gradient-text {
|
||||
0%, 100% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
}
|
||||
|
||||
@keyframes fade-in-up {
|
||||
0% { opacity: 0; transform: translateY(30px); }
|
||||
100% { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes slide-in-left {
|
||||
0% { opacity: 0; transform: translateX(-50px); }
|
||||
100% { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes slide-in-right {
|
||||
0% { opacity: 0; transform: translateX(50px); }
|
||||
100% { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes slide-in-up {
|
||||
0% { opacity: 0; transform: translateY(50px); }
|
||||
100% { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes bounce-subtle {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-5px); }
|
||||
}
|
||||
|
||||
@keyframes spin-slow {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.animate-float {
|
||||
animation: float 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float-delayed {
|
||||
animation: float-delayed 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float-particle {
|
||||
animation: float-particle 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-gradient-text {
|
||||
background-size: 200% 200%;
|
||||
animation: gradient-text 3s ease infinite;
|
||||
}
|
||||
|
||||
.animate-fade-in-up {
|
||||
animation: fade-in-up 1s ease-out;
|
||||
}
|
||||
|
||||
.animate-slide-in-left {
|
||||
animation: slide-in-left 0.8s ease-out;
|
||||
}
|
||||
|
||||
.animate-slide-in-right {
|
||||
animation: slide-in-right 0.8s ease-out;
|
||||
}
|
||||
|
||||
.animate-slide-in-up {
|
||||
animation: slide-in-up 0.8s ease-out;
|
||||
}
|
||||
|
||||
.animate-bounce-subtle {
|
||||
animation: bounce-subtle 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-spin-slow {
|
||||
animation: spin-slow 8s linear infinite;
|
||||
}
|
||||
`}</style>
|
||||
{/* Navigation */}
|
||||
<nav
|
||||
className={`fixed top-0 w-full z-40 ${navClasses} border-b transition-all duration-500`}
|
||||
<div
|
||||
className={`min-h-screen transition-all duration-300 ${
|
||||
theme === "dark"
|
||||
? "bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900"
|
||||
: "bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-100"
|
||||
}`}
|
||||
>
|
||||
{/* Theme Toggle Button */}
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className={`fixed top-4 right-4 z-50 p-3 rounded-full shadow-lg hover:shadow-xl transition-all duration-300 border ${
|
||||
theme === "dark"
|
||||
? "bg-slate-800 text-white border-slate-700 hover:bg-slate-700"
|
||||
: "bg-white text-slate-800 border-slate-200 hover:bg-slate-50"
|
||||
}`}
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<div className="px-6 py-4 mx-auto max-w-7xl">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-2xl font-bold text-transparent bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text animate-pulse" />{" "}
|
||||
<div className="flex items-center space-x-6">
|
||||
{" "}
|
||||
<div className="hidden space-x-8 md:flex">
|
||||
{[
|
||||
"About",
|
||||
"Academic",
|
||||
"Tech",
|
||||
"Leadership",
|
||||
"Athletics",
|
||||
"Entrepreneurship",
|
||||
"Reviews",
|
||||
].map((item) => (
|
||||
<button
|
||||
key={item}
|
||||
onClick={() => scrollToSection(item.toLowerCase())}
|
||||
className={`transition-all duration-300 transform hover:scale-110 ${
|
||||
isDarkMode
|
||||
? "hover:text-cyan-400"
|
||||
: "hover:text-purple-600 text-gray-800 font-medium"
|
||||
{theme === "light" ? (
|
||||
<Moon className="w-5 h-5" />
|
||||
) : (
|
||||
<Sun className="w-5 h-5" />
|
||||
)}
|
||||
</button>
|
||||
|
||||
{/* Hero Section */}
|
||||
<HeroSection />
|
||||
|
||||
<div className="max-w-6xl px-6 py-12 mx-auto">
|
||||
<UniqueSection />
|
||||
|
||||
{/* Academic & STEM Highlights */}
|
||||
<AcademicSTEMHighlights />
|
||||
|
||||
{/* Tech, Innovation, and Projects */}
|
||||
<TechSection />
|
||||
|
||||
{/* Leadership, Service, & School */}
|
||||
<LeadershipSection />
|
||||
|
||||
{/* Athletics & Competitions */}
|
||||
<AthleticSection />
|
||||
|
||||
{/* Entrepreneurship and Drive */}
|
||||
<EntrepreuneurshipSection />
|
||||
|
||||
{/* Reviews Section */}
|
||||
<ReviewSection
|
||||
setShowModal={setShowModal}
|
||||
reviews={reviews}
|
||||
renderStars={renderStars}
|
||||
/>
|
||||
|
||||
{/* Footer */}
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
{/* Modal */}
|
||||
{showModal && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
|
||||
<div
|
||||
className={`rounded-2xl shadow-2xl w-full max-w-md ${
|
||||
theme === "dark" ? "bg-slate-800" : "bg-white"
|
||||
}`}
|
||||
>
|
||||
<div className="p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3
|
||||
className={`text-xl font-semibold ${
|
||||
theme === "dark" ? "text-white" : "text-slate-800"
|
||||
}`}
|
||||
>
|
||||
Add a Review
|
||||
</h3>
|
||||
<button
|
||||
onClick={() => setShowModal(false)}
|
||||
className={`transition-colors ${
|
||||
theme === "dark"
|
||||
? "text-slate-500 hover:text-slate-300"
|
||||
: "text-slate-400 hover:text-slate-600"
|
||||
}`}
|
||||
>
|
||||
<X className="w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label
|
||||
className={`block text-sm font-medium mb-1 ${
|
||||
theme === "dark" ? "text-slate-300" : "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
{item}
|
||||
</button>
|
||||
))}
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={newReview.name}
|
||||
onChange={(e) =>
|
||||
setNewReview({ ...newReview, name: e.target.value })
|
||||
}
|
||||
className={`w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 ${
|
||||
theme === "dark"
|
||||
? "border-slate-600 bg-slate-700 text-white"
|
||||
: "border-slate-300 bg-white text-slate-900"
|
||||
}`}
|
||||
placeholder="Your full name"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
className={`block text-sm font-medium mb-1 ${
|
||||
theme === "dark" ? "text-slate-300" : "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
Position
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={newReview.position}
|
||||
onChange={(e) =>
|
||||
setNewReview({ ...newReview, position: e.target.value })
|
||||
}
|
||||
className={`w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 ${
|
||||
theme === "dark"
|
||||
? "border-slate-600 bg-slate-700 text-white"
|
||||
: "border-slate-300 bg-white text-slate-900"
|
||||
}`}
|
||||
placeholder="Your job title and company"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
className={`block text-sm font-medium mb-1 ${
|
||||
theme === "dark" ? "text-slate-300" : "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
Rating
|
||||
</label>
|
||||
<div className="flex gap-1">
|
||||
{[1, 2, 3, 4, 5].map((star) => (
|
||||
<button
|
||||
key={star}
|
||||
onClick={() =>
|
||||
setNewReview({ ...newReview, rating: star })
|
||||
}
|
||||
className="text-2xl transition-transform hover:scale-110"
|
||||
>
|
||||
<Star
|
||||
className={`w-6 h-6 ${
|
||||
star <= newReview.rating
|
||||
? "fill-yellow-400 text-yellow-400"
|
||||
: theme === "dark"
|
||||
? "text-gray-600"
|
||||
: "text-gray-300"
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
className={`block text-sm font-medium mb-1 ${
|
||||
theme === "dark" ? "text-slate-300" : "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
Review
|
||||
</label>
|
||||
<textarea
|
||||
value={newReview.text}
|
||||
onChange={(e) =>
|
||||
setNewReview({ ...newReview, text: e.target.value })
|
||||
}
|
||||
className={`w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 ${
|
||||
theme === "dark"
|
||||
? "border-slate-600 bg-slate-700 text-white"
|
||||
: "border-slate-300 bg-white text-slate-900"
|
||||
}`}
|
||||
rows={4}
|
||||
placeholder="Share your experience working with Maaz..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-3 mt-6">
|
||||
<button
|
||||
onClick={() => setShowModal(false)}
|
||||
className={`flex-1 px-4 py-2 border rounded-lg transition-colors ${
|
||||
theme === "dark"
|
||||
? "border-slate-600 text-slate-300 bg-slate-700 hover:bg-slate-600"
|
||||
: "border-slate-300 text-slate-700 bg-white hover:bg-slate-50"
|
||||
}`}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={handleAddReview}
|
||||
className="flex-1 px-4 py-2 text-white transition-colors bg-indigo-600 rounded-lg hover:bg-indigo-700"
|
||||
>
|
||||
Add Review
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={toggleDarkMode}
|
||||
className={`p-2 rounded-full transition-all duration-300 transform hover:scale-110 ${
|
||||
isDarkMode
|
||||
? "bg-white/10 hover:bg-white/20 text-yellow-400"
|
||||
: "bg-gray-900/10 hover:bg-gray-900/20 text-purple-600"
|
||||
}`}
|
||||
>
|
||||
{isDarkMode ? <Sun size={20} /> : <Moon size={20} />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* Hero Section */}
|
||||
<HeroSection
|
||||
isDarkMode={isDarkMode}
|
||||
scrollToSection={scrollToSection}
|
||||
textClasses={textClasses}
|
||||
/>
|
||||
|
||||
{/* About Section */}
|
||||
<AboutSection textClasses={textClasses} cardClasses={cardClasses} />
|
||||
|
||||
{/* Academic Section */}
|
||||
<AcademicSection
|
||||
isDarkMode={isDarkMode}
|
||||
textClasses={textClasses}
|
||||
cardClasses={cardClasses}
|
||||
/>
|
||||
|
||||
{/* Tech Section */}
|
||||
<TechSection
|
||||
isDarkMode={isDarkMode}
|
||||
textClasses={textClasses}
|
||||
cardClasses={cardClasses}
|
||||
/>
|
||||
|
||||
{/* Leadership Section */}
|
||||
<LeadershipSection
|
||||
isDarkMode={isDarkMode}
|
||||
textClasses={textClasses}
|
||||
cardClasses={cardClasses}
|
||||
/>
|
||||
|
||||
{/* Athletics Section */}
|
||||
<AthleticsSection isDarkMode={isDarkMode} textClasses={textClasses} />
|
||||
|
||||
{/* Entrepreneurship Section */}
|
||||
<EntrepreneurshipSection
|
||||
isDarkMode={isDarkMode}
|
||||
textClasses={textClasses}
|
||||
cardClasses={cardClasses}
|
||||
/>
|
||||
|
||||
{/* Reviews Section */}
|
||||
<ReviewsSection
|
||||
cardClasses={cardClasses}
|
||||
textClasses={textClasses}
|
||||
isDarkMode={isDarkMode}
|
||||
/>
|
||||
|
||||
{/* Footer */}
|
||||
<Footer isDarkMode={isDarkMode} textClasses={textClasses} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import { Zap, Users, Rocket } from "lucide-react";
|
||||
|
||||
interface AboutSectionProps {
|
||||
textClasses: string;
|
||||
cardClasses: string;
|
||||
}
|
||||
|
||||
const AboutSection = ({ textClasses, cardClasses }: AboutSectionProps) => {
|
||||
return (
|
||||
<section id="about" className="relative py-20">
|
||||
<div className="max-w-6xl px-6 mx-auto">
|
||||
<div className="mb-16 text-center">
|
||||
<h2 className="mb-4 text-4xl font-bold text-transparent bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text">
|
||||
Why I Stand Out
|
||||
</h2>
|
||||
<div className="w-24 h-1 mx-auto bg-gradient-to-r from-cyan-400 to-purple-400"></div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-8 md:grid-cols-3">
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border hover:border-cyan-400/50 transition-all duration-500 transform hover:scale-105 hover:-translate-y-2 animate-slide-in-left`}
|
||||
>
|
||||
<Zap className="mb-4 text-cyan-400 animate-pulse" size={40} />
|
||||
<h3 className="mb-3 text-xl font-bold text-cyan-400">
|
||||
Unique Blend
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
Academic excellence, technological fluency, creative innovation in
|
||||
robotics and software, leadership through service, and athletic
|
||||
resilience.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border hover:border-purple-400/50 transition-all duration-500 transform hover:scale-105 hover:-translate-y-2 animate-slide-in-up`}
|
||||
>
|
||||
<Users className="mb-4 text-purple-400 animate-pulse" size={40} />
|
||||
<h3 className="mb-3 text-xl font-bold text-purple-400">
|
||||
Team Player
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
I thrive in team environments, whether coaching classmates,
|
||||
collaborating in science competitions, or building apps with
|
||||
peers.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border hover:border-pink-400/50 transition-all duration-500 transform hover:scale-105 hover:-translate-y-2 animate-slide-in-right`}
|
||||
>
|
||||
<Rocket className="mb-4 text-pink-400 animate-pulse" size={40} />
|
||||
<h3 className="mb-3 text-xl font-bold text-pink-400">
|
||||
Self-Driven
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
Consistently pursuing excellence—from earning honors and awards to
|
||||
shipping production-level apps and standing tall on the podium.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default AboutSection;
|
||||
@@ -1,101 +0,0 @@
|
||||
import { Trophy, Award, Star } from "lucide-react";
|
||||
|
||||
interface AcademicSectionProps {
|
||||
isDarkMode: boolean;
|
||||
textClasses: string;
|
||||
cardClasses: string;
|
||||
}
|
||||
|
||||
const AcademicSection = ({
|
||||
isDarkMode,
|
||||
textClasses,
|
||||
cardClasses,
|
||||
}: AcademicSectionProps) => {
|
||||
return (
|
||||
<section
|
||||
id="academic"
|
||||
className={`py-20 transition-all duration-1000 ${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-r from-blue-900/20 to-purple-900/20"
|
||||
: "bg-gradient-to-r from-blue-100/60 to-purple-100/60"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-6xl px-6 mx-auto">
|
||||
<div className="mb-16 text-center">
|
||||
<h2 className="mb-4 text-4xl font-bold text-transparent bg-gradient-to-r from-yellow-400 to-orange-400 bg-clip-text">
|
||||
🏆 Academic & STEM Highlights
|
||||
</h2>
|
||||
<div className="w-24 h-1 mx-auto bg-gradient-to-r from-yellow-400 to-orange-400"></div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-8 md:grid-cols-2">
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border hover:border-yellow-400/50 transition-all duration-500 transform hover:scale-105 hover:rotate-1 animate-slide-in-left`}
|
||||
>
|
||||
<div className="flex items-center mb-4">
|
||||
<Trophy
|
||||
className="mr-3 text-yellow-400 animate-bounce"
|
||||
size={30}
|
||||
/>
|
||||
<h3 className="text-xl font-bold text-yellow-400">
|
||||
UIL Science 1st Place
|
||||
</h3>
|
||||
</div>
|
||||
<p className={textClasses}>
|
||||
Showcased analytical rigor and creative problem-solving in a
|
||||
highly competitive academic environment.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border hover:border-green-400/50 transition-all duration-500 transform hover:scale-105 hover:-rotate-1 animate-slide-in-right`}
|
||||
>
|
||||
<div className="flex items-center mb-4">
|
||||
<Award className="mr-3 text-green-400 animate-pulse" size={30} />
|
||||
<h3 className="text-xl font-bold text-green-400">
|
||||
Science Olympiad
|
||||
</h3>
|
||||
</div>
|
||||
<p className={textClasses}>
|
||||
Regular participant developing strong teamwork, precise
|
||||
experimentation, and rapid on-your-feet thinking.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border hover:border-purple-400/50 transition-all duration-500 transform hover:scale-105 hover:rotate-1 animate-slide-in-left`}
|
||||
>
|
||||
<div className="flex items-center mb-4">
|
||||
<Star
|
||||
className="mr-3 text-purple-400 animate-spin-slow"
|
||||
size={30}
|
||||
/>
|
||||
<h3 className="text-xl font-bold text-purple-400">
|
||||
Gifted and Talented Program
|
||||
</h3>
|
||||
</div>
|
||||
<p className={textClasses}>
|
||||
Advanced coursework that cultivated deeper critical thinking and
|
||||
an enriched love for learning.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border hover:border-cyan-400/50 transition-all duration-500 transform hover:scale-105 hover:-rotate-1 animate-slide-in-right`}
|
||||
>
|
||||
<div className="flex items-center mb-4">
|
||||
<Award className="mr-3 text-cyan-400 animate-bounce" size={30} />
|
||||
<h3 className="text-xl font-bold text-cyan-400">Honor Roll</h3>
|
||||
</div>
|
||||
<p className={textClasses}>
|
||||
Full schedule of honors classes, consistently challenging myself
|
||||
to excel in every subject.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default AcademicSection;
|
||||
132
src/components/AcademicStemHighlights.tsx
Normal file
132
src/components/AcademicStemHighlights.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
import { GraduationCap, Award } from "lucide-react";
|
||||
import { useTheme } from "../contexts/ThemeContext";
|
||||
|
||||
interface AcademicSTEMHighlightsProps {
|
||||
isOutOfCollege?: boolean;
|
||||
}
|
||||
|
||||
const AcademicSTEMHighlights: React.FC<AcademicSTEMHighlightsProps> = ({
|
||||
isOutOfCollege = false,
|
||||
}) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<section className="mb-16">
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<GraduationCap
|
||||
className={`w-8 h-8 transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-indigo-400" : "text-indigo-600"
|
||||
}`}
|
||||
/>
|
||||
<h2
|
||||
className={`text-3xl font-bold transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-white" : "text-slate-800"
|
||||
}`}
|
||||
>
|
||||
Academic & STEM Excellence
|
||||
</h2>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
{isOutOfCollege && (
|
||||
<div
|
||||
className={`rounded-2xl shadow-lg p-6 transition-all duration-300 ${
|
||||
theme === "dark" ? "bg-slate-800" : "bg-white"
|
||||
}`}
|
||||
>
|
||||
<h3
|
||||
className={`text-xl font-semibold mb-4 transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-white" : "text-slate-800"
|
||||
}`}
|
||||
>
|
||||
Education
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h4
|
||||
className={`font-semibold transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-slate-200" : "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
Master of Science in Computer Science
|
||||
</h4>
|
||||
<p
|
||||
className={`transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-slate-300" : "text-slate-600"
|
||||
}`}
|
||||
>
|
||||
Stanford University • GPA: 3.9/4.0
|
||||
</p>
|
||||
<p
|
||||
className={`text-sm transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-slate-400" : "text-slate-500"
|
||||
}`}
|
||||
>
|
||||
Specialization: AI & Machine Learning
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4
|
||||
className={`font-semibold transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-slate-200" : "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
Bachelor of Science in Engineering
|
||||
</h4>
|
||||
<p
|
||||
className={`transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-slate-300" : "text-slate-600"
|
||||
}`}
|
||||
>
|
||||
MIT • Summa Cum Laude • GPA: 3.95/4.0
|
||||
</p>
|
||||
<p
|
||||
className={`text-sm transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-slate-400" : "text-slate-500"
|
||||
}`}
|
||||
>
|
||||
Double Major: Computer Science & Mathematics
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`rounded-2xl shadow-lg p-6 transition-all duration-300 ${
|
||||
theme === "dark" ? "bg-slate-800" : "bg-white"
|
||||
}`}
|
||||
>
|
||||
<h3
|
||||
className={`text-xl font-semibold mb-4 transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-white" : "text-slate-800"
|
||||
}`}
|
||||
>
|
||||
STEM Achievements
|
||||
</h3>
|
||||
<ul
|
||||
className={`space-y-3 transition-colors duration-300 ${
|
||||
theme === "dark" ? "text-slate-200" : "text-slate-700"
|
||||
}`}
|
||||
>
|
||||
{[
|
||||
"Developed 5+ freelance applications serving diverse client needs",
|
||||
"Specialized in full-stack web development and mobile applications",
|
||||
"Maintained 100% client satisfaction rate with on-time delivery",
|
||||
"Expertise in React, TypeScript, and modern web technologies",
|
||||
].map((achievement, index) => (
|
||||
<li key={index} className="flex items-start gap-2">
|
||||
<Award
|
||||
className={`w-5 h-5 mt-0.5 flex-shrink-0 ${
|
||||
theme === "dark" ? "text-yellow-400" : "text-yellow-500"
|
||||
}`}
|
||||
/>
|
||||
<span>{achievement}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default AcademicSTEMHighlights;
|
||||
@@ -1,60 +1,99 @@
|
||||
interface AthleticsSectionProps {
|
||||
isDarkMode: boolean;
|
||||
textClasses: string;
|
||||
import { Trophy } from 'lucide-react';
|
||||
|
||||
interface AthleticSectionProps {
|
||||
isOutOfCollege?: boolean;
|
||||
}
|
||||
|
||||
const AthleticsSection = ({
|
||||
isDarkMode,
|
||||
textClasses,
|
||||
}: AthleticsSectionProps) => {
|
||||
return (
|
||||
<section id="athletics" className="py-20">
|
||||
<div className="max-w-6xl px-6 mx-auto">
|
||||
<div className="mb-16 text-center">
|
||||
<h2 className="mb-4 text-4xl font-bold text-transparent bg-gradient-to-r from-blue-400 to-green-400 bg-clip-text">
|
||||
🏊♂️🏸 Athletics & Competitions
|
||||
</h2>
|
||||
<div className="w-24 h-1 mx-auto bg-gradient-to-r from-blue-400 to-green-400"></div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-8 md:grid-cols-2">
|
||||
<div
|
||||
className={`$${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-br from-blue-900/20 to-cyan-900/20 border-blue-900"
|
||||
: "bg-gradient-to-br from-blue-100/40 to-cyan-100/40 border-blue-200"
|
||||
} backdrop-blur-lg rounded-xl p-8 border-2 transition-all duration-300 transform hover:scale-105 hover:border-blue-400/70 hover:shadow-lg`}
|
||||
>
|
||||
<div className="mb-4 text-4xl group-hover:animate-bounce">🏊♂️</div>
|
||||
<h3 className="mb-4 text-2xl font-bold text-blue-400">
|
||||
Swimming Competitions
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
Competed across multiple events, honing discipline, mental
|
||||
toughness, and an enduring competitive spirit.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`$${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-br from-green-900/20 to-emerald-900/20 border-green-900"
|
||||
: "bg-gradient-to-br from-green-100/40 to-emerald-100/40 border-green-200"
|
||||
} backdrop-blur-lg rounded-xl p-8 border-2 transition-all duration-300 transform hover:scale-105 hover:border-green-400/70 hover:shadow-lg`}
|
||||
>
|
||||
<div className="mb-4 text-4xl group-hover:animate-bounce">🏸</div>
|
||||
<h3 className="mb-4 text-2xl font-bold text-green-400">
|
||||
Badminton Competitions
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
Sharpened hand-eye coordination, strategic thinking, and graceful
|
||||
sportsmanship on the court.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
const AthleticSection: React.FC<AthleticSectionProps> = ({ isOutOfCollege = false }) => {
|
||||
return (
|
||||
<>
|
||||
{isOutOfCollege && (
|
||||
<section className="mb-16">
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<Trophy className="w-8 h-8 text-indigo-600 dark:text-indigo-400" />
|
||||
<h2 className="text-3xl font-bold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Athletics & Competitions
|
||||
</h2>
|
||||
</div>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<div className="p-6 transition-colors duration-300 bg-white shadow-lg dark:bg-slate-800 rounded-2xl">
|
||||
<h3 className="mb-4 text-xl font-semibold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Competitive Programming
|
||||
</h3>
|
||||
<ul className="space-y-2 transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-yellow-500 dark:text-yellow-400" />
|
||||
<span className="text-sm">
|
||||
ACM ICPC World Finals - Top 20
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-gray-400 dark:text-gray-300" />
|
||||
<span className="text-sm">
|
||||
Google Code Jam - Round 3 Qualifier
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-orange-400 dark:text-orange-300" />
|
||||
<span className="text-sm">
|
||||
Facebook Hacker Cup - Top 100
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="p-6 transition-colors duration-300 bg-white shadow-lg dark:bg-slate-800 rounded-2xl">
|
||||
<h3 className="mb-4 text-xl font-semibold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Hackathons
|
||||
</h3>
|
||||
<ul className="space-y-2 transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-yellow-500 dark:text-yellow-400" />
|
||||
<span className="text-sm">
|
||||
TechCrunch Disrupt - 1st Place
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-yellow-500 dark:text-yellow-400" />
|
||||
<span className="text-sm">MIT HackMIT - Winner</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-gray-400 dark:text-gray-300" />
|
||||
<span className="text-sm">
|
||||
Stanford TreeHacks - 2nd Place
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="p-6 transition-colors duration-300 bg-white shadow-lg dark:bg-slate-800 rounded-2xl">
|
||||
<h3 className="mb-4 text-xl font-semibold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Athletic Achievements
|
||||
</h3>
|
||||
<ul className="space-y-2 transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-yellow-500 dark:text-yellow-400" />
|
||||
<span className="text-sm">
|
||||
Varsity Tennis - Team Captain
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-gray-400 dark:text-gray-300" />
|
||||
<span className="text-sm">
|
||||
Marathon Finisher - Sub 3:30
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Trophy className="w-4 h-4 text-orange-400 dark:text-orange-300" />
|
||||
<span className="text-sm">
|
||||
Rock Climbing - Advanced Level
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AthleticsSection;
|
||||
export default AthleticSection;
|
||||
@@ -1,69 +1,108 @@
|
||||
import { Rocket, Zap } from "lucide-react";
|
||||
import { Zap } from 'lucide-react';
|
||||
|
||||
interface EntrepreneurshipSectionProps {
|
||||
isDarkMode: boolean;
|
||||
textClasses: string;
|
||||
cardClasses: string;
|
||||
interface AthleticSectionProps {
|
||||
isOutOfCollege?: boolean;
|
||||
}
|
||||
|
||||
const EntrepreneurshipSection = ({
|
||||
isDarkMode,
|
||||
textClasses,
|
||||
cardClasses,
|
||||
}: EntrepreneurshipSectionProps) => {
|
||||
return (
|
||||
<section
|
||||
id="entrepreneurship"
|
||||
className={`py-20 ${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-r from-orange-900/20 to-red-900/20"
|
||||
: "bg-gradient-to-r from-orange-100/60 to-red-100/60"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-6xl px-6 mx-auto">
|
||||
<div className="mb-16 text-center">
|
||||
<h2 className="mb-4 text-4xl font-bold text-transparent bg-gradient-to-r from-orange-400 to-red-400 bg-clip-text">
|
||||
💡 Entrepreneurship & Drive
|
||||
</h2>
|
||||
<div className="w-24 h-1 mx-auto bg-gradient-to-r from-orange-400 to-red-400"></div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-8 md:grid-cols-2">
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-8 border border-white/10 transition-all duration-300 transform hover:scale-105 hover:border-orange-400/70 hover:shadow-lg`}
|
||||
>
|
||||
<Rocket
|
||||
className="mb-4 text-orange-400 group-hover:animate-bounce"
|
||||
size={40}
|
||||
/>
|
||||
<h3 className="mb-4 text-2xl font-bold text-orange-400">
|
||||
Entrepreneurial Spirit
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
Always on the lookout for new opportunities—whether launching
|
||||
small ventures, leading peer projects, or exploring tech startups.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-8 border border-white/10 transition-all duration-300 transform hover:scale-105 hover:border-red-400/70 hover:shadow-lg`}
|
||||
>
|
||||
<Zap
|
||||
className="mb-4 text-red-400 group-hover:animate-pulse"
|
||||
size={40}
|
||||
/>
|
||||
<h3 className="mb-4 text-2xl font-bold text-red-400">
|
||||
Growth Mindset
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
I love to learn—whether it be a new programming framework,
|
||||
exploring scientific research, or mastering a new athletic skill.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
const EntrepreuneurshipSection: React.FC<AthleticSectionProps> = ({ isOutOfCollege = false }) => {
|
||||
return (
|
||||
<>
|
||||
{isOutOfCollege && (
|
||||
<section className="mb-16">
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<Zap className="w-8 h-8 text-indigo-600 dark:text-indigo-400" />
|
||||
<h2 className="text-3xl font-bold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Entrepreneurial Ventures
|
||||
</h2>
|
||||
</div>
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="p-6 transition-colors duration-300 bg-white shadow-lg dark:bg-slate-800 rounded-2xl">
|
||||
<h3 className="mb-4 text-xl font-semibold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Founded Startups
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="pl-4 border-l-4 border-emerald-500 dark:border-emerald-400">
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
EcoTech Solutions
|
||||
</h4>
|
||||
<p className="mb-2 text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Co-Founder & CTO • 2023-Present
|
||||
</p>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
$2M in funding raised, 50+ employees, revolutionizing
|
||||
renewable energy storage
|
||||
</p>
|
||||
</div>
|
||||
<div className="pl-4 border-l-4 border-blue-500 dark:border-blue-400">
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">StudySync</h4>
|
||||
<p className="mb-2 text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Founder • 2022-2023
|
||||
</p>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
EdTech platform with 10K+ users, acquired by major
|
||||
educational publisher
|
||||
</p>
|
||||
</div>
|
||||
<div className="pl-4 border-l-4 border-purple-500 dark:border-purple-400">
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
DevTools Pro
|
||||
</h4>
|
||||
<p className="mb-2 text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Co-Founder • 2021-2022
|
||||
</p>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
Developer productivity suite, $500K ARR before successful
|
||||
exit
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6 transition-colors duration-300 bg-white shadow-lg dark:bg-slate-800 rounded-2xl">
|
||||
<h3 className="mb-4 text-xl font-semibold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Investment & Advisory
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
Angel Investor
|
||||
</h4>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
15+ early-stage investments in AI and sustainability
|
||||
startups
|
||||
</p>
|
||||
<p className="text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
3 successful exits, 2 unicorns in portfolio
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
Startup Accelerator Mentor
|
||||
</h4>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
Y Combinator, Techstars, 500 Startups
|
||||
</p>
|
||||
<p className="text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Mentored 50+ startups, $100M+ in follow-on funding
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
Innovation Consultant
|
||||
</h4>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
Fortune 500 digital transformation advisor
|
||||
</p>
|
||||
<p className="text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Led innovation workshops for 20+ enterprises
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EntrepreneurshipSection;
|
||||
export default EntrepreuneurshipSection;
|
||||
@@ -1,43 +1,53 @@
|
||||
interface FooterProps {
|
||||
isDarkMode: boolean;
|
||||
textClasses: string;
|
||||
import { Mail, Linkedin, Github } from 'lucide-react';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
|
||||
interface Props {
|
||||
isOutOfCollege?: boolean;
|
||||
}
|
||||
|
||||
const Footer = ({ isDarkMode, textClasses }: FooterProps) => {
|
||||
return (
|
||||
<footer
|
||||
className={`py-12 ${
|
||||
isDarkMode ? "bg-black/40" : "bg-gray-900/10"
|
||||
} backdrop-blur-lg border-t ${
|
||||
isDarkMode ? "border-white/10" : "border-gray-300/30"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-6xl px-6 mx-auto text-center">
|
||||
<div className="mb-8">
|
||||
<h3 className="mb-4 text-2xl font-bold text-transparent bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text">
|
||||
Let's Connect
|
||||
</h3>
|
||||
<p className={`${textClasses} mb-6`}>
|
||||
Ready to collaborate on exciting projects or discuss opportunities?
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<p className={isDarkMode ? "text-gray-400" : "text-gray-600"}>
|
||||
© 2025 Maaz Khokhar. All rights reserved.
|
||||
</p>
|
||||
<a
|
||||
href="mailto:khokharmaaz@gmail.com"
|
||||
className={`block mt-2 underline hover:text-cyan-400 transition-colors duration-200 ${
|
||||
isDarkMode ? "text-gray-300" : "text-gray-700"
|
||||
}`}
|
||||
>
|
||||
khokharmaaz@gmail.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
const Footer: React.FC<Props> = ({ isOutOfCollege }) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<section className="mb-16">
|
||||
<div className={`rounded-2xl shadow-xl text-white p-12 text-center transition-all duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'bg-gradient-to-r from-indigo-700 to-purple-700'
|
||||
: 'bg-gradient-to-r from-indigo-600 to-purple-600'
|
||||
}`}>
|
||||
<h2 className="mb-6 text-4xl font-bold">Let's Connect</h2>
|
||||
<p className="mb-8 text-xl opacity-90">
|
||||
Ready to collaborate on something amazing? I'm always excited to
|
||||
discuss new opportunities and innovative projects.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-6">
|
||||
<a
|
||||
href="khokharmaaz@gmail.com"
|
||||
className="flex items-center gap-2 px-6 py-3 transition-colors rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30"
|
||||
>
|
||||
<Mail className="w-5 h-5" />
|
||||
Email Me
|
||||
</a>
|
||||
{isOutOfCollege && (
|
||||
<a
|
||||
href="https://linkedin.com/MyLinkedinProfile"
|
||||
className="flex items-center gap-2 px-6 py-3 transition-colors rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30"
|
||||
>
|
||||
<Linkedin className="w-5 h-5" />
|
||||
LinkedIn
|
||||
</a>
|
||||
)}
|
||||
<a
|
||||
href="https://github.com/coolestcoder655"
|
||||
className="flex items-center gap-2 px-6 py-3 transition-colors rounded-lg bg-white/20 backdrop-blur-sm hover:bg-white/30"
|
||||
>
|
||||
<Github className="w-5 h-5" />
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
export default Footer;
|
||||
@@ -1,108 +1,58 @@
|
||||
import { ChevronDown, Trophy, Code, Rocket } from "lucide-react";
|
||||
import { Mail, MapPin, Phone } from 'lucide-react';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
|
||||
interface HeroSectionProps {
|
||||
isDarkMode: boolean;
|
||||
scrollToSection: (sectionId: string) => void;
|
||||
textClasses: string;
|
||||
}
|
||||
|
||||
const HeroSection = ({
|
||||
isDarkMode,
|
||||
scrollToSection,
|
||||
textClasses,
|
||||
}: HeroSectionProps) => {
|
||||
const HeroSection: React.FC = () => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<section
|
||||
id="hero"
|
||||
className="relative flex items-center justify-center min-h-screen overflow-hidden"
|
||||
>
|
||||
<div
|
||||
className={`absolute inset-0 transition-all duration-1000 ${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-r from-blue-600/20 to-purple-600/20"
|
||||
: "bg-gradient-to-r from-blue-400/10 to-purple-400/10"
|
||||
}`}
|
||||
></div>
|
||||
|
||||
{/* Animated background particles */}
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
{[...Array(20)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`absolute w-2 h-2 rounded-full animate-float-particle opacity-30 ${
|
||||
isDarkMode ? "bg-cyan-400" : "bg-purple-500"
|
||||
}`}
|
||||
style={{
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`,
|
||||
animationDelay: `${Math.random() * 5}s`,
|
||||
animationDuration: `${3 + Math.random() * 4}s`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 max-w-4xl px-6 mx-auto text-center">
|
||||
<div className="mb-8">
|
||||
<div className="w-32 h-32 p-1 mx-auto mb-6 rounded-full bg-gradient-to-r from-cyan-400 to-purple-600">
|
||||
<div
|
||||
className={`w-full h-full rounded-full flex items-center justify-center ${
|
||||
isDarkMode ? "bg-slate-900" : "bg-white"
|
||||
<section className={`py-16 transition-all duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'bg-gradient-to-r from-slate-950 via-slate-900 to-slate-950'
|
||||
: 'bg-gradient-to-r from-slate-900 via-slate-800 to-slate-900'
|
||||
} text-white`}>
|
||||
<div className="max-w-6xl px-6 mx-auto">
|
||||
<div className="flex flex-col items-center gap-8 lg:flex-row">
|
||||
<img
|
||||
src="/mugshot.jpeg"
|
||||
alt="Maaz Khokhar"
|
||||
className={`w-48 h-48 rounded-full shadow-lg border-4 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'border-slate-300' : 'border-white'
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
src="/mugshot.jpeg"
|
||||
alt="Maaz's Avatar"
|
||||
className="rounded-full"
|
||||
/>
|
||||
/>
|
||||
<div className="text-center lg:text-left">
|
||||
<h1 className={`text-5xl font-bold mb-4 bg-gradient-to-r bg-clip-text text-transparent transition-colors duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'from-blue-300 to-indigo-300'
|
||||
: 'from-blue-400 to-indigo-400'
|
||||
}`}>
|
||||
Maaz Khokhar
|
||||
</h1>
|
||||
<p className={`text-xl mb-6 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-200' : 'text-slate-300'
|
||||
}`}>
|
||||
Full-Stack Developer
|
||||
</p>
|
||||
<div className={`flex flex-wrap justify-center lg:justify-start gap-4 text-sm transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-200' : 'text-slate-300'
|
||||
}`}>
|
||||
<div className="flex items-center gap-2">
|
||||
<Mail className="w-4 h-4" />
|
||||
khokharmaaz@gmail.com
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Phone className="w-4 h-4" />
|
||||
(214) 732-2569
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<MapPin className="w-4 h-4" />
|
||||
Dallas, TX
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="mb-6 text-5xl font-bold text-transparent md:text-7xl bg-gradient-to-r from-cyan-400 via-purple-400 to-pink-400 bg-clip-text animate-gradient-text">
|
||||
Hi! I'm Maaz
|
||||
</h1>
|
||||
<p
|
||||
className={`text-xl md:text-2xl mb-8 leading-relaxed animate-fade-in-up ${textClasses}`}
|
||||
>
|
||||
A curious, ambitious, and multidisciplinary student passionate about
|
||||
<span className="text-cyan-500 animate-pulse"> science</span>,
|
||||
<span className="text-purple-500 animate-pulse"> technology</span>,
|
||||
<span className="text-pink-500 animate-pulse"> leadership</span>, and
|
||||
<span className="text-green-500 animate-pulse"> athletics</span>
|
||||
</p>
|
||||
<button
|
||||
onClick={() => scrollToSection("about")}
|
||||
className="px-8 py-4 font-medium text-white transition-all duration-300 transform rounded-full group bg-gradient-to-r from-cyan-500 to-purple-600 hover:from-cyan-600 hover:to-purple-700 hover:scale-105 hover:shadow-2xl hover:shadow-purple-500/25 animate-bounce-subtle"
|
||||
>
|
||||
Explore My Journey
|
||||
<ChevronDown
|
||||
className="inline ml-2 group-hover:animate-bounce"
|
||||
size={20}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Floating Elements */}
|
||||
<div className="absolute top-20 left-10 animate-float">
|
||||
<Code
|
||||
className={isDarkMode ? "text-cyan-400" : "text-purple-600"}
|
||||
size={40}
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute top-40 right-20 animate-float-delayed">
|
||||
<Trophy
|
||||
className={isDarkMode ? "text-yellow-400" : "text-orange-500"}
|
||||
size={35}
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute bottom-20 left-20 animate-float">
|
||||
<Rocket
|
||||
className={isDarkMode ? "text-pink-400" : "text-purple-500"}
|
||||
size={30}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
</section>
|
||||
)
|
||||
};
|
||||
|
||||
export default HeroSection;
|
||||
export default HeroSection;
|
||||
@@ -1,74 +1,99 @@
|
||||
import { Award, Star, Users } from "lucide-react";
|
||||
import { Users } from 'lucide-react';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
|
||||
interface LeadershipSectionProps {
|
||||
isDarkMode: boolean;
|
||||
textClasses: string;
|
||||
cardClasses: string;
|
||||
isOutOfCollege?: boolean;
|
||||
}
|
||||
|
||||
const LeadershipSection = ({
|
||||
isDarkMode,
|
||||
textClasses,
|
||||
cardClasses,
|
||||
}: LeadershipSectionProps) => {
|
||||
return (
|
||||
<section
|
||||
id="leadership"
|
||||
className={`py-20 ${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-r from-purple-900/20 to-pink-900/20"
|
||||
: "bg-gradient-to-r from-purple-100/60 to-pink-100/60"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-6xl px-6 mx-auto">
|
||||
<div className="mb-16 text-center">
|
||||
<h2 className="mb-4 text-4xl font-bold text-transparent bg-gradient-to-r from-purple-400 to-pink-400 bg-clip-text">
|
||||
📚 Leadership, Service & School
|
||||
</h2>
|
||||
<div className="w-24 h-1 mx-auto bg-gradient-to-r from-purple-400 to-pink-400"></div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-8 md:grid-cols-3">
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border border-white/10 hover:border-purple-400/50 transition-all duration-300 transform hover:scale-105`}
|
||||
>
|
||||
<Award className="mb-4 text-purple-400" size={40} />
|
||||
<h3 className="mb-3 text-xl font-bold text-purple-400">
|
||||
NJHS Inductee
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
National Junior Honor Society recognition for academic excellence,
|
||||
leadership, and community commitment.
|
||||
</p>
|
||||
const LeadershipSection: React.FC<LeadershipSectionProps> = ({ isOutOfCollege = false }) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<section className="mb-16">
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<Users className={`w-8 h-8 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-indigo-400' : 'text-indigo-600'
|
||||
}`} />
|
||||
<h2 className={`text-3xl font-bold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Leadership & Service
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border border-white/10 hover:border-pink-400/50 transition-all duration-300 transform hover:scale-105`}
|
||||
>
|
||||
<Users className="mb-4 text-pink-400" size={40} />
|
||||
<h3 className="mb-3 text-xl font-bold text-pink-400">Tutoring</h3>
|
||||
<p className={textClasses}>
|
||||
Volunteered regularly to tutor peers in math, science, and
|
||||
programming—fostering academic growth in others.
|
||||
</p>
|
||||
<div className={`rounded-2xl shadow-lg p-8 transition-all duration-300 ${
|
||||
theme === 'dark' ? 'bg-slate-800' : 'bg-white'
|
||||
}`}>
|
||||
<div className="grid gap-8 md:grid-cols-2">
|
||||
<div>
|
||||
<h3 className={`text-xl font-semibold mb-6 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Leadership Roles
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
NJHS Inductee
|
||||
</h4>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
National Junior Honor Society Inductee • 2024
|
||||
</p>
|
||||
<p className="text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Recognized for academic excellence, leadership, and
|
||||
community service in middle school
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
"Fabulous Falcon" Award
|
||||
</h4>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
Forestwood Middle School • 2024
|
||||
</p>
|
||||
<p className="text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Awarded for outstanding contributions to school community
|
||||
and leadership in student activities
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
Peer Learning Mentor
|
||||
</h4>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
Forestwood Middle School • 2023-2024
|
||||
</p>
|
||||
<p className="text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Mentored 50+ students in computer science fundamentals,
|
||||
fostering a collaborative learning environment
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{isOutOfCollege && (
|
||||
<div>
|
||||
<h3 className="mb-6 text-xl font-semibold transition-colors duration-300 text-slate-800 dark:text-white">
|
||||
Community Service
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h4 className="font-semibold transition-colors duration-300 text-slate-700 dark:text-slate-200">
|
||||
Code for Good Volunteer
|
||||
</h4>
|
||||
<p className="transition-colors duration-300 text-slate-600 dark:text-slate-300">
|
||||
2020-Present • 500+ hours
|
||||
</p>
|
||||
<p className="text-sm transition-colors duration-300 text-slate-600 dark:text-slate-400">
|
||||
Built digital solutions for 10+ nonprofits, impacting
|
||||
10,000+ lives
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border border-white/10 hover:border-yellow-400/50 transition-all duration-300 transform hover:scale-105`}
|
||||
>
|
||||
<Star className="mb-4 text-yellow-400" size={40} />
|
||||
<h3 className="mb-3 text-xl font-bold text-yellow-400">
|
||||
Fabulous Falcon Award
|
||||
</h3>
|
||||
<p className={textClasses}>
|
||||
Honored for outstanding school spirit, positive contributions to
|
||||
campus life, and consistent character.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default LeadershipSection;
|
||||
export default LeadershipSection;
|
||||
88
src/components/ReviewSection.tsx
Normal file
88
src/components/ReviewSection.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import { Star, Plus } from 'lucide-react';
|
||||
import { type JSX } from 'react';
|
||||
import { type Review } from '../reviewsApi';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
|
||||
interface Props {
|
||||
setShowModal: (show: boolean) => void;
|
||||
reviews: Review[];
|
||||
renderStars: (rating: number) => JSX.Element[];
|
||||
}
|
||||
|
||||
const ReviewSection: React.FC<Props> = ({ setShowModal, renderStars, reviews }) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<section className="mb-16">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<div className="flex items-center gap-3">
|
||||
<Star className={`w-8 h-8 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-indigo-400' : 'text-indigo-600'
|
||||
}`} />
|
||||
<h2 className={`text-3xl font-bold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Professional Reviews
|
||||
</h2>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setShowModal(true)}
|
||||
className="flex items-center gap-2 px-6 py-3 font-medium text-white transition-colors bg-indigo-600 rounded-lg hover:bg-indigo-700"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
Add Review
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
{reviews.length > 1 ? (
|
||||
reviews.map((review, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`rounded-2xl shadow-lg p-6 hover:shadow-xl transition-all duration-300 ${
|
||||
theme === 'dark' ? 'bg-slate-800' : 'bg-white'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className={`w-12 h-12 rounded-full flex items-center justify-center transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'bg-blue-900/30' : 'bg-blue-100'
|
||||
}`}>
|
||||
<Star className={`w-8 h-8 ${
|
||||
theme === 'dark' ? 'text-blue-400' : 'text-blue-600'
|
||||
}`} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className={`text-lg font-semibold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
{review.name}
|
||||
</h3>
|
||||
<p className={`text-sm transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-400' : 'text-slate-600'
|
||||
}`}>
|
||||
{review.position}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center mb-4">
|
||||
{renderStars(review.rating)}
|
||||
</div>
|
||||
<p className={`transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-300' : 'text-slate-700'
|
||||
}`}>{review.text}</p>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className={`col-span-full text-center rounded-2xl p-6 transition-colors duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'text-slate-400 bg-slate-700'
|
||||
: 'text-slate-500 bg-slate-100'
|
||||
}`}>
|
||||
No reviews yet. Be the first to add one!
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReviewSection;
|
||||
@@ -1,207 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { fetchReviews, addReview } from "../reviewsApi";
|
||||
import type { Review } from "../reviewsApi";
|
||||
import { Star } from "lucide-react";
|
||||
|
||||
const ReviewsSection = ({
|
||||
cardClasses,
|
||||
textClasses,
|
||||
isDarkMode,
|
||||
}: {
|
||||
cardClasses: string;
|
||||
textClasses: string;
|
||||
isDarkMode: boolean;
|
||||
}) => {
|
||||
const [reviews, setReviews] = useState<Review[]>([]);
|
||||
const [name, setName] = useState("");
|
||||
const [message, setMessage] = useState("");
|
||||
const [rating, setRating] = useState(5);
|
||||
const [hoverRating, setHoverRating] = useState(0);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [success, setSuccess] = useState("");
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchReviews().then(setReviews);
|
||||
}, []);
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
setError("");
|
||||
setSuccess("");
|
||||
try {
|
||||
await addReview({ name, message, rating });
|
||||
setSuccess("Review submitted!");
|
||||
setName("");
|
||||
setMessage("");
|
||||
setRating(5);
|
||||
setReviews(await fetchReviews());
|
||||
// Close modal immediately after successful submission
|
||||
setIsModalOpen(false);
|
||||
} catch (err) {
|
||||
setError("Failed to submit review.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const openModal = () => {
|
||||
setIsModalOpen(true);
|
||||
setError("");
|
||||
setSuccess("");
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="reviews" className="py-20">
|
||||
<div className="max-w-3xl mx-auto px-4">
|
||||
<h2 className="text-3xl font-bold mb-8 text-center text-transparent bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text">
|
||||
Reviews
|
||||
</h2>
|
||||
|
||||
<div className="flex justify-center mb-8">
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="px-6 py-3 rounded-lg bg-gradient-to-r from-cyan-400 to-purple-400 text-white font-semibold shadow-lg hover:from-purple-400 hover:to-cyan-400 transition-colors transform hover:scale-105 duration-500"
|
||||
>
|
||||
Add Your Review
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Review Modal */}
|
||||
{isModalOpen && (
|
||||
<div className="fixed inset-0 flex items-center justify-center z-50 bg-black/50 backdrop-blur-sm">
|
||||
<div
|
||||
className={`relative w-full max-w-md p-6 rounded-xl border ${cardClasses} animate-fade-in-up`}
|
||||
>
|
||||
<button
|
||||
onClick={() => setIsModalOpen(false)}
|
||||
className="absolute top-4 right-4 text-gray-400 hover:text-gray-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<h3 className="text-xl font-bold mb-4 text-transparent bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text">
|
||||
Share Your Review
|
||||
</h3>{" "}
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
||||
<input
|
||||
className={`p-3 rounded border focus:outline-none ${
|
||||
isDarkMode
|
||||
? "bg-slate-800 text-white border-white/10"
|
||||
: "bg-white text-gray-900 border-gray-300"
|
||||
}`}
|
||||
placeholder="Your Name"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<div className="mb-2">
|
||||
<label className="block text-sm mb-1">Your Rating</label>
|
||||
<div className="flex gap-1">
|
||||
{[1, 2, 3, 4, 5].map((star) => (
|
||||
<button
|
||||
key={star}
|
||||
type="button"
|
||||
onClick={() => setRating(star)}
|
||||
onMouseEnter={() => setHoverRating(star)}
|
||||
onMouseLeave={() => setHoverRating(0)}
|
||||
className="transition-transform hover:scale-110"
|
||||
>
|
||||
<Star
|
||||
size={24}
|
||||
fill={
|
||||
(hoverRating || rating) >= star ? "#38BDF8" : "none"
|
||||
}
|
||||
color={
|
||||
(hoverRating || rating) >= star
|
||||
? "#38BDF8"
|
||||
: "#9CA3AF"
|
||||
}
|
||||
className="transition-colors duration-200"
|
||||
/>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<textarea
|
||||
className={`p-3 rounded border focus:outline-none ${
|
||||
isDarkMode
|
||||
? "bg-slate-800 text-white border-white/10"
|
||||
: "bg-white text-gray-900 border-gray-300"
|
||||
}`}
|
||||
placeholder="Your Review"
|
||||
value={message}
|
||||
onChange={(e) => setMessage(e.target.value)}
|
||||
required
|
||||
rows={3}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-6 py-2 rounded bg-gradient-to-r from-cyan-400 to-purple-400 text-white font-semibold shadow-md hover:from-purple-400 hover:to-cyan-400 transition-colors duration-500"
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? "Submitting..." : "Submit Review"}
|
||||
</button>
|
||||
{error && <p className="text-red-500 text-sm mt-2">{error}</p>}
|
||||
{success && (
|
||||
<p className="text-green-500 text-sm mt-2">{success}</p>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-6">
|
||||
{reviews.length === 0 && (
|
||||
<p className={textClasses + " text-center"}>
|
||||
No reviews yet. Be the first!
|
||||
</p>
|
||||
)}
|
||||
{reviews.map((review) => (
|
||||
<div
|
||||
key={review.id}
|
||||
className={`p-5 rounded-xl border ${cardClasses} transition-all duration-300 transform hover:scale-105 hover:shadow-xl hover:border-cyan-400/70`}
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center">
|
||||
<span className="font-semibold mr-2 text-cyan-400">
|
||||
{review.name}
|
||||
</span>
|
||||
<span className="text-xs text-gray-400">
|
||||
{review.createdAt?.toDate?.().toLocaleString?.() || ""}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex">
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
size={16}
|
||||
fill={i < (review.rating || 5) ? "#38BDF8" : "none"}
|
||||
color={i < (review.rating || 5) ? "#38BDF8" : "#9CA3AF"}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className={textClasses}>{review.message}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReviewsSection;
|
||||
@@ -1,166 +1,199 @@
|
||||
import { Code, Trophy, Cloud } from "lucide-react";
|
||||
import { Briefcase } from "lucide-react";
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
|
||||
interface TechSectionProps {
|
||||
isDarkMode: boolean;
|
||||
textClasses: string;
|
||||
cardClasses: string;
|
||||
isOutOfCollege?: boolean;
|
||||
}
|
||||
|
||||
const TechSection = ({
|
||||
isDarkMode,
|
||||
textClasses,
|
||||
cardClasses,
|
||||
}: TechSectionProps) => {
|
||||
return (
|
||||
<section id="tech" className="py-20">
|
||||
<div className="max-w-6xl px-6 mx-auto">
|
||||
<div className="mb-16 text-center">
|
||||
<h2 className="mb-4 text-4xl font-bold text-transparent bg-gradient-to-r from-cyan-400 to-green-400 bg-clip-text">
|
||||
⚙️ Tech, Innovation & Projects
|
||||
</h2>
|
||||
<div className="w-24 h-1 mx-auto bg-gradient-to-r from-cyan-400 to-green-400"></div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-8">
|
||||
{" "}
|
||||
<div
|
||||
className={`${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-r from-cyan-900/20 to-blue-900/20"
|
||||
: "bg-gradient-to-r from-cyan-100/40 to-blue-100/40"
|
||||
} backdrop-blur-lg rounded-xl p-8 border ${
|
||||
isDarkMode ? "border-cyan-400/30" : "border-cyan-300/50"
|
||||
} transition-all duration-300 transform hover:scale-105 hover:shadow-xl hover:border-cyan-400/70`}
|
||||
>
|
||||
<div className="flex items-center mb-4">
|
||||
<Code className="mr-3 text-cyan-400" size={30} />
|
||||
<a
|
||||
className="text-2xl font-bold text-cyan-400"
|
||||
href="https://ialfm-attendance.netlify.app/"
|
||||
>
|
||||
Sunday School Attendance App
|
||||
</a>
|
||||
<span className="px-3 py-1 ml-3 text-sm text-green-400 rounded-full bg-green-500/20">
|
||||
In Production
|
||||
</span>
|
||||
</div>
|
||||
<p className={`${textClasses} mb-4`}>
|
||||
Architecting and building a fully functional, community-oriented
|
||||
app, designed for a local community center. Handling everything
|
||||
from UI/UX design to back-end integration.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{["React Native", "UI/UX Design", "Backend Integration"].map(
|
||||
(tech) => (
|
||||
<span
|
||||
key={tech}
|
||||
className="px-3 py-1 text-sm rounded-full bg-cyan-400/20 text-cyan-400"
|
||||
>
|
||||
{tech}
|
||||
</span>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-r from-blue-900/20 to-indigo-900/20"
|
||||
: "bg-gradient-to-r from-blue-100/40 to-indigo-100/40"
|
||||
} backdrop-blur-lg rounded-xl p-8 border ${
|
||||
isDarkMode ? "border-blue-400/30" : "border-blue-300/50"
|
||||
} transition-all duration-300 transform hover:scale-105 hover:shadow-xl hover:border-blue-400/70`}
|
||||
>
|
||||
<div className="flex items-center mb-4">
|
||||
<Cloud className="mr-3 text-blue-400" size={30} />
|
||||
<a
|
||||
className="text-2xl font-bold text-blue-400"
|
||||
href="https://sunscope.netlify.app"
|
||||
>
|
||||
Sunscope
|
||||
</a>
|
||||
<span className="px-3 py-1 ml-3 text-sm text-blue-400 rounded-full bg-blue-500/20">
|
||||
Weather Application
|
||||
</span>
|
||||
</div>
|
||||
<p className={`${textClasses} mb-4`}>
|
||||
Developed a weather application that provides real-time weather
|
||||
updates, forecasts, and alerts using WeatherAPI's API, showcasing
|
||||
my skills in API integration and responsive design.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={`${
|
||||
isDarkMode
|
||||
? "bg-gradient-to-r from-purple-900/20 to-pink-900/20"
|
||||
: "bg-gradient-to-r from-purple-100/40 to-pink-100/40"
|
||||
} backdrop-blur-lg rounded-xl p-8 border ${
|
||||
isDarkMode ? "border-purple-400/30" : "border-purple-300/50"
|
||||
} transition-all duration-300 transform hover:scale-105 hover:shadow-xl hover:border-purple-400/70`}
|
||||
>
|
||||
<div className="flex items-center mb-4">
|
||||
<Trophy className="mr-3 text-purple-400" size={30} />
|
||||
<h3 className="text-2xl font-bold text-purple-400">
|
||||
Competitive Robotics
|
||||
</h3>
|
||||
<span className="px-3 py-1 ml-3 text-sm text-yellow-400 rounded-full bg-yellow-500/20">
|
||||
Award Winner
|
||||
</span>
|
||||
</div>{" "}
|
||||
<p className={`${textClasses} mb-4`}>
|
||||
Core contributor on an RC Robotics Team, earned the "Plethora of
|
||||
Features" award by integrating remarkable range of
|
||||
capabilities—demonstrating versatility and innovation.
|
||||
</p>
|
||||
const TechSection: React.FC<TechSectionProps> = ({ isOutOfCollege = false }) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<section className="mb-16">
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<Briefcase className={`w-8 h-8 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-indigo-400' : 'text-indigo-600'
|
||||
}`} />
|
||||
<h2 className={`text-3xl font-bold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Technology & Innovation
|
||||
</h2>
|
||||
</div>
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
{" "}
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border border-white/10 transition-all duration-300 transform hover:scale-105 hover:shadow-lg hover:border-green-400/70`}
|
||||
>
|
||||
<h4 className="mb-3 text-lg font-bold text-green-400">
|
||||
Programming Skills
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{[
|
||||
"Python",
|
||||
"React",
|
||||
"React Native",
|
||||
"Tailwind CSS",
|
||||
"Javascript",
|
||||
"APIs",
|
||||
"AI Integration",
|
||||
"UI/UX Design",
|
||||
"Docker Containers",
|
||||
"Git",
|
||||
"Virtualization",
|
||||
].map((skill) => (
|
||||
<span
|
||||
key={skill}
|
||||
className="px-3 py-1 text-sm text-green-400 rounded-full bg-green-400/20 transition-all duration-300 hover:bg-green-400/40 hover:scale-105 inline-block"
|
||||
<div className={`rounded-2xl shadow-lg p-6 transition-all duration-300 ${
|
||||
theme === 'dark' ? 'bg-slate-800' : 'bg-white'
|
||||
}`}>
|
||||
<h3 className={`text-xl font-semibold mb-4 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Featured Projects
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div className={`border-l-4 pl-4 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'border-blue-400' : 'border-blue-500'
|
||||
}`}>
|
||||
<a
|
||||
href="https://ialfm-attendance.netlify.app"
|
||||
className={`font-semibold transition-colors duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'text-slate-200 hover:text-blue-400'
|
||||
: 'text-slate-700 hover:text-blue-600'
|
||||
}`}
|
||||
>
|
||||
{skill}
|
||||
</span>
|
||||
))}
|
||||
Local School Attendance App
|
||||
</a>
|
||||
<p className={`text-sm mb-2 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-400' : 'text-slate-600'
|
||||
}`}>
|
||||
Lead Developer | 2025
|
||||
</p>
|
||||
<p className={`transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-300' : 'text-slate-600'
|
||||
}`}>
|
||||
Developed and deployed a comprehensive attendance management
|
||||
system for a local educational institution, streamlining
|
||||
their administrative processes and improving data accuracy.
|
||||
The application continues to serve the organization daily,
|
||||
demonstrating successful long-term solution delivery.
|
||||
</p>
|
||||
</div>
|
||||
{isOutOfCollege && (
|
||||
<div className={`border-l-4 pl-4 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'border-green-400' : 'border-green-500'
|
||||
}`}>
|
||||
<h4 className={`font-semibold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-200' : 'text-slate-700'
|
||||
}`}>Sun-Scope</h4>
|
||||
<p className={`text-sm mb-2 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-400' : 'text-slate-600'
|
||||
}`}>
|
||||
Full-Stack Engineer | 2025
|
||||
</p>
|
||||
<p className={`transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-300' : 'text-slate-600'
|
||||
}`}>
|
||||
Built IoT solution reducing energy consumption by 35%
|
||||
across 200+ commercial buildings
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className={`border-l-4 pl-4 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'border-purple-400' : 'border-purple-500'
|
||||
}`}>
|
||||
<a
|
||||
href="https://i-dazzle.netlify.app"
|
||||
className={`font-semibold transition-colors duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'text-slate-200 hover:text-purple-400'
|
||||
: 'text-slate-700 hover:text-purple-600'
|
||||
}`}
|
||||
>
|
||||
I-Dazzle E-Commerce Platform
|
||||
</a>
|
||||
<p className={`text-sm mb-2 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-400' : 'text-slate-600'
|
||||
}`}>
|
||||
Technical Lead | 2025
|
||||
</p>
|
||||
<p className={`transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-300' : 'text-slate-600'
|
||||
}`}>
|
||||
Architected and developed a custom e-commerce platform for a
|
||||
luxury bag retailer, enabling direct-to-consumer sales and
|
||||
reducing third-party marketplace dependency. Implemented
|
||||
responsive design, secure payment processing, and inventory
|
||||
management features to support business growth and brand
|
||||
independence.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`rounded-2xl shadow-lg p-6 transition-all duration-300 ${
|
||||
theme === 'dark' ? 'bg-slate-800' : 'bg-white'
|
||||
}`}>
|
||||
<h3 className={`text-xl font-semibold mb-4 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Technical Skills
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h4 className={`font-semibold mb-2 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-200' : 'text-slate-700'
|
||||
}`}>
|
||||
Programming Languages
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{["Python", "JavaScript", "TypeScript"].map((skill) => (
|
||||
<span
|
||||
key={skill}
|
||||
className={`px-3 py-1 rounded-full text-sm font-medium transition-colors duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'bg-blue-900/30 text-blue-300'
|
||||
: 'bg-blue-100 text-blue-800'
|
||||
}`}
|
||||
>
|
||||
{skill}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className={`font-semibold mb-2 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-200' : 'text-slate-700'
|
||||
}`}>
|
||||
Frameworks & Tools
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{[
|
||||
"React",
|
||||
"React Native",
|
||||
"Docker",
|
||||
"React Native",
|
||||
"TailwindCSS",
|
||||
].map((skill) => (
|
||||
<span
|
||||
key={skill}
|
||||
className={`px-3 py-1 rounded-full text-sm font-medium transition-colors duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'bg-green-900/30 text-green-300'
|
||||
: 'bg-green-100 text-green-800'
|
||||
}`}
|
||||
>
|
||||
{skill}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{isOutOfCollege && (
|
||||
<div>
|
||||
<h4 className={`font-semibold mb-2 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-200' : 'text-slate-700'
|
||||
}`}>
|
||||
Specializations
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{["UI/UX Design", ""].map((skill) => (
|
||||
<span
|
||||
key={skill}
|
||||
className={`px-3 py-1 rounded-full text-sm font-medium transition-colors duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'bg-purple-900/30 text-purple-300'
|
||||
: 'bg-purple-100 text-purple-800'
|
||||
}`}
|
||||
>
|
||||
{skill}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>{" "}
|
||||
<div
|
||||
className={`${cardClasses} rounded-xl p-6 border border-white/10 transition-all duration-300 transform hover:scale-105 hover:shadow-lg hover:border-orange-400/70`}
|
||||
>
|
||||
<h4 className="mb-3 text-lg font-bold text-orange-400">
|
||||
Striker Competition
|
||||
</h4>
|
||||
<p className={`${textClasses}`}>
|
||||
Engineered a realistic operating room prototype showcased at the
|
||||
Stryker Competition, demonstrating advanced surgical workflow
|
||||
design and innovation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default TechSection;
|
||||
export default TechSection;
|
||||
89
src/components/UniqueSection.tsx
Normal file
89
src/components/UniqueSection.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import { Award, Zap, Users, Briefcase } from 'lucide-react';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
|
||||
const UniqueSection: React.FC = () => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<section className="mb-16">
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<Zap className={`w-8 h-8 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-indigo-400' : 'text-indigo-600'
|
||||
}`} />
|
||||
<h2 className={`text-3xl font-bold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
What Makes Me Unique
|
||||
</h2>
|
||||
</div>
|
||||
<div className={`rounded-2xl shadow-lg p-8 border-l-4 transition-all duration-300 ${
|
||||
theme === 'dark'
|
||||
? 'bg-slate-800 border-indigo-400'
|
||||
: 'bg-white border-indigo-500'
|
||||
}`}>
|
||||
<p className={`text-lg leading-relaxed mb-6 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-200' : 'text-slate-700'
|
||||
}`}>
|
||||
I bridge the gap between cutting-edge technology and real-world
|
||||
impact. With a unique combination of technical expertise,
|
||||
entrepreneurial mindset, and leadership experience, I transform
|
||||
complex problems into elegant solutions that drive meaningful
|
||||
change.
|
||||
</p>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<div className="text-center">
|
||||
<div className={`w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-3 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'bg-blue-900/30' : 'bg-blue-100'
|
||||
}`}>
|
||||
<Award className={`w-8 h-8 ${theme === 'dark' ? 'text-blue-400' : 'text-blue-600'}`} />
|
||||
</div>
|
||||
<h3 className={`font-semibold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Innovation Driver
|
||||
</h3>
|
||||
<p className={`text-sm transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-300' : 'text-slate-600'
|
||||
}`}>
|
||||
Transforming ideas into scalable solutions
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className={`w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-3 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'bg-green-900/30' : 'bg-green-100'
|
||||
}`}>
|
||||
<Users className={`w-8 h-8 ${theme === 'dark' ? 'text-green-400' : 'text-green-600'}`} />
|
||||
</div>
|
||||
<h3 className={`font-semibold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>Team Catalyst</h3>
|
||||
<p className={`text-sm transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-300' : 'text-slate-600'
|
||||
}`}>
|
||||
Inspiring collaboration and excellence
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className={`w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-3 transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'bg-purple-900/30' : 'bg-purple-100'
|
||||
}`}>
|
||||
<Briefcase className={`w-8 h-8 ${theme === 'dark' ? 'text-purple-400' : 'text-purple-600'}`} />
|
||||
</div>
|
||||
<h3 className={`font-semibold transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-white' : 'text-slate-800'
|
||||
}`}>
|
||||
Results Focused
|
||||
</h3>
|
||||
<p className={`text-sm transition-colors duration-300 ${
|
||||
theme === 'dark' ? 'text-slate-300' : 'text-slate-600'
|
||||
}`}>
|
||||
Delivering measurable impact consistently
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default UniqueSection;
|
||||
73
src/contexts/ThemeContext.tsx
Normal file
73
src/contexts/ThemeContext.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
|
||||
type Theme = "light" | "dark";
|
||||
|
||||
interface ThemeContextType {
|
||||
theme: Theme;
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
||||
|
||||
export const useTheme = () => {
|
||||
const context = useContext(ThemeContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useTheme must be used within a ThemeProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
interface ThemeProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
|
||||
const [theme, setTheme] = useState<Theme>(() => {
|
||||
// Check if there's a saved theme in localStorage
|
||||
const savedTheme = localStorage.getItem("theme") as Theme;
|
||||
if (savedTheme) {
|
||||
return savedTheme;
|
||||
}
|
||||
// Otherwise, check system preference
|
||||
return window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light";
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// Save theme to localStorage
|
||||
localStorage.setItem("theme", theme);
|
||||
|
||||
// Apply theme CSS custom properties to document
|
||||
const root = document.documentElement;
|
||||
if (theme === "dark") {
|
||||
root.style.setProperty("--bg-primary", "#0f172a"); // slate-900
|
||||
root.style.setProperty("--bg-secondary", "#1e293b"); // slate-800
|
||||
root.style.setProperty("--bg-tertiary", "#334155"); // slate-700
|
||||
root.style.setProperty("--text-primary", "#ffffff");
|
||||
root.style.setProperty("--text-secondary", "#cbd5e1"); // slate-300
|
||||
root.style.setProperty("--text-tertiary", "#94a3b8"); // slate-400
|
||||
root.style.setProperty("--border-color", "#475569"); // slate-600
|
||||
root.style.setProperty("--accent-color", "#6366f1"); // indigo-500
|
||||
} else {
|
||||
root.style.setProperty("--bg-primary", "#f8fafc"); // slate-50
|
||||
root.style.setProperty("--bg-secondary", "#ffffff");
|
||||
root.style.setProperty("--bg-tertiary", "#f1f5f9"); // slate-100
|
||||
root.style.setProperty("--text-primary", "#0f172a"); // slate-900
|
||||
root.style.setProperty("--text-secondary", "#334155"); // slate-700
|
||||
root.style.setProperty("--text-tertiary", "#64748b"); // slate-500
|
||||
root.style.setProperty("--border-color", "#e2e8f0"); // slate-200
|
||||
root.style.setProperty("--accent-color", "#4f46e5"); // indigo-600
|
||||
}
|
||||
}, [theme]);
|
||||
|
||||
const toggleTheme = () => {
|
||||
setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, toggleTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -1 +1,51 @@
|
||||
@import "tailwindcss";
|
||||
@import "tailwindcss";
|
||||
|
||||
/* Theme CSS Variables */
|
||||
:root {
|
||||
--bg-primary: #f8fafc;
|
||||
--bg-secondary: #ffffff;
|
||||
--bg-tertiary: #f1f5f9;
|
||||
--text-primary: #0f172a;
|
||||
--text-secondary: #334155;
|
||||
--text-tertiary: #64748b;
|
||||
--border-color: #e2e8f0;
|
||||
--accent-color: #4f46e5;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Custom theme classes */
|
||||
.theme-bg-primary {
|
||||
background-color: var(--bg-primary);
|
||||
}
|
||||
|
||||
.theme-bg-secondary {
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.theme-bg-tertiary {
|
||||
background-color: var(--bg-tertiary);
|
||||
}
|
||||
|
||||
.theme-text-primary {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.theme-text-secondary {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.theme-text-tertiary {
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.theme-border {
|
||||
border-color: var(--border-color);
|
||||
}
|
||||
|
||||
.theme-accent {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.theme-bg-accent {
|
||||
background-color: var(--accent-color);
|
||||
}
|
||||
19
src/main.tsx
19
src/main.tsx
@@ -1,10 +1,13 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import App from './App.tsx'
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App.tsx";
|
||||
import { ThemeProvider } from "./contexts/ThemeContext.tsx";
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
<ThemeProvider>
|
||||
<App />
|
||||
</ThemeProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
import { db } from '../firebase';
|
||||
import { collection, getDocs, addDoc, Timestamp } from 'firebase/firestore';
|
||||
import { collection, getDocs, addDoc } from 'firebase/firestore';
|
||||
|
||||
export type Review = {
|
||||
id?: string;
|
||||
name: string;
|
||||
message: string;
|
||||
rating: number;
|
||||
createdAt?: Timestamp;
|
||||
position: string;
|
||||
text: string;
|
||||
};
|
||||
|
||||
const reviewsCollection = collection(db, 'reviews');
|
||||
|
||||
export async function fetchReviews(): Promise<Review[]> {
|
||||
const snapshot = await getDocs(reviewsCollection);
|
||||
return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() } as Review));
|
||||
return snapshot.docs.map(doc => doc.data() as Review);
|
||||
}
|
||||
|
||||
export async function addReview(review: Omit<Review, 'id' | 'createdAt'>): Promise<void> {
|
||||
await addDoc(reviewsCollection, {
|
||||
...review,
|
||||
createdAt: Timestamp.now(),
|
||||
});
|
||||
export async function addReview(review: Review): Promise<void> {
|
||||
await addDoc(reviewsCollection, review);
|
||||
}
|
||||
|
||||
7
tailwind.config.js
Normal file
7
tailwind.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
darkMode: 'class',
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user