diff --git a/package-lock.json b/package-lock.json index b9f48bf..62b9509 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@tailwindcss/vite": "^4.1.13", "axios": "^1.12.2", "framer-motion": "^12.23.22", + "lucide-react": "^0.545.0", "react": "^19.1.1", "react-dom": "^19.1.1", "react-icons": "^5.5.0", @@ -61,7 +62,6 @@ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -1611,7 +1611,6 @@ "integrity": "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -1653,7 +1652,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1776,7 +1774,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", @@ -2130,7 +2127,6 @@ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3046,6 +3042,14 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.545.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.545.0.tgz", + "integrity": "sha512-7r1/yUuflQDSt4f1bpn5ZAocyIxcTyVyBBChSVtBKn5M+392cPmI5YJMWOJKk/HUWGm5wg83chlAZtCcGbEZtw==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/magic-string": { "version": "0.30.19", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", @@ -3282,7 +3286,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3349,7 +3352,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3359,7 +3361,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -3694,7 +3695,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.6.tgz", "integrity": "sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", diff --git a/package.json b/package.json index e11b239..bfcb360 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@tailwindcss/vite": "^4.1.13", "axios": "^1.12.2", "framer-motion": "^12.23.22", + "lucide-react": "^0.545.0", "react": "^19.1.1", "react-dom": "^19.1.1", "react-icons": "^5.5.0", diff --git a/src/components/ui/About.jsx b/src/components/ui/About.jsx index af3e13c..cd70511 100644 --- a/src/components/ui/About.jsx +++ b/src/components/ui/About.jsx @@ -1,26 +1,344 @@ import { motion } from 'framer-motion'; +import { useState } from 'react'; +import { Code2, Lightbulb, Users2, Rocket } from 'lucide-react'; + +// Feature card component +function FeatureCard({ icon: Icon, title, description, index }) { + const [isHovered, setIsHovered] = useState(false); + + return ( + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + className="relative group" + > + + + + + +

{title}

+

{description}

+ + {/* Corner glow */} + + +
+ ); +} + +// Floating code snippets background +function FloatingCodeSnippets() { + const codeSnippets = [ + '{ }', + '< />', + '( )', + '=>', + '===', + 'fn()', + '[ ]', + '...', + ]; + + return ( +
+ {codeSnippets.map((snippet, i) => ( + + {snippet} + + ))} +
+ ); +} + +// Animated text highlight +function AnimatedHighlight({ children, delay = 0 }) { + return ( + + {children} + + ); +} function About() { + const features = [ + { + icon: Code2, + title: "Share Your Code Journey", + description: "Document wins, fails, and those 3AM debugging victories" + }, + { + icon: Lightbulb, + title: "Drop Knowledge Bombs", + description: "Write tutorials that actually make sense to real developers" + }, + { + icon: Users2, + title: "Vibe With Your Tribe", + description: "Connect with devs who get your semicolon struggles" + }, + { + icon: Rocket, + title: "Launch Your Ideas", + description: "Share breakthrough moments when everything finally clicks" + } + ]; + return ( -
-
+
+ {/* Background effects */} + + + {/* Gradient orbs */} + + + +
+ {/* Main content */} + + {/* Tag label */} + + About Us + + + + {/* Animated title */} + -

+ A Blog Platform That Actually Gets It -

-

- HackerBlog is lowkey the blog platform developers have been waiting for. Share your coding wins and fails, drop tutorials that actually make sense, spill the tea on programming concepts, and vibe with a community that gets your semicolon struggles. Whether you're documenting your coding journey or sharing that breakthrough moment when everything finally clicks - we're here for it! ✨ + + + + {/* Description with staggered animation */} + +

+ HackerBlog is lowkey the blog platform developers have been waiting for. + Share your coding wins and fails, drop tutorials that actually make sense, spill the tea on programming concepts, + and vibe with a community that gets your semicolon struggles.

+ + Whether you're documenting your coding journey or sharing that breakthrough moment when everything finally clicks - + we're here for it! + + ✨ + +
+ + + {/* Feature cards grid */} +
+ {features.map((feature, index) => ( + + ))}
-
- ) + + {/* Stats section */} + + {/* Animated border glow */} + + +
+ + Built by developers, for developers + + + No fluff, no corporate speak, just a straightforward platform where you can share your code, + your struggles, and your victories with people who actually understand. + + + {/* Decorative code line */} + +
+
+ + {/* Bottom decorative elements */} + + {[0, 1, 2, 3, 4].map((i) => ( + + ))} + +
+ + {/* Corner accents */} +
+
+
+ ); } -export default About \ No newline at end of file +export default About; \ No newline at end of file diff --git a/src/components/ui/Community.jsx b/src/components/ui/Community.jsx index e15982b..ac0ac86 100644 --- a/src/components/ui/Community.jsx +++ b/src/components/ui/Community.jsx @@ -1,56 +1,292 @@ -import {useState} from "react"; -import InfoCard from "./InfoCard"; +import { useState } from "react"; import { motion } from "framer-motion"; -import { - FiPenTool, - FiUsers, - FiSend, -} from "react-icons/fi"; -import { useNavigate } from "react-router-dom"; +import { PenTool, Users, Send } from "lucide-react"; + +// Enhanced InfoCard with advanced animations and effects +function InfoCard({ icon, title, description, index }) { + const [isHovered, setIsHovered] = useState(false); + + return ( + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + className="relative group" + > + {/* Glowing border effect */} + + + {/* Card content */} +
+ {/* Animated icon container */} + + + {icon} + + + {/* Title with gradient on hover */} + + {title} + + +

+ {description} +

+ + {/* Animated corner accent */} + +
+
+ ); +} + +// Animated particles for background +function BackgroundParticles() { + const particles = Array.from({ length: 15 }, (_, i) => ({ + id: i, + x: Math.random() * 100, + y: Math.random() * 100, + size: Math.random() * 3 + 1, + duration: Math.random() * 15 + 10, + delay: Math.random() * 5, + })); + + return ( +
+ {particles.map((particle) => ( + + ))} +
+ ); +} + +// Stats counter animation +function AnimatedStat({ value, label, delay }) { + const [count, setCount] = useState(0); + + return ( + { + let start = 0; + const end = parseInt(value); + const duration = 2000; + const increment = end / (duration / 16); + + const timer = setInterval(() => { + start += increment; + if (start >= end) { + setCount(end); + clearInterval(timer); + } else { + setCount(Math.floor(start)); + } + }, 16); + }} + className="text-center" + > +
+ {count}+ +
+
{label}
+
+ ); +} function Community() { - const [userProfile] = useState(null); // user state, if they dont exist... no need to show start your journey CTA - const navigate=useNavigate(); + const [userProfile] = useState(null); const infoArray = [ { - icon: , + icon: , title: "Document Your Wins & Fails", description: "Share your coding journey - the plot twists, breakthroughs, and those 3AM debugging sessions", }, { - icon: , + icon: , title: "Find Your Code Besties", description: "Network with developers who speak your language and maybe find your next collab partner", }, { - icon: , + icon: , title: "Show Off Your Projects", description: "Display your portfolio and get that validation you deserve from people who actually understand", }, ]; + + function handleRedirect(value) { + console.log(`Navigating to: ${value}`); + } + return ( -
-
+
+ {/* Background effects */} + + + {/* Grid overlay */} +
+ + {/* Animated gradient orbs */} + + + +
+ {/* Header section */} + + + + Join Now + + + + + Join Our Growing Community + + ✨ + + + + + Whether you're here to flex your latest project, learn from the pros, or just vibe with like-minded devs + + + + {/* Stats section */} -

- Join Our Growing Community ✨ -

-

- Whether you're here to flex your latest project, learn from the - pros... -

+ + +
-
+ {/* Info cards */} +
{infoArray.map((info, index) => ( + {/* CTA section */} {!userProfile && ( -

- Ready to level up your developer game? Let's go! 🎮 -

+ {/* Glow effect behind CTA */} + + + + Ready to level up your developer game? Let's go! + + 🎮 + + + navigate("/register")} + animate={{ + boxShadow: [ + "0 0 20px rgba(160, 160, 255, 0.3)", + "0 0 40px rgba(160, 160, 255, 0.6)", + "0 0 20px rgba(160, 160, 255, 0.3)", + ], + }} + transition={{ + boxShadow: { duration: 2, repeat: Infinity, ease: "easeInOut" }, + }} + className="relative font-mono px-10 sm:px-12 py-5 sm:py-6 bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-lg font-bold text-lg sm:text-xl shadow-2xl overflow-hidden group" + onClick={() => handleRedirect("register")} > - Start Your Journey + {/* Animated shine effect */} + + + Start Your Journey + + {/* Arrow animation */} + + → + + + {/* Decorative elements */} + + {[0, 1, 2].map((i) => ( + + ))} + )}
+ + {/* Bottom corner accent */} +
); } -export default Community; +export default Community; \ No newline at end of file diff --git a/src/components/ui/Hero.jsx b/src/components/ui/Hero.jsx index 4e6bb6f..7aa0262 100644 --- a/src/components/ui/Hero.jsx +++ b/src/components/ui/Hero.jsx @@ -1,68 +1,194 @@ -import { motion } from "framer-motion"; -import { useState } from "react"; -import HeroAnimation from "../animations/HeroAnimation"; -import { useNavigate } from "react-router-dom"; +import { motion, useAnimation } from "framer-motion"; +import { useState, useEffect } from "react"; + +// Lightweight typewriter hook +function useTypewriter(words, typingSpeed = 150, deletingSpeed = 100, pauseDuration = 2000) { + const [displayText, setDisplayText] = useState(""); + const [wordIndex, setWordIndex] = useState(0); + const [isDeleting, setIsDeleting] = useState(false); + + useEffect(() => { + const currentWord = words[wordIndex]; + + const timer = setTimeout(() => { + if (!isDeleting) { + if (displayText.length < currentWord.length) { + setDisplayText(currentWord.slice(0, displayText.length + 1)); + } else { + setTimeout(() => setIsDeleting(true), pauseDuration); + } + } else { + if (displayText.length > 0) { + setDisplayText(currentWord.slice(0, displayText.length - 1)); + } else { + setIsDeleting(false); + setWordIndex((prev) => (prev + 1) % words.length); + } + } + }, isDeleting ? deletingSpeed : typingSpeed); + + return () => clearTimeout(timer); + }, [displayText, isDeleting, wordIndex, words, typingSpeed, deletingSpeed, pauseDuration]); + + return displayText; +} + +// Floating particles component +function FloatingParticles() { + const particles = Array.from({ length: 20 }, (_, i) => ({ + id: i, + x: Math.random() * 100, + y: Math.random() * 100, + size: Math.random() * 4 + 2, + duration: Math.random() * 20 + 10, + delay: Math.random() * 5, + })); + + return ( +
+ {particles.map((particle) => ( + + ))} +
+ ); +} + +// Animated gradient background +function AnimatedGradient() { + return ( +
+ +
+ ); +} + +// Scroll indicator +function ScrollIndicator() { + return ( + + + + + + ↓ + + + ); +} function Hero() { const [userProfile] = useState(null); + const phrases = ["Code.", "Create.", "Connect."]; + const typedText = useTypewriter(phrases, 120, 80, 1500); const containerVariants = { hidden: { opacity: 0 }, visible: { opacity: 1, - transition: { staggerChildren: 0.2 }, + transition: { staggerChildren: 0.15, delayChildren: 0.2 }, }, }; const itemVariants = { - hidden: { opacity: 0, y: 20 }, + hidden: { opacity: 0, y: 30 }, visible: { opacity: 1, y: 0, - transition: { duration: 0.5 }, + transition: { duration: 0.6, ease: "easeOut" }, }, }; - const navigate=useNavigate(); + const glowVariants = { + animate: { + boxShadow: [ + "0 0 20px rgba(160, 160, 255, 0.3)", + "0 0 40px rgba(160, 160, 255, 0.6)", + "0 0 20px rgba(160, 160, 255, 0.3)", + ], + }, + }; - function handleRedirect(value){ - if(value==="register"){navigate("/register")} - else if(value==="login"){navigate("/login")} - else{navigate("/dashboard")} + function handleRedirect(value) { + console.log(`Navigating to: ${value}`); } return ( -
- {/* top animation */} - - - {/* bottom animation */} - +
+ {/* Animated gradient background */} + + + {/* Floating particles */} + - {/* subtle central animation effect */} -
- -
+ {/* Grid overlay for hacker aesthetic */} +
- {/* hero contents */} + {/* Hero content */} HackerBlog + + {/* Typewriter subtitle */} + + > + {typedText} + + _ + + Where developers share stories, insights, and code - no cap! 🔥 @@ -90,52 +246,64 @@ function Hero() { {!userProfile ? ( handleRedirect("register")} + variants={glowVariants} + animate="animate" + transition={{ + boxShadow: { duration: 2, repeat: Infinity, ease: "easeInOut" }, + }} + className="font-mono w-full sm:w-auto px-8 sm:px-10 py-4 sm:py-5 bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-lg font-bold text-base sm:text-lg shadow-xl relative overflow-hidden group" + onClick={() => handleRedirect("register")} > - Get Started + + Get Started + handleRedirect("login")} + className="font-mono w-full sm:w-auto px-8 sm:px-10 py-4 sm:py-5 bg-slate-800/50 backdrop-blur-sm border-2 border-purple-500/50 text-slate-200 rounded-lg font-bold text-base sm:text-lg hover:bg-slate-700/50 transition-all shadow-lg" + onClick={() => handleRedirect("login")} > Sign In ) : ( -

+

Welcome back, {userProfile.name || "Developer"}! Ready to drop some fire content? 🚀

handleRedirect("dashboard")} + className="font-mono px-8 sm:px-10 py-4 sm:py-5 bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-lg font-bold text-base sm:text-lg shadow-xl" + onClick={() => handleRedirect("dashboard")} > Go to Dashboard
)} - - - ↓ - + {/* Scroll indicator */} + + + + {/* Corner accents */} +
+
); } diff --git a/src/components/ui/Terminal.jsx b/src/components/ui/Terminal.jsx index b5382d5..a9758ec 100644 --- a/src/components/ui/Terminal.jsx +++ b/src/components/ui/Terminal.jsx @@ -209,3 +209,5 @@ function Terminal() { } export default Terminal; + + diff --git a/src/pages/LandingPage.jsx b/src/pages/LandingPage.jsx index 94cf32b..12de761 100644 --- a/src/pages/LandingPage.jsx +++ b/src/pages/LandingPage.jsx @@ -1,6 +1,6 @@ import Hero from "../components/ui/Hero"; import About from "../components/ui/About"; -import Terminal from "../components/ui/Terminal"; +import TerminalSection from "../components/ui/Terminal"; import Community from "../components/ui/Community"; import Footer from "../components/Footer"; @@ -13,7 +13,7 @@ const LandingPage = () => { {/* about section */} {/* hacktoberfest terminal section */} - + {/* community section */} {/* future footer component will be added here */} @@ -21,5 +21,5 @@ const LandingPage = () => {
); }; - + export default LandingPage;